mirror of
https://gerrit.googlesource.com/git-repo
synced 2025-01-02 16:14:25 +00:00
Hold persistent proxy connection open while fetching clone.bundle
The persistent proxy may choose to present a per-process cookie file that gets cleaned up after the process exits, to help with the fact that libcurl cannot save cookies atomically when a cookie file is shared across processes. We were letting this cleanup happen immediately by closing stdin as soon as we read the configuration option, resulting in a nonexistent cookie file by the time we use the config option. Work around this by converting the cookie logic to a context manager method, which closes the process only when we're done with the cookie file. Change-Id: I12a88b25cc19621ef8161337144c1b264264211a
This commit is contained in:
parent
42e679b9f6
commit
137d0131bf
18
project.py
18
project.py
@ -13,7 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import traceback
|
import contextlib
|
||||||
import errno
|
import errno
|
||||||
import filecmp
|
import filecmp
|
||||||
import os
|
import os
|
||||||
@ -26,6 +26,7 @@ import sys
|
|||||||
import tarfile
|
import tarfile
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
import traceback
|
||||||
|
|
||||||
from color import Coloring
|
from color import Coloring
|
||||||
from git_command import GitCommand, git_require
|
from git_command import GitCommand, git_require
|
||||||
@ -1946,7 +1947,7 @@ class Project(object):
|
|||||||
os.remove(tmpPath)
|
os.remove(tmpPath)
|
||||||
if 'http_proxy' in os.environ and 'darwin' == sys.platform:
|
if 'http_proxy' in os.environ and 'darwin' == sys.platform:
|
||||||
cmd += ['--proxy', os.environ['http_proxy']]
|
cmd += ['--proxy', os.environ['http_proxy']]
|
||||||
cookiefile = self._GetBundleCookieFile(srcUrl)
|
with self._GetBundleCookieFile(srcUrl) as cookiefile:
|
||||||
if cookiefile:
|
if cookiefile:
|
||||||
cmd += ['--cookie', cookiefile]
|
cmd += ['--cookie', cookiefile]
|
||||||
if srcUrl.startswith('persistent-'):
|
if srcUrl.startswith('persistent-'):
|
||||||
@ -1994,6 +1995,7 @@ class Project(object):
|
|||||||
except OSError:
|
except OSError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
def _GetBundleCookieFile(self, url):
|
def _GetBundleCookieFile(self, url):
|
||||||
if url.startswith('persistent-'):
|
if url.startswith('persistent-'):
|
||||||
try:
|
try:
|
||||||
@ -2001,7 +2003,7 @@ class Project(object):
|
|||||||
['git-remote-persistent-https', '-print_config', url],
|
['git-remote-persistent-https', '-print_config', url],
|
||||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE)
|
||||||
p.stdin.close() # Tell subprocess it's ok to close.
|
try:
|
||||||
prefix = 'http.cookiefile='
|
prefix = 'http.cookiefile='
|
||||||
cookiefile = None
|
cookiefile = None
|
||||||
for line in p.stdout:
|
for line in p.stdout:
|
||||||
@ -2009,19 +2011,23 @@ class Project(object):
|
|||||||
if line.startswith(prefix):
|
if line.startswith(prefix):
|
||||||
cookiefile = line[len(prefix):]
|
cookiefile = line[len(prefix):]
|
||||||
break
|
break
|
||||||
|
# Leave subprocess open, as cookie file may be transient.
|
||||||
|
if cookiefile:
|
||||||
|
yield cookiefile
|
||||||
|
return
|
||||||
|
finally:
|
||||||
|
p.stdin.close()
|
||||||
if p.wait():
|
if p.wait():
|
||||||
err_msg = p.stderr.read()
|
err_msg = p.stderr.read()
|
||||||
if ' -print_config' in err_msg:
|
if ' -print_config' in err_msg:
|
||||||
pass # Persistent proxy doesn't support -print_config.
|
pass # Persistent proxy doesn't support -print_config.
|
||||||
else:
|
else:
|
||||||
print(err_msg, file=sys.stderr)
|
print(err_msg, file=sys.stderr)
|
||||||
if cookiefile:
|
|
||||||
return cookiefile
|
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno == errno.ENOENT:
|
if e.errno == errno.ENOENT:
|
||||||
pass # No persistent proxy.
|
pass # No persistent proxy.
|
||||||
raise
|
raise
|
||||||
return GitConfig.ForUser().GetString('http.cookiefile')
|
yield GitConfig.ForUser().GetString('http.cookiefile')
|
||||||
|
|
||||||
def _Checkout(self, rev, quiet=False):
|
def _Checkout(self, rev, quiet=False):
|
||||||
cmd = ['checkout']
|
cmd = ['checkout']
|
||||||
|
Loading…
Reference in New Issue
Block a user