You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Thorsten Schöning <ts...@am-soft.de> on 2019/06/14 10:12:11 UTC

mod_dav_svn of SVN 1.9.3 doesn't seem to calc repo names from URLs with spaces properly.

Hi all,

I'm hosting some SVN-repos using mod_dav_svn and am running into
problems when using URLs with spaces.

My approach is simply to have a directory structure of SVN-repos
grouped by customers or some topic and for each of those groups I want
to configure a corresponding URL as entry point into mod_dav_svn. Some
of those groups contain spaces for historical reasons and because I
want to use 1:1 paths in the file system as URLs, those spaces should
be handled by httpd and mod_dav_svn as well.

Have a look at the following config:

>     <Location "/svn/Bin/LSG BE-BB">
>         DAV                 svn
>         SVNParentPath       "/home/ams_svn_repos/Bin/LSG BE-BB"
>         SVNListParentPath   On
>         SVNAdvertiseV2Protocol          Off
>         AuthzSVNReposRelativeAccessFile authz
>     </Location>

Requests to that location are properly forwarded to mod_dav_svn, but
that fails to calculate the ultimate repo to use:

> (2)No such file or directory: [...] Failed to load the mod_authz_svn config: Can't open file '/home/ams_svn_repos/Bin/LSG BE-BB/svn/conf/authz': No such file or directory
> Access denied: - OPTIONS svn:/Bin/LSG BE-BB/GosaPrint/trunk

When I change the location to use an underscore and request that,
things succeed:

> <Location "/svn/Bin/LSG_BE-BB">
> Access denied: - OPTIONS GosaPrint:/trunk

"Access denied" is the correct thing to do in this case, the important
point is that the correct authz-file has been used, the correct repo
extracted from the URL etc.

So the problem is obviously with the space, but when I change the
"Location" of httpd to contain "%20", that doesn't work, because httpd
doesn't match the location at all anymore:

> <Location "/svn/Bin/LSG%20BE-BB">
> Fehler: The server at
> Fehler:  '[...]/svn/Bin/LSG%20BE-BB/GosaPrint/trunk'
> Fehler:  does not support the HTTP/DAV protocol

If I provide other locations, those get matched instead, like
"/svn/Bin" and mod_dav_svn calculates another wrong repo name. So it's
not that things don't work anymore at all, but only that httpd seems
to really expect a space in the "Location".

And I think that's the problem: The matched location is forwarded
using a space to mod_dav_svn, which tries to calculate the repo name
from the request and that request most likely containes %20 instead of
the space. So calculation simply fails:

>   /* The URL space defined by the SVN provider is always a virtual
>      space. Construct the path relative to the configured Location
>      (root_path). So... the relative location is simply the URL used,
>      skipping the root_path.
>      Note: mod_dav has canonialized root_path. It will not have a trailing
>      slash (unless it is "/").
>      Note: given a URI of /something and a root of /some, then it is
>            impossible to be here (and end up with "thing"). This is simply
>            because we control /some and are dispatched to here for its
>            URIs. We do not control /something, so we don't get here. Or,
>            if we *do* control /something, then it is for THAT root.
>   */
>   relative = ap_stripprefix(uri, root_path);

https://github.com/apache/subversion/blob/trunk/subversion/mod_dav_svn/repos.c#L1326

In the above code, "uri" and "root_path" would need to have the same
representation, either both being encoded or decoded, but I guess both
are different. Because of that, the "root_path" is not stripped, which
leads to "svn" from the URL being the first component and hence use
wrongly as repo name to map into "SVNParentPath".

Similar problems with difference in "Location[Match]" vs. URLs of the
request have been discussed in the past already:

https://bz.apache.org/bugzilla/show_bug.cgi?id=35077
https://svn.haxx.se/dev/archive-2005-09/0470.shtml

But I couldn't find anything simple like using spaces in URLs to
repos.

So, does that make sense to you? Has that problem already been
reported in the past and I simply didn't find it? Is this worth
reporting a bug or already fixed in current versions of SVN?

Any workarounds you can think of with being able to keep the space in
the URL?

Thanks!

Mit freundlichen Grüßen,

Thorsten Schöning

-- 
Thorsten Schöning       E-Mail: Thorsten.Schoening@AM-SoFT.de
AM-SoFT IT-Systeme      http://www.AM-SoFT.de/

Telefon...........05151-  9468- 55
Fax...............05151-  9468- 88
Mobil..............0178-8 9468- 04

AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow


Re: mod_dav_svn of SVN 1.9.3 doesn't seem to calc repo names from URLs with spaces properly.

Posted by Thorsten Schöning <ts...@am-soft.de>.
Guten Tag Thorsten Schöning,
am Freitag, 14. Juni 2019 um 12:12 schrieben Sie:

> And I think that's the problem: The matched location is forwarded
> using a space to mod_dav_svn, which tries to calculate the repo name
> from the request and that request most likely containes %20 instead of
> the space. So calculation simply fails:

I'm not so sure about that anymore, because it seems the "Location"
configured in httpd gets forwarded to mod_authz_svn and that seems to
handle HEX-encoding as needed:

> conf->base_path = svn_urlpath__canonicalize(d, p);

https://github.com/apache/subversion/blob/1.9.3/subversion/mod_authz_svn/mod_authz_svn.c#L121

> uri = svn_fspath__canonicalize(uri, pool);
> /* Do a little dance to normalize hex encoding. */
> uri = svn_path_uri_decode(uri, pool);
> uri = svn_path_uri_encode(uri, pool);

https://github.com/apache/subversion/blob/1.9.3/subversion/libsvn_subr/dirent_uri.c#L2622

This seems the request might contain the space instead of %20, but I
have some mod_perl-handler on my own and am somewhat sure that that
contained %20 instead of spaces. At least there's code in there
unescaping an URI of a request...

But doesn't change that much overall, I'm still unabale to tell
mod_dav_svn to use the same URLs.

> But I couldn't find anything simple like using spaces in URLs to
> repos.

I'm more convinced now that space is the correct thing to configure
instead of %20 in "Location". Not only because it only works this way,
but as well because such a discussion is more likely for mod_rewrite
and in those case spaces are to be used as well always.

https://stackoverflow.com/questions/410811/mod-rewrite-with-spaces-in-the-urls

> Any workarounds you can think of with being able to keep the space in
> the URL?

I tried simply using a rewrite rule to internally change " " to "_",
and while that works to properly forward requests containing "%20" to
mod_dav_svn, the latter fails again. While I can authenticate
successfully, SVN doesn't error out because of missing authz files and
the client even starts creating the .svn-dir, a checkout doesn't work
in the end because of the following errors: 

> Could not parse 'src-path' URL.  [500, #190001]
> Unusable URI: it does not refer to this repository  [500, #190001]

So internally replacing parts of the URL is not an option. Sending a
redirect to the client instead seems to work:

> RewriteRule "^(svn/Bin/LSG) (BE-BB/.+)$" "$1_$2" [L]
vs.
> RewriteRule "^(svn/Bin/LSG) (BE-BB/.+)$" "$1_$2" [R=301,L]

It seems the only option currently is really to avoid the spaces in
URLs containing the repo name. While keeping them in the configured
SVNParentPath still works!

Mit freundlichen Grüßen,

Thorsten Schöning

-- 
Thorsten Schöning       E-Mail: Thorsten.Schoening@AM-SoFT.de
AM-SoFT IT-Systeme      http://www.AM-SoFT.de/

Telefon...........05151-  9468- 55
Fax...............05151-  9468- 88
Mobil..............0178-8 9468- 04

AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow