PATH_INFO: use new method to consistently extract proper PATH_INFO data

This commit is contained in:
RhodeCode Admin 2023-05-11 12:32:19 +02:00
parent 9740247ef1
commit 67ddb883ac
7 changed files with 40 additions and 29 deletions

View file

@ -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')(

View file

@ -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"

View file

@ -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'

View file

@ -30,6 +30,7 @@ import urllib.request, urllib.parse, urllib.error
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:]

View file

@ -28,6 +28,7 @@ from pyramid.httpexceptions import HTTPNotAcceptable
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

View file

@ -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)

View file

@ -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)