##// END OF EJS Templates
svn: use streaming uploads/downloads of files....
marcink -
r3022:211018a9 stable
parent child Browse files
Show More
@@ -21,7 +21,7 b''
21 21 import base64
22 22 import logging
23 23 import urllib
24 from urlparse import urljoin
24 import urlparse
25 25
26 26 import requests
27 27 from pyramid.httpexceptions import HTTPNotAcceptable
@@ -48,29 +48,50 b' class SimpleSvnApp(object):'
48 48
49 49 def __call__(self, environ, start_response):
50 50 request_headers = self._get_request_headers(environ)
51 data = environ['wsgi.input']
52 req_method = environ['REQUEST_METHOD']
53 has_content_length = 'CONTENT_LENGTH' in environ
54 path_info = self._get_url(environ['PATH_INFO'])
55 transfer_encoding = environ.get('HTTP_TRANSFER_ENCODING', '')
56 log.debug('Handling: %s method via `%s`', req_method, path_info)
51 57
52 data = environ['wsgi.input']
53 # johbo: Avoid that we end up with sending the request in chunked
54 # transfer encoding (mainly on Gunicorn). If we know the content
55 # length, then we should transfer the payload in one request.
56 if environ['REQUEST_METHOD'] == 'MKCOL' or 'CONTENT_LENGTH' in environ:
57 data = data.read()
58 if data.startswith('(create-txn-with-props'):
58 # stream control flag, based on request and content type...
59 stream = False
60
61 if req_method in ['MKCOL'] or has_content_length:
62 data_processed = False
63 # read chunk to check if we have txn-with-props
64 initial_data = data.read(1024)
65 if initial_data.startswith('(create-txn-with-props'):
66 data = initial_data + data.read()
59 67 # store on-the-fly our rc_extra using svn revision properties
60 68 # those can be read later on in hooks executed so we have a way
61 69 # to pass in the data into svn hooks
62 70 rc_data = base64.urlsafe_b64encode(json.dumps(self.rc_extras))
63 71 rc_data_len = len(rc_data)
64 # header defines data lenght, and serialized data
72 # header defines data length, and serialized data
65 73 skel = ' rc-scm-extras {} {}'.format(rc_data_len, rc_data)
66 74 data = data[:-2] + skel + '))'
75 data_processed = True
67 76
68 log.debug('Calling: %s method via `%s`', environ['REQUEST_METHOD'],
69 self._get_url(environ['PATH_INFO']))
77 if not data_processed:
78 # NOTE(johbo): Avoid that we end up with sending the request in chunked
79 # transfer encoding (mainly on Gunicorn). If we know the content
80 # length, then we should transfer the payload in one request.
81 data = initial_data + data.read()
70 82
83 if req_method in ['GET', 'PUT'] or transfer_encoding == 'chunked':
84 # NOTE(marcink): when getting/uploading files we want to STREAM content
85 # back to the client/proxy instead of buffering it here...
86 stream = True
87
88 stream = stream
89 log.debug(
90 'Calling SVN PROXY: method:%s via `%s`, Stream: %s',
91 req_method, path_info, stream)
71 92 response = requests.request(
72 environ['REQUEST_METHOD'], self._get_url(environ['PATH_INFO']),
73 data=data, headers=request_headers)
93 req_method, path_info,
94 data=data, headers=request_headers, stream=stream)
74 95
75 96 if response.status_code not in [200, 401]:
76 97 if response.status_code >= 500:
@@ -97,7 +118,7 b' class SimpleSvnApp(object):'
97 118 return response.iter_content(chunk_size=1024)
98 119
99 120 def _get_url(self, path):
100 url_path = urljoin(
121 url_path = urlparse.urljoin(
101 122 self.config.get('subversion_http_server_url', ''), path)
102 123 url_path = urllib.quote(url_path, safe="/:=~+!$,;'")
103 124 return url_path
General Comments 0
You need to be logged in to leave comments. Login now