svn: use streaming uploads/downloads of files....
marcink -
r3022:211018a9 stable
Not Reviewed
Show More
Add another comment
TODOs: 0 unresolved 0 Resolved
COMMENTS: 0 General 0 Inline
@@ -21,7 +21,7
21 import base64
21 import base64
22 import logging
22 import logging
23 import urllib
23 import urllib
24 from urlparse import urljoin
24 import urlparse
25
25
26 import requests
26 import requests
27 from pyramid.httpexceptions import HTTPNotAcceptable
27 from pyramid.httpexceptions import HTTPNotAcceptable
@@ -48,29 +48,50
48
48
49 def __call__(self, environ, start_response):
49 def __call__(self, environ, start_response):
50 request_headers = self._get_request_headers(environ)
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']
58 # stream control flag, based on request and content type...
53 # johbo: Avoid that we end up with sending the request in chunked
59 stream = False
54 # transfer encoding (mainly on Gunicorn). If we know the content
60
55 # length, then we should transfer the payload in one request.
61 if req_method in ['MKCOL'] or has_content_length:
56 if environ['REQUEST_METHOD'] == 'MKCOL' or 'CONTENT_LENGTH' in environ:
62 data_processed = False
57 data = data.read()
63 # read chunk to check if we have txn-with-props
58 if data.startswith('(create-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 # store on-the-fly our rc_extra using svn revision properties
67 # store on-the-fly our rc_extra using svn revision properties
60 # those can be read later on in hooks executed so we have a way
68 # those can be read later on in hooks executed so we have a way
61 # to pass in the data into svn hooks
69 # to pass in the data into svn hooks
62 rc_data = base64.urlsafe_b64encode(json.dumps(self.rc_extras))
70 rc_data = base64.urlsafe_b64encode(json.dumps(self.rc_extras))
63 rc_data_len = len(rc_data)
71 rc_data_len = len(rc_data)
64 # header defines data lenght, and serialized data
72 # header defines data length, and serialized data
65 skel = ' rc-scm-extras {} {}'.format(rc_data_len, rc_data)
73 skel = ' rc-scm-extras {} {}'.format(rc_data_len, rc_data)
66 data = data[:-2] + skel + '))'
74 data = data[:-2] + skel + '))'
75 data_processed = True
67
76
68 log.debug('Calling: %s method via `%s`', environ['REQUEST_METHOD'],
77 if not data_processed:
69 self._get_url(environ['PATH_INFO']))
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 response = requests.request(
92 response = requests.request(
72 environ['REQUEST_METHOD'], self._get_url(environ['PATH_INFO']),
93 req_method, path_info,
73 data=data, headers=request_headers)
94 data=data, headers=request_headers, stream=stream)
74
95
75 if response.status_code not in [200, 401]:
96 if response.status_code not in [200, 401]:
76 if response.status_code >= 500:
97 if response.status_code >= 500:
@@ -97,7 +118,7
97 return response.iter_content(chunk_size=1024)
118 return response.iter_content(chunk_size=1024)
98
119
99 def _get_url(self, path):
120 def _get_url(self, path):
100 url_path = urljoin(
121 url_path = urlparse.urljoin(
101 self.config.get('subversion_http_server_url', ''), path)
122 self.config.get('subversion_http_server_url', ''), path)
102 url_path = urllib.quote(url_path, safe="/:=~+!$,;'")
123 url_path = urllib.quote(url_path, safe="/:=~+!$,;'")
103 return url_path
124 return url_path
Comments 0
You need to be logged in to leave comments. Login now