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