summaryrefslogtreecommitdiffstats
path: root/subcmds
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2015-08-19 23:36:35 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-08-19 23:36:35 +0000
commit7c9263bce09725227dc518ee298b350becbdf26e (patch)
treec2547dbfca738c2da6763fb5fe59195f4ee10658 /subcmds
parentdab9e99f0f6d4f82e0e61b37396f7c0915a8d508 (diff)
parent0745bb26571e0cf097baebd48761b8cd743ec7fc (diff)
downloadgit-repo-7c9263bce09725227dc518ee298b350becbdf26e.tar.gz
Merge "Support smart-sync through persistent-http[s]"
Diffstat (limited to 'subcmds')
-rw-r--r--subcmds/sync.py105
1 files changed, 104 insertions, 1 deletions
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 652a0c0d..0fc493c4 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -23,18 +23,26 @@ import shutil
23import socket 23import socket
24import subprocess 24import subprocess
25import sys 25import sys
26import tempfile
26import time 27import time
27 28
28from pyversion import is_python3 29from pyversion import is_python3
29if is_python3(): 30if is_python3():
31 import http.cookiejar as cookielib
32 import urllib.error
30 import urllib.parse 33 import urllib.parse
34 import urllib.request
31 import xmlrpc.client 35 import xmlrpc.client
32else: 36else:
37 import cookielib
33 import imp 38 import imp
39 import urllib2
34 import urlparse 40 import urlparse
35 import xmlrpclib 41 import xmlrpclib
36 urllib = imp.new_module('urllib') 42 urllib = imp.new_module('urllib')
43 urllib.error = urllib2
37 urllib.parse = urlparse 44 urllib.parse = urlparse
45 urllib.request = urllib2
38 xmlrpc = imp.new_module('xmlrpc') 46 xmlrpc = imp.new_module('xmlrpc')
39 xmlrpc.client = xmlrpclib 47 xmlrpc.client = xmlrpclib
40 48
@@ -57,6 +65,7 @@ except ImportError:
57 multiprocessing = None 65 multiprocessing = None
58 66
59from git_command import GIT, git_require 67from git_command import GIT, git_require
68from git_config import GetSchemeFromUrl, GetUrlCookieFile
60from git_refs import R_HEADS, HEAD 69from git_refs import R_HEADS, HEAD
61import gitc_utils 70import gitc_utils
62from project import Project 71from project import Project
@@ -598,8 +607,12 @@ later is required to fix a server side protocol bug.
598 (username, password), 607 (username, password),
599 1) 608 1)
600 609
610 transport = PersistentTransport(manifest_server)
611 if manifest_server.startswith('persistent-'):
612 manifest_server = manifest_server[len('persistent-'):]
613
601 try: 614 try:
602 server = xmlrpc.client.Server(manifest_server) 615 server = xmlrpc.client.Server(manifest_server, transport=transport)
603 if opt.smart_sync: 616 if opt.smart_sync:
604 p = self.manifest.manifestProject 617 p = self.manifest.manifestProject
605 b = p.GetBranch(p.CurrentBranch) 618 b = p.GetBranch(p.CurrentBranch)
@@ -879,3 +892,93 @@ class _FetchTimes(object):
879 os.remove(self._path) 892 os.remove(self._path)
880 except OSError: 893 except OSError:
881 pass 894 pass
895
896# This is a replacement for xmlrpc.client.Transport using urllib2
897# and supporting persistent-http[s]. It cannot change hosts from
898# request to request like the normal transport, the real url
899# is passed during initialization.
900class PersistentTransport(xmlrpc.client.Transport):
901 def __init__(self, orig_host):
902 self.orig_host = orig_host
903
904 def request(self, host, handler, request_body, verbose=False):
905 with GetUrlCookieFile(self.orig_host, not verbose) as (cookiefile, proxy):
906 # Python doesn't understand cookies with the #HttpOnly_ prefix
907 # Since we're only using them for HTTP, copy the file temporarily,
908 # stripping those prefixes away.
909 tmpcookiefile = tempfile.NamedTemporaryFile()
910 try:
911 with open(cookiefile) as f:
912 for line in f:
913 if line.startswith("#HttpOnly_"):
914 line = line[len("#HttpOnly_"):]
915 tmpcookiefile.write(line)
916 tmpcookiefile.flush()
917
918 cookiejar = cookielib.MozillaCookieJar(tmpcookiefile.name)
919 cookiejar.load()
920 finally:
921 tmpcookiefile.close()
922
923 proxyhandler = urllib.request.ProxyHandler
924 if proxy:
925 proxyhandler = urllib.request.ProxyHandler({
926 "http": proxy,
927 "https": proxy })
928
929 opener = urllib.request.build_opener(
930 urllib.request.HTTPCookieProcessor(cookiejar),
931 proxyhandler)
932
933 url = urllib.parse.urljoin(self.orig_host, handler)
934 parse_results = urllib.parse.urlparse(url)
935
936 scheme = parse_results.scheme
937 if scheme == 'persistent-http':
938 scheme = 'http'
939 if scheme == 'persistent-https':
940 # If we're proxying through persistent-https, use http. The
941 # proxy itself will do the https.
942 if proxy:
943 scheme = 'http'
944 else:
945 scheme = 'https'
946
947 # Parse out any authentication information using the base class
948 host, extra_headers, _ = self.get_host_info(parse_results.netloc)
949
950 url = urllib.parse.urlunparse((
951 scheme,
952 host,
953 parse_results.path,
954 parse_results.params,
955 parse_results.query,
956 parse_results.fragment))
957
958 request = urllib.request.Request(url, request_body)
959 if extra_headers is not None:
960 for (name, header) in extra_headers:
961 request.add_header(name, header)
962 request.add_header('Content-Type', 'text/xml')
963 try:
964 response = opener.open(request)
965 except urllib.error.HTTPError as e:
966 if e.code == 501:
967 # We may have been redirected through a login process
968 # but our POST turned into a GET. Retry.
969 response = opener.open(request)
970 else:
971 raise
972
973 p, u = xmlrpc.client.getparser()
974 while 1:
975 data = response.read(1024)
976 if not data:
977 break
978 p.feed(data)
979 p.close()
980 return u.close()
981
982 def close(self):
983 pass
984