From 2aa9154b1f850ac14cd4291357594da0d59df8d9 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 23 Jul 2024 12:30:27 -0400 Subject: [PATCH] require a valid uuid at the end of an annex+http url --- P2P/Http/Url.hs | 34 ++++++++++++++++++++------ doc/design/p2p_protocol_over_http.mdwn | 6 +++-- doc/git-annex-p2phttp.mdwn | 4 +-- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/P2P/Http/Url.hs b/P2P/Http/Url.hs index 5d85b54353..b80ae33350 100644 --- a/P2P/Http/Url.hs +++ b/P2P/Http/Url.hs @@ -9,8 +9,14 @@ module P2P.Http.Url where +import Types.UUID +import Utility.FileSystemEncoding +import Utility.PartialPrelude + import Data.List import Network.URI +import System.FilePath.Posix as P +import qualified Data.UUID as UUID #ifdef WITH_SERVANT import Servant.Client (BaseUrl(..), Scheme(..)) import Text.Read @@ -24,37 +30,49 @@ isP2PHttpProtocolUrl s = "annex+http://" `isPrefixOf` s || "annex+https://" `isPrefixOf` s -data P2PHttpUrl = +data P2PHttpUrl = P2PHttpUrl + { p2pHttpUrlString :: String + , p2pHttpUUID :: Maybe UUID #ifdef WITH_SERVANT - P2PHttpUrl String BaseUrl -#else - P2PHttpUrl String + , p2pHttpBaseUrl :: BaseUrl #endif + } + deriving (Show) parseP2PHttpUrl :: String -> Maybe P2PHttpUrl parseP2PHttpUrl us | isP2PHttpProtocolUrl us = case parseURI (drop prefixlen us) of Nothing -> Nothing + Just u -> #ifdef WITH_SERVANT - Just u -> case uriScheme u of "http:" -> mkbaseurl Http u "https:" -> mkbaseurl Https u _ -> Nothing #else - Just _ -> - Just (P2PHttpUrl us) + Just $ P2PHttpUrl us (extractuuid u) #endif | otherwise = Nothing where prefixlen = length "annex+" + + extractuuid u = do + p <- lastMaybe $ P.splitDirectories (uriPath u) + -- While git-annex generally allows a UUID that is not + -- well formed, here it's important to make sure that the + -- url a user provided really ends with a UUID, so check + -- that it's well formed. + case UUID.fromString p of + Nothing -> Nothing + Just _ -> return (UUID (encodeBS p)) + #ifdef WITH_SERVANT mkbaseurl s u = do auth <- uriAuthority u port <- if null (uriPort auth) then Just defaultP2PHttpProtocolPort else readMaybe (dropWhile (== ':') (uriPort auth)) - return $ P2PHttpUrl us $ BaseUrl + return $ P2PHttpUrl us (extractuuid u) $ BaseUrl { baseUrlScheme = s , baseUrlHost = uriRegName auth , baseUrlPath = uriPath u diff --git a/doc/design/p2p_protocol_over_http.mdwn b/doc/design/p2p_protocol_over_http.mdwn index af3c3702ca..f24d3a6038 100644 --- a/doc/design/p2p_protocol_over_http.mdwn +++ b/doc/design/p2p_protocol_over_http.mdwn @@ -9,8 +9,10 @@ connection (mostly). This is a translation of that protocol to HTTP. To indicate that an url uses this protocol, use `annex+http` or `annex+https` as the url scheme. Such an url uses -port 9417 by default, although another port can be specified. For example, -`annex+http://example.com/` or `annex+http://example.com:80/` +port 9417 by default, although another port can be specified. +The last part of the path of such an url is always the repository uuid. +For example, `annex+http://example.com/git-annex/$uuid` or +`annex+http://example.com:80/git-annex/$uuid` ## base64 encoding of keys, uuids, and filenames diff --git a/doc/git-annex-p2phttp.mdwn b/doc/git-annex-p2phttp.mdwn index dc2a02f236..9102af2d4a 100644 --- a/doc/git-annex-p2phttp.mdwn +++ b/doc/git-annex-p2phttp.mdwn @@ -17,8 +17,8 @@ API. Typically a remote will have `remote.name.url` set to a http url as usual, and `remote.name.annexUrl` set to an annex+http url such as -`annex+http://example.com/`. The annex+http url is served by this -server, and uses port 9417 by default. +`annex+http://example.com/git-annex/$uuid`. The annex+http url is +served by this server, and uses port 9417 by default. As well as serving the git-annex HTTP API, this server provides a convenient way to download the content of any key, by using the path -- 2.30.2