diff --git a/rhodecode/lib/middleware/simplesvn.py b/rhodecode/lib/middleware/simplesvn.py --- a/rhodecode/lib/middleware/simplesvn.py +++ b/rhodecode/lib/middleware/simplesvn.py @@ -31,7 +31,7 @@ from rhodecode.lib import rc_cache from rhodecode.lib.middleware import simplevcs from rhodecode.lib.middleware.utils import get_path_info from rhodecode.lib.utils import is_valid_repo -from rhodecode.lib.str_utils import safe_str, safe_int +from rhodecode.lib.str_utils import safe_str, safe_int, safe_bytes from rhodecode.lib.type_utils import str2bool from rhodecode.lib.ext_json import json from rhodecode.lib.hooks_daemon import store_txn_id_data @@ -51,8 +51,8 @@ class SimpleSvnApp(object): def __call__(self, environ, start_response): request_headers = self._get_request_headers(environ) - data = environ['wsgi.input'] - req_method = environ['REQUEST_METHOD'] + data_io = environ['wsgi.input'] + req_method: str = environ['REQUEST_METHOD'] has_content_length = 'CONTENT_LENGTH' in environ path_info = self._get_url( @@ -66,37 +66,38 @@ class SimpleSvnApp(object): if req_method in ['MKCOL'] or has_content_length: data_processed = False # read chunk to check if we have txn-with-props - initial_data = data.read(1024) - if initial_data.startswith('(create-txn-with-props'): - data = initial_data + data.read() + initial_data: bytes = data_io.read(1024) + if initial_data.startswith(b'(create-txn-with-props'): + data_io = initial_data + data_io.read() # store on-the-fly our rc_extra using svn revision properties # those can be read later on in hooks executed so we have a way # to pass in the data into svn hooks rc_data = base64.urlsafe_b64encode(json.dumps(self.rc_extras)) - rc_data_len = len(rc_data) + rc_data_len = str(len(rc_data)) # header defines data length, and serialized data - skel = ' rc-scm-extras {} {}'.format(rc_data_len, rc_data) - data = data[:-2] + skel + '))' + skel = b' rc-scm-extras %b %b' % (safe_bytes(rc_data_len), safe_bytes(rc_data)) + data_io = data_io[:-2] + skel + b'))' data_processed = True if not data_processed: # NOTE(johbo): Avoid that we end up with sending the request in chunked # transfer encoding (mainly on Gunicorn). If we know the content # length, then we should transfer the payload in one request. - data = initial_data + data.read() + data_io = initial_data + data_io.read() if req_method in ['GET', 'PUT'] or transfer_encoding == 'chunked': - # NOTE(marcink): when getting/uploading files we want to STREAM content + # NOTE(marcink): when getting/uploading files, we want to STREAM content # back to the client/proxy instead of buffering it here... stream = True stream = stream log.debug('Calling SVN PROXY at `%s`, using method:%s. Stream: %s', path_info, req_method, stream) + try: response = requests.request( req_method, path_info, - data=data, headers=request_headers, stream=stream) + data=data_io, headers=request_headers, stream=stream) except requests.ConnectionError: log.exception('ConnectionError occurred for endpoint %s', path_info) raise @@ -119,9 +120,7 @@ class SimpleSvnApp(object): port = safe_int(self.rc_extras['hooks_uri'].split(':')[-1]) store_txn_id_data(txn_id, {'port': port}) - start_response( - '{} {}'.format(response.status_code, response.reason), - response_headers) + start_response(f'{response.status_code} {response.reason}', response_headers) return response.iter_content(chunk_size=1024) def _get_url(self, svn_http_server, path):