svn: fixed issue with custom svn client user agents
This commit is contained in:
parent
e7e12dfaf2
commit
f172aa4144
2 changed files with 63 additions and 9 deletions
|
|
@ -110,15 +110,19 @@ class SubversionTunnelWrapper(object):
|
|||
signal.alarm(0)
|
||||
return self._parse_first_client_response(first_response) if first_response else None
|
||||
|
||||
def patch_first_client_response(self, response, **kwargs):
|
||||
def _prepare_first_client_response(self, response: dict, **kwargs) -> bytes:
|
||||
version = response["version"]
|
||||
capabilities = response["capabilities"]
|
||||
client = response["client"] or b""
|
||||
|
||||
url = self._svn_bytes(response["url"])
|
||||
ra_client = self._svn_bytes(response["ra_client"])
|
||||
client = b" " + self._svn_bytes(response["client"]) or b""
|
||||
|
||||
buffer_ = b"( %b ( %b ) %b%b( %b) ) " % (version, capabilities, url, ra_client, client)
|
||||
buffer_ = b"( %b ( %b ) %b%b(%b) )" % (version, capabilities, url, ra_client, client)
|
||||
return buffer_
|
||||
|
||||
def patch_first_client_response(self, response, **kwargs):
|
||||
buffer_ = self._prepare_first_client_response(response, **kwargs)
|
||||
self.process.stdin.write(buffer_)
|
||||
self.process.stdin.flush()
|
||||
|
||||
|
|
@ -162,8 +166,7 @@ class SubversionTunnelWrapper(object):
|
|||
According to the Subversion RA protocol, the first request
|
||||
should look like:
|
||||
|
||||
( version:number ( cap:word ... ) url:string ? ra-client:string
|
||||
( ? client:string ) )
|
||||
( version:number ( cap:word ... ) url:string ? ra-client:string ( ? client:string ) )
|
||||
|
||||
Please check https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_ra_svn/protocol
|
||||
"""
|
||||
|
|
@ -173,15 +176,14 @@ class SubversionTunnelWrapper(object):
|
|||
ra_client_re = rb"(\d+\:(?P<ra_client>[\W\w]+)\s)"
|
||||
client_re = rb"(\d+\:(?P<client>[\W\w]+)\s)*"
|
||||
regex = re.compile(
|
||||
rb"^\(\s%b\s%b\s%b\s%b"
|
||||
rb"\(\s%b\)\s\)\s*$" % (version_re, capabilities_re, url_re, ra_client_re, client_re)
|
||||
rb"^\(\s%b\s%b\s%b\s%b\(\s%b\)\s\)\s*$" % (version_re, capabilities_re, url_re, ra_client_re, client_re)
|
||||
)
|
||||
matcher = regex.match(buffer_)
|
||||
return matcher.groupdict() if matcher else None
|
||||
|
||||
def _match_repo_name(self, url):
|
||||
"""
|
||||
Given an server url, try to match it against ALL known repository names.
|
||||
Given a server url, try to match it against ALL known repository names.
|
||||
This handles a tricky SVN case for SSH and subdir commits.
|
||||
E.g if our repo name is my-svn-repo, a svn commit on file in a subdir would
|
||||
result in the url with this subdir added.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import os
|
|||
import mock
|
||||
import pytest
|
||||
|
||||
from rhodecode.apps.ssh_support.lib.backends.svn import SubversionServer
|
||||
from rhodecode.apps.ssh_support.lib.backends.svn import SubversionServer, SubversionTunnelWrapper
|
||||
from rhodecode.apps.ssh_support.tests.conftest import plain_dummy_env, plain_dummy_user
|
||||
|
||||
|
||||
|
|
@ -224,3 +224,55 @@ class TestSubversionServer(object):
|
|||
exit_code = server.run(tunnel_extras={"config": server.ini_path})
|
||||
|
||||
assert exit_code == (1, False)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"first_resp, expected_match",
|
||||
[
|
||||
(
|
||||
b"( 2 ( edit-pipeline svndiff1 accepts-svndiff2 absent-entries depth mergeinfo log-revprops ) 44:svn+ssh://rc@code.example.com/TestRepo/trunk 34:SVN/1.14.5 (x64-microsoft-windows) ( 24:TortoiseSVN-1.14.9.29743 ) )",
|
||||
{
|
||||
"version": b"2",
|
||||
"capabilities": b"edit-pipeline svndiff1 accepts-svndiff2 absent-entries depth mergeinfo log-revprops",
|
||||
"url": b"svn+ssh://rc@code.example.com/TestRepo/trunk",
|
||||
"ra_client": b"SVN/1.14.5 (x64-microsoft-windows)",
|
||||
"client": b"TortoiseSVN-1.14.9.29743",
|
||||
},
|
||||
),
|
||||
(
|
||||
b"( 2 ( edit-pipeline svndiff1 accepts-svndiff2 absent-entries depth mergeinfo log-revprops ) 44:svn+ssh://rc@code.example.com/TestRepo/trunk 34:SVN/1.14.5 (x64-microsoft-windows) ( ) )",
|
||||
{
|
||||
"version": b"2",
|
||||
"capabilities": b"edit-pipeline svndiff1 accepts-svndiff2 absent-entries depth mergeinfo log-revprops",
|
||||
"url": b"svn+ssh://rc@code.example.com/TestRepo/trunk",
|
||||
"ra_client": b"SVN/1.14.5 (x64-microsoft-windows)",
|
||||
"client": None,
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
def test__parse_first_client_response(self, svn_server, first_resp, expected_match):
|
||||
server = svn_server.create()
|
||||
tunnel = SubversionTunnelWrapper(server)
|
||||
parsed = tunnel._parse_first_client_response(first_resp)
|
||||
assert parsed == expected_match
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"first_resp, expected_match",
|
||||
[
|
||||
(
|
||||
b"( 2 ( edit-pipeline svndiff1 accepts-svndiff2 absent-entries depth mergeinfo log-revprops ) 44:svn+ssh://rc@code.example.com/TestRepo/trunk 34:SVN/1.14.5 (x64-microsoft-windows) ( 24:TortoiseSVN-1.14.9.29743 ) )",
|
||||
None,
|
||||
),
|
||||
(
|
||||
b"( 2 ( edit-pipeline svndiff1 accepts-svndiff2 absent-entries depth mergeinfo log-revprops ) 44:svn+ssh://rc@code.example.com/TestRepo/trunk 34:SVN/1.14.5 (x64-microsoft-windows) ( ) )",
|
||||
None,
|
||||
),
|
||||
],
|
||||
)
|
||||
def test__parse_and_prepare_first_client_response(self, svn_server, first_resp, expected_match):
|
||||
server = svn_server.create()
|
||||
tunnel = SubversionTunnelWrapper(server)
|
||||
parsed = tunnel._parse_first_client_response(first_resp)
|
||||
first_response_prepared = tunnel._prepare_first_client_response(parsed)
|
||||
|
||||
assert first_response_prepared == first_resp
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue