# HG changeset patch # User RhodeCode Admin # Date 2023-05-11 10:32:19 # Node ID f4682f64c1fdf70ac6b7ac418442996f09984832 # Parent 975a57053eb8474fe67fbe0256b677b736261922 PATH_INFO: use new method to consistently extract proper PATH_INFO data diff --git a/rhodecode/lib/middleware/csrf.py b/rhodecode/lib/middleware/csrf.py --- a/rhodecode/lib/middleware/csrf.py +++ b/rhodecode/lib/middleware/csrf.py @@ -27,7 +27,7 @@ import webob import webob.exc import rhodecode.lib.auth - +from rhodecode.lib.middleware.utils import get_path_info log = logging.getLogger(__name__) @@ -77,10 +77,11 @@ class CSRFDetector(object): def __call__(self, environ, start_response): if environ['REQUEST_METHOD'].upper() not in ('GET', 'POST'): raise Exception(self._PUT_DELETE_MESSAGE) - token_expected = environ['PATH_INFO'] not in self._PATHS_WITHOUT_TOKEN + path_info = get_path_info(environ) + token_expected = path_info not in self._PATHS_WITHOUT_TOKEN allowed = True for pattern in self._SKIP_PATTERN: - if environ['PATH_INFO'].startswith(pattern): + if path_info.startswith(pattern): allowed = False break @@ -99,7 +100,7 @@ class CSRFDetector(object): if rhodecode.lib.auth.csrf_token_key not in content: raise Exception( '%s to %s does not have a csrf_token %r' % - (environ['REQUEST_METHOD'], environ['PATH_INFO'], content)) + (environ['REQUEST_METHOD'], path_info, content)) return self._app(environ, start_response) @@ -149,10 +150,10 @@ class OriginChecker(object): origin = origin_header.split(' ', 1)[0] if origin == 'null': origin = None - - if (environ['PATH_INFO'] not in self._skip_urls and origin and + path_info = get_path_info(environ) + if (path_info not in self._skip_urls and origin and not _equivalent_urls(origin, self._expected_origin)): - log.warn( + log.warning( 'Invalid Origin header detected: got %s, expected %s', origin_header, self._expected_origin) return webob.exc.HTTPForbidden('Origin header mismatch')( diff --git a/rhodecode/lib/middleware/request_wrapper.py b/rhodecode/lib/middleware/request_wrapper.py --- a/rhodecode/lib/middleware/request_wrapper.py +++ b/rhodecode/lib/middleware/request_wrapper.py @@ -23,7 +23,8 @@ import logging import rhodecode from rhodecode.lib.auth import AuthUser -from rhodecode.lib.base import get_ip_addr, get_access_path, get_user_agent +from rhodecode.lib.base import get_ip_addr, get_user_agent +from rhodecode.lib.middleware.utils import get_path_info from rhodecode.lib.utils2 import safe_str, get_current_rhodecode_user @@ -52,7 +53,7 @@ class RequestWrapperTween(object): finally: count = request.request_count() _ver_ = rhodecode.__version__ - _path = safe_str(get_access_path(request.environ)) + _path = get_path_info(request.environ) _auth_user = self._get_user_info(request) ip = get_ip_addr(request.environ) match_route = request.matched_route.name if request.matched_route else "NOT_FOUND" diff --git a/rhodecode/lib/middleware/simplegit.py b/rhodecode/lib/middleware/simplegit.py --- a/rhodecode/lib/middleware/simplegit.py +++ b/rhodecode/lib/middleware/simplegit.py @@ -31,6 +31,7 @@ import rhodecode from rhodecode.lib import utils from rhodecode.lib import utils2 from rhodecode.lib.middleware import simplevcs +from rhodecode.lib.middleware.utils import get_path_info log = logging.getLogger(__name__) @@ -60,7 +61,8 @@ class SimpleGit(simplevcs.SimpleVCS): :param environ: environ where PATH_INFO is stored """ - repo_name = GIT_PROTO_PAT.match(environ['PATH_INFO']).group(1) + path_info = get_path_info(environ) + repo_name = GIT_PROTO_PAT.match(path_info).group(1) # for GIT LFS, and bare format strip .git suffix from names if repo_name.endswith('.git'): repo_name = repo_name[:-4] @@ -120,16 +122,15 @@ class SimpleGit(simplevcs.SimpleVCS): :param environ: """ - path = environ['PATH_INFO'] + path = get_path_info(environ) if path.endswith('/info/refs'): query = urllib.parse.parse_qs(environ['QUERY_STRING']) service_cmd = query.get('service', [''])[0] return self._ACTION_MAPPING.get(service_cmd, 'pull') - elif GIT_LFS_PROTO_PAT.match(environ['PATH_INFO']): - return self._get_lfs_action( - environ['PATH_INFO'], environ['REQUEST_METHOD']) + elif GIT_LFS_PROTO_PAT.match(path): + return self._get_lfs_action(path, environ['REQUEST_METHOD']) elif path.endswith('/git-receive-pack'): return 'push' diff --git a/rhodecode/lib/middleware/simplehg.py b/rhodecode/lib/middleware/simplehg.py --- a/rhodecode/lib/middleware/simplehg.py +++ b/rhodecode/lib/middleware/simplehg.py @@ -30,6 +30,7 @@ import urllib.request, urllib.parse, url from rhodecode.lib import utils from rhodecode.lib.ext_json import json from rhodecode.lib.middleware import simplevcs +from rhodecode.lib.middleware.utils import get_path_info log = logging.getLogger(__name__) @@ -44,7 +45,7 @@ class SimpleHg(simplevcs.SimpleVCS): :param environ: environ where PATH_INFO is stored """ - repo_name = environ['PATH_INFO'] + repo_name = get_path_info(environ) if repo_name and repo_name.startswith('/'): # remove only the first leading / repo_name = repo_name[1:] 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 @@ -28,6 +28,7 @@ from pyramid.httpexceptions import HTTPN 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.utils2 import str2bool, safe_int, safe_str from rhodecode.lib.ext_json import json @@ -51,8 +52,9 @@ class SimpleSvnApp(object): data = environ['wsgi.input'] req_method = environ['REQUEST_METHOD'] has_content_length = 'CONTENT_LENGTH' in environ + path_info = self._get_url( - self.config.get('subversion_http_server_url', ''), environ['PATH_INFO']) + self.config.get('subversion_http_server_url', ''), get_path_info(environ)) transfer_encoding = environ.get('HTTP_TRANSFER_ENCODING', '') log.debug('Handling: %s method via `%s`', req_method, path_info) @@ -178,7 +180,7 @@ class SimpleSvn(simplevcs.SimpleVCS): :param environ: environ where PATH_INFO is stored """ - path = environ['PATH_INFO'].split('!') + path = get_path_info(environ).split('!') repo_name = path[0].strip('/') # SVN includes the whole path in it's requests, including diff --git a/rhodecode/lib/middleware/utils/scm_app_http.py b/rhodecode/lib/middleware/utils/scm_app_http.py --- a/rhodecode/lib/middleware/utils/scm_app_http.py +++ b/rhodecode/lib/middleware/utils/scm_app_http.py @@ -32,7 +32,7 @@ import requests import webob.request import rhodecode - +from rhodecode.lib.middleware.utils import get_path_info log = logging.getLogger(__name__) @@ -161,7 +161,7 @@ def _is_request_chunked(environ): def _maybe_stream_request(environ): - path = environ['PATH_INFO'] + path = get_path_info(environ) stream = _is_request_chunked(environ) log.debug('handling request `%s` with stream support: %s', path, stream) diff --git a/rhodecode/lib/middleware/vcs.py b/rhodecode/lib/middleware/vcs.py --- a/rhodecode/lib/middleware/vcs.py +++ b/rhodecode/lib/middleware/vcs.py @@ -27,12 +27,14 @@ import urllib.parse from webob.exc import HTTPNotFound import rhodecode +from rhodecode.lib.middleware.utils import get_path_info from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled from rhodecode.lib.middleware.simplegit import SimpleGit, GIT_PROTO_PAT from rhodecode.lib.middleware.simplehg import SimpleHg from rhodecode.lib.middleware.simplesvn import SimpleSvn from rhodecode.model.settings import VcsSettingsModel + log = logging.getLogger(__name__) VCS_TYPE_KEY = '_rc_vcs_type' @@ -43,9 +45,10 @@ def is_git(environ): """ Returns True if requests should be handled by GIT wsgi middleware """ - is_git_path = GIT_PROTO_PAT.match(environ['PATH_INFO']) + path_info = get_path_info(environ) + is_git_path = GIT_PROTO_PAT.match(path_info) log.debug( - 'request path: `%s` detected as GIT PROTOCOL %s', environ['PATH_INFO'], + 'request path: `%s` detected as GIT PROTOCOL %s', path_info, is_git_path is not None) return is_git_path @@ -65,8 +68,9 @@ def is_hg(environ): if 'cmd' in query: is_hg_path = True + path_info = get_path_info(environ) log.debug( - 'request path: `%s` detected as HG PROTOCOL %s', environ['PATH_INFO'], + 'request path: `%s` detected as HG PROTOCOL %s', path_info, is_hg_path) return is_hg_path @@ -80,13 +84,14 @@ def is_svn(environ): http_dav = environ.get('HTTP_DAV', '') magic_path_segment = rhodecode.CONFIG.get( 'rhodecode_subversion_magic_path', '/!svn') + path_info = get_path_info(environ) is_svn_path = ( 'subversion' in http_dav or - magic_path_segment in environ['PATH_INFO'] + magic_path_segment in path_info or environ['REQUEST_METHOD'] in ['PROPFIND', 'PROPPATCH'] ) log.debug( - 'request path: `%s` detected as SVN PROTOCOL %s', environ['PATH_INFO'], + 'request path: `%s` detected as SVN PROTOCOL %s', path_info, is_svn_path) return is_svn_path @@ -173,10 +178,8 @@ def detect_vcs_request(environ, backends # full channelstream connect should be VCS skipped '_admin/channelstream/connect', ] - - path_info = environ['PATH_INFO'] - - path_elem = get_path_elem(path_info) + path_info = get_path_info(environ) + path_url = path_info.lstrip('/') if path_elem in white_list: log.debug('path `%s` in whitelist, skipping...', path_info) @@ -251,7 +254,9 @@ class VCSMiddleware(object): if vcs_handler: # translate the _REPO_ID into real repo NAME for usage # in middleware - environ['PATH_INFO'] = vcs_handler._get_by_id(environ['PATH_INFO']) + + path_info = get_path_info(environ) + environ['PATH_INFO'] = vcs_handler._get_by_id(path_info) # Set acl, url and vcs repo names. vcs_handler.set_repo_names(environ)