move serveruuid into routes
authorJoey Hess <joeyh@joeyh.name>
Thu, 11 Jul 2024 15:19:20 +0000 (11:19 -0400)
committerJoey Hess <joeyh@joeyh.name>
Thu, 11 Jul 2024 15:19:20 +0000 (11:19 -0400)
In particular the generic get route needs it, so that when a single http
server is serving multiple repositories, it knows what repository to
use.

P2P/Http.hs
doc/design/p2p_protocol_over_http/draft1.mdwn

index 8f55f65e267a969355915101df97aec122a8a2ec..7b3eceb5b127304994f499c5b471f3b4174e41d5 100644 (file)
@@ -42,43 +42,43 @@ import Control.Concurrent
 import System.IO.Unsafe
 
 type P2PHttpAPI
-       =    "git-annex" :> PV3 :> "key" :> CaptureKey :> GetAPI
-       :<|> "git-annex" :> PV2 :> "key" :> CaptureKey :> GetAPI
-       :<|> "git-annex" :> PV1 :> "key" :> CaptureKey :> GetAPI
-       :<|> "git-annex" :> PV0 :> "key" :> CaptureKey :> GetAPI
-       :<|> "git-annex" :> PV3 :> "checkpresent" :> CheckPresentAPI
-       :<|> "git-annex" :> PV2 :> "checkpresent" :> CheckPresentAPI
-       :<|> "git-annex" :> PV1 :> "checkpresent" :> CheckPresentAPI
-       :<|> "git-annex" :> PV0 :> "checkpresent" :> CheckPresentAPI
-       :<|> "git-annex" :> PV3 :> "remove" :> RemoveAPI RemoveResultPlus
-       :<|> "git-annex" :> PV2 :> "remove" :> RemoveAPI RemoveResultPlus
-       :<|> "git-annex" :> PV1 :> "remove" :> RemoveAPI RemoveResult
-       :<|> "git-annex" :> PV0 :> "remove" :> RemoveAPI RemoveResult
-       :<|> "git-annex" :> PV3 :> "remove-before" :> RemoveBeforeAPI
-       :<|> "git-annex" :> PV3 :> "gettimestamp" :> GetTimestampAPI
-       :<|> "git-annex" :> PV3 :> "put" :> DataLengthHeader
+       =    "git-annex" :> SU :> PV3 :> "key" :> GetAPI
+       :<|> "git-annex" :> SU :> PV2 :> "key" :> GetAPI
+       :<|> "git-annex" :> SU :> PV1 :> "key" :> GetAPI
+       :<|> "git-annex" :> SU :> PV0 :> "key" :> GetAPI
+       :<|> "git-annex" :> SU :> PV3 :> "checkpresent" :> CheckPresentAPI
+       :<|> "git-annex" :> SU :> PV2 :> "checkpresent" :> CheckPresentAPI
+       :<|> "git-annex" :> SU :> PV1 :> "checkpresent" :> CheckPresentAPI
+       :<|> "git-annex" :> SU :> PV0 :> "checkpresent" :> CheckPresentAPI
+       :<|> "git-annex" :> SU :> PV3 :> "remove" :> RemoveAPI RemoveResultPlus
+       :<|> "git-annex" :> SU :> PV2 :> "remove" :> RemoveAPI RemoveResultPlus
+       :<|> "git-annex" :> SU :> PV1 :> "remove" :> RemoveAPI RemoveResult
+       :<|> "git-annex" :> SU :> PV0 :> "remove" :> RemoveAPI RemoveResult
+       :<|> "git-annex" :> SU :> PV3 :> "remove-before" :> RemoveBeforeAPI
+       :<|> "git-annex" :> SU :> PV3 :> "gettimestamp" :> GetTimestampAPI
+       :<|> "git-annex" :> SU :> PV3 :> "put" :> DataLengthHeader
                :> PutAPI PutResultPlus
-       :<|> "git-annex" :> PV2 :> "put" :> DataLengthHeader
+       :<|> "git-annex" :> SU :> PV2 :> "put" :> DataLengthHeader
                :> PutAPI PutResultPlus
-       :<|> "git-annex" :> PV1 :> "put" :> DataLengthHeader
+       :<|> "git-annex" :> SU :> PV1 :> "put" :> DataLengthHeader
                :> PutAPI PutResult
-       :<|> "git-annex" :> PV0 :> "put"
+       :<|> "git-annex" :> SU :> PV0 :> "put"
                :> PutAPI PutResult
-       :<|> "git-annex" :> PV3 :> "putoffset"
+       :<|> "git-annex" :> SU :> PV3 :> "putoffset"
                :> PutOffsetAPI PutOffsetResultPlus
-       :<|> "git-annex" :> PV2 :> "putoffset"
+       :<|> "git-annex" :> SU :> PV2 :> "putoffset"
                :> PutOffsetAPI PutOffsetResultPlus
-       :<|> "git-annex" :> PV1 :> "putoffset"
+       :<|> "git-annex" :> SU :> PV1 :> "putoffset"
                :> PutOffsetAPI PutOffsetResult
-       :<|> "git-annex" :> PV3 :> "lockcontent" :> LockContentAPI
-       :<|> "git-annex" :> PV2 :> "lockcontent" :> LockContentAPI
-       :<|> "git-annex" :> PV1 :> "lockcontent" :> LockContentAPI
-       :<|> "git-annex" :> PV0 :> "lockcontent" :> LockContentAPI
-       :<|> "git-annex" :> PV3 :> "keeplocked" :> KeepLockedAPI
-       :<|> "git-annex" :> PV2 :> "keeplocked" :> KeepLockedAPI
-       :<|> "git-annex" :> PV1 :> "keeplocked" :> KeepLockedAPI
-       :<|> "git-annex" :> PV0 :> "keeplocked" :> KeepLockedAPI
-       :<|> "git-annex" :> "key" :> CaptureKey :> GetGenericAPI
+       :<|> "git-annex" :> SU :> PV3 :> "lockcontent" :> LockContentAPI
+       :<|> "git-annex" :> SU :> PV2 :> "lockcontent" :> LockContentAPI
+       :<|> "git-annex" :> SU :> PV1 :> "lockcontent" :> LockContentAPI
+       :<|> "git-annex" :> SU :> PV0 :> "lockcontent" :> LockContentAPI
+       :<|> "git-annex" :> SU :> PV3 :> "keeplocked" :> KeepLockedAPI
+       :<|> "git-annex" :> SU :> PV2 :> "keeplocked" :> KeepLockedAPI
+       :<|> "git-annex" :> SU :> PV1 :> "keeplocked" :> KeepLockedAPI
+       :<|> "git-annex" :> SU :> PV0 :> "keeplocked" :> KeepLockedAPI
+       :<|> "git-annex" :> SU :> "key" :> GetGenericAPI
 
 p2pHttpAPI :: Proxy P2PHttpAPI
 p2pHttpAPI = Proxy
@@ -105,7 +105,7 @@ serveP2pHttp st
        :<|> servePut st id
        :<|> servePut st id
        :<|> servePut st dePlus
-       :<|> (\v -> servePut st dePlus v Nothing)
+       :<|> (\su v -> servePut st dePlus su v Nothing)
        :<|> servePutOffset st id
        :<|> servePutOffset st id
        :<|> servePutOffset st dePlus
@@ -119,14 +119,20 @@ serveP2pHttp st
        :<|> serveKeepLocked st
        :<|> serveGetGeneric st
 
-type GetGenericAPI = StreamGet NoFraming OctetStream (SourceIO B.ByteString)
+type GetGenericAPI
+       = CaptureKey
+       :> StreamGet NoFraming OctetStream (SourceIO B.ByteString)
 
-serveGetGeneric :: P2PHttpServerState -> B64Key -> Handler (S.SourceT IO B.ByteString)
-serveGetGeneric = undefined -- TODO
+serveGetGeneric
+       :: P2PHttpServerState
+       -> B64UUID ServerSide
+       -> B64Key
+       -> Handler (S.SourceT IO B.ByteString)
+serveGetGeneric st su k = undefined -- serveGet st V0 k
 
 type GetAPI
-       = ClientUUID Required
-       :> ServerUUID Required
+       = CaptureKey
+       :> CU Required
        :> BypassUUIDs
        :> AssociatedFileParam
        :> OffsetParam
@@ -138,17 +144,17 @@ type GetAPI
 serveGet
        :: APIVersion v
        => P2PHttpServerState
+       -> B64UUID ServerSide
        -> v
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Maybe B64FilePath
        -> Maybe Offset
        -> IsSecure
        -> Maybe Auth
        -> Handler (Headers '[DataLengthHeader] (S.SourceT IO B.ByteString))
-serveGet st apiver (B64Key k) cu su bypass baf startat sec auth = do
+serveGet st su apiver (B64Key k) cu bypass baf startat sec auth = do
        conn <- getP2PConnection apiver st cu su bypass sec auth ReadAction
        bsv <- liftIO newEmptyTMVarIO
        endv <- liftIO newEmptyTMVarIO
@@ -232,15 +238,15 @@ clientGet
        :: ClientEnv
        -> ProtocolVersion
        -> B64Key
-       -> B64UUID ClientSide
        -> B64UUID ServerSide
+       -> B64UUID ClientSide
        -> [B64UUID Bypass]
        -> Maybe B64FilePath
        -> Maybe Offset
        -> Maybe Auth
        -> IO ()
-clientGet clientenv ver k cu su bypass af o auth =
-       withClientM (clientGet' ver k cu su bypass af o auth) clientenv $ \case
+clientGet clientenv ver k su cu bypass af o auth =
+       withClientM (clientGet' su ver k cu bypass af o auth) clientenv $ \case
                Left err -> throwM err
                Right respheaders -> do
                        let dl = case lookupResponseHeader @DataLengthHeader' respheaders of
@@ -261,28 +267,27 @@ gatherByteString = unsafeInterleaveIO . go
        go (S.Yield v s) = LI.Chunk v <$> unsafeInterleaveIO (go s)
 
 clientGet'
-       :: ProtocolVersion
+       :: B64UUID ServerSide
+       -> ProtocolVersion
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Maybe B64FilePath
        -> Maybe Offset
        -> Maybe Auth
        -> ClientM (Headers '[DataLengthHeader] (S.SourceT IO B.ByteString))
-clientGet' (ProtocolVersion ver) = case ver of
-       3 -> v3 V3
-       2 -> v2 V2
-       1 -> v1 V1
-       0 -> v0 V0
+clientGet' su (ProtocolVersion ver) = case ver of
+       3 -> v3 su V3
+       2 -> v2 su V2
+       1 -> v1 su V1
+       0 -> v0 su V0
        _ -> error "unsupported protocol version"
   where
        v3 :<|> v2 :<|> v1 :<|> v0 :<|> _ = client p2pHttpAPI
 
 type CheckPresentAPI
        = KeyParam
-       :> ClientUUID Required
-       :> ServerUUID Required
+       :> CU Required
        :> BypassUUIDs
        :> IsSecure
        :> AuthHeader
@@ -291,15 +296,15 @@ type CheckPresentAPI
 serveCheckPresent
        :: APIVersion v
        => P2PHttpServerState
+       -> B64UUID ServerSide
        -> v
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> IsSecure
        -> Maybe Auth
        -> Handler CheckPresentResult
-serveCheckPresent st apiver (B64Key k) cu su bypass sec auth = do
+serveCheckPresent st su apiver (B64Key k) cu bypass sec auth = do
        res <- withP2PConnection apiver st cu su bypass sec auth ReadAction
                $ \conn -> liftIO $ proxyClientNetProto conn $ checkPresent k
        case res of
@@ -316,15 +321,15 @@ clientCheckPresent
        -> Maybe Auth
        -> IO Bool
 clientCheckPresent clientenv (ProtocolVersion ver) key cu su bypass auth =
-       withClientM (cli key cu su bypass auth) clientenv $ \case
+       withClientM (cli su key cu bypass auth) clientenv $ \case
                Left err -> throwM err
                Right (CheckPresentResult res) -> return res
   where
        cli = case ver of
-               3 -> v3 V3
-               2 -> v2 V2
-               1 -> v1 V1
-               0 -> v0 V0
+               3 -> flip v3 V3
+               2 -> flip v2 V2
+               1 -> flip v1 V1
+               0 -> flip v0 V0
                _ -> error "unsupported protocol version"
        
        _ :<|> _ :<|> _ :<|> _ :<|>
@@ -332,8 +337,7 @@ clientCheckPresent clientenv (ProtocolVersion ver) key cu su bypass auth =
 
 type RemoveAPI result
        = KeyParam
-       :> ClientUUID Required
-       :> ServerUUID Required
+       :> CU Required
        :> BypassUUIDs
        :> IsSecure
        :> AuthHeader
@@ -343,15 +347,15 @@ serveRemove
        :: APIVersion v
        => P2PHttpServerState
        -> (RemoveResultPlus -> t)
+       -> B64UUID ServerSide
        -> v
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> IsSecure
        -> Maybe Auth
        -> Handler t
-serveRemove st resultmangle apiver (B64Key k) cu su bypass sec auth = do
+serveRemove st resultmangle su apiver (B64Key k) cu bypass sec auth = do
        res <- withP2PConnection apiver st cu su bypass sec auth RemoveAction
                $ \conn ->
                        liftIO $ proxyClientNetProto conn $ remove Nothing k
@@ -376,10 +380,10 @@ clientRemove clientenv (ProtocolVersion ver) key cu su bypass auth =
                Right res -> return res
   where
        cli = case ver of
-               3 -> v3 V3 key cu su bypass auth
-               2 -> v2 V2 key cu su bypass auth
-               1 -> plus <$> v1 V1 key cu su bypass auth
-               0 -> plus <$> v0 V0 key cu su bypass auth
+               3 -> v3 su V3 key cu bypass auth
+               2 -> v2 su V2 key cu bypass auth
+               1 -> plus <$> v1 su V1 key cu bypass auth
+               0 -> plus <$> v0 su V0 key cu bypass auth
                _ -> error "unsupported protocol version"
        
        _ :<|> _ :<|> _ :<|> _ :<|>
@@ -388,8 +392,7 @@ clientRemove clientenv (ProtocolVersion ver) key cu su bypass auth =
 
 type RemoveBeforeAPI
        = KeyParam
-       :> ClientUUID Required
-       :> ServerUUID Required
+       :> CU Required
        :> BypassUUIDs
        :> QueryParam' '[Required] "timestamp" Timestamp
        :> IsSecure
@@ -399,16 +402,16 @@ type RemoveBeforeAPI
 serveRemoveBefore
        :: APIVersion v
        => P2PHttpServerState
+       -> B64UUID ServerSide
        -> v
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Timestamp
        -> IsSecure
        -> Maybe Auth
        -> Handler RemoveResultPlus
-serveRemoveBefore st apiver (B64Key k) cu su bypass (Timestamp ts) sec auth = do
+serveRemoveBefore st su apiver (B64Key k) cu bypass (Timestamp ts) sec auth = do
        res <- withP2PConnection apiver st cu su bypass sec auth RemoveAction
                $ \conn ->
                        liftIO $ proxyClientNetProto conn $
@@ -430,12 +433,12 @@ clientRemoveBefore
        -> Maybe Auth
        -> IO RemoveResultPlus
 clientRemoveBefore clientenv (ProtocolVersion ver) key cu su bypass ts auth =
-       withClientM (cli key cu su bypass ts auth) clientenv $ \case
+       withClientM (cli su key cu bypass ts auth) clientenv $ \case
                Left err -> throwM err
                Right res -> return res
   where
        cli = case ver of
-               3 -> v3 V3
+               3 -> flip v3 V3
                _ -> error "unsupported protocol version"
        
        _ :<|> _ :<|> _ :<|> _ :<|>
@@ -444,8 +447,7 @@ clientRemoveBefore clientenv (ProtocolVersion ver) key cu su bypass ts auth =
                v3 :<|> _ = client p2pHttpAPI
 
 type GetTimestampAPI
-       = ClientUUID Required
-       :> ServerUUID Required
+       = CU Required
        :> BypassUUIDs
        :> IsSecure
        :> AuthHeader
@@ -454,14 +456,14 @@ type GetTimestampAPI
 serveGetTimestamp
        :: APIVersion v
        => P2PHttpServerState
+       -> B64UUID ServerSide
        -> v
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> IsSecure
        -> Maybe Auth
        -> Handler GetTimestampResult
-serveGetTimestamp st apiver cu su bypass sec auth = do
+serveGetTimestamp st su apiver cu bypass sec auth = do
        res <- withP2PConnection apiver st cu su bypass sec auth ReadAction
                $ \conn ->
                        liftIO $ proxyClientNetProto conn getTimestamp
@@ -479,12 +481,12 @@ clientGetTimestamp
        -> Maybe Auth
        -> IO GetTimestampResult
 clientGetTimestamp clientenv (ProtocolVersion ver) cu su bypass auth = 
-       withClientM (cli cu su bypass auth) clientenv $ \case
+       withClientM (cli su cu bypass auth) clientenv $ \case
                Left err -> throwM err
                Right res -> return res
   where
        cli = case ver of
-               3 -> v3 V3
+               3 -> flip v3 V3
                _ -> error "unsupported protocol version"
        
        _ :<|> _ :<|> _ :<|> _ :<|>
@@ -495,8 +497,7 @@ clientGetTimestamp clientenv (ProtocolVersion ver) cu su bypass auth =
 
 type PutAPI result
        = KeyParam
-       :> ClientUUID Required
-       :> ServerUUID Required
+       :> CU Required
        :> BypassUUIDs
        :> AssociatedFileParam
        :> OffsetParam
@@ -508,11 +509,11 @@ servePut
        :: APIVersion v
        => P2PHttpServerState
        -> (PutResultPlus -> t)
+       -> B64UUID ServerSide
        -> v
        -> Maybe Integer
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Maybe B64FilePath
        -> Maybe Offset
@@ -534,10 +535,10 @@ clientPut
        -> S.SourceT IO B.ByteString
        -> ClientM PutResultPlus
 clientPut (ProtocolVersion ver) sz k cu su bypass af o l src = case ver of
-       3 -> v3 V3 sz k cu su bypass af o l src
-       2 -> v2 V2 sz k cu su bypass af o l src
-       1 -> plus <$> v1 V1 sz k cu su bypass af o l src
-       0 -> plus <$> v0 V0 k cu su bypass af o l src
+       3 -> v3 su V3 sz k cu bypass af o l src
+       2 -> v2 su V2 sz k cu bypass af o l src
+       1 -> plus <$> v1 su V1 sz k cu bypass af o l src
+       0 -> plus <$> v0 su V0 k cu bypass af o l src
        _ -> error "unsupported protocol version"
   where
        _ :<|> _ :<|> _ :<|> _ :<|>
@@ -549,8 +550,7 @@ clientPut (ProtocolVersion ver) sz k cu su bypass af o l src = case ver of
 
 type PutOffsetAPI result
        = KeyParam
-       :> ClientUUID Required
-       :> ServerUUID Required
+       :> CU Required
        :> BypassUUIDs
        :> Post '[JSON] result
 
@@ -558,24 +558,24 @@ servePutOffset
        :: APIVersion v
        => P2PHttpServerState
        -> (PutOffsetResultPlus -> t)
+       -> B64UUID ServerSide
        -> v
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Handler t
 servePutOffset = undefined -- TODO
 
 clientPutOffset
-       :: ProtocolVersion
+       :: B64UUID ServerSide
+       -> ProtocolVersion
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> ClientM PutOffsetResultPlus
-clientPutOffset (ProtocolVersion ver) = case ver of
-       3 -> v3 V3
-       2 -> v2 V2
+clientPutOffset su (ProtocolVersion ver) = case ver of
+       3 -> v3 su V3
+       2 -> v2 su V2
        _ -> error "unsupported protocol version"
   where
        _ :<|> _ :<|> _ :<|> _ :<|>
@@ -588,34 +588,33 @@ clientPutOffset (ProtocolVersion ver) = case ver of
 
 type LockContentAPI
        = KeyParam
-       :> ClientUUID Required
-       :> ServerUUID Required
+       :> CU Required
        :> BypassUUIDs
        :> Post '[JSON] LockResult
 
 serveLockContent
        :: APIVersion v
        => P2PHttpServerState
+       -> B64UUID ServerSide
        -> v
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Handler LockResult
 serveLockContent = undefined -- TODO
 
 clientLockContent
-       :: ProtocolVersion
+       :: B64UUID ServerSide
+       -> ProtocolVersion
        -> B64Key
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> ClientM LockResult
-clientLockContent (ProtocolVersion ver) = case ver of
-       3 -> v3 V3
-       2 -> v2 V2
-       1 -> v1 V1
-       0 -> v0 V0
+clientLockContent su (ProtocolVersion ver) = case ver of
+       3 -> v3 su V3
+       2 -> v2 su V2
+       1 -> v1 su V1
+       0 -> v0 su V0
        _ -> error "unsupported protocol version"
   where
        _ :<|> _ :<|> _ :<|> _ :<|>
@@ -629,8 +628,7 @@ clientLockContent (ProtocolVersion ver) = case ver of
 
 type KeepLockedAPI
        = LockIDParam
-       :> ClientUUID Required
-       :> ServerUUID Required
+       :> CU Required
        :> BypassUUIDs
        :> Header "Connection" ConnectionKeepAlive
        :> Header "Keep-Alive" KeepAlive
@@ -640,16 +638,16 @@ type KeepLockedAPI
 serveKeepLocked
        :: APIVersion v
        => P2PHttpServerState
+       -> B64UUID ServerSide
        -> v
        -> LockID
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Maybe ConnectionKeepAlive
        -> Maybe KeepAlive
        -> S.SourceT IO UnlockRequest
        -> Handler LockResult
-serveKeepLocked st apiver lckid cu su _ _ _ unlockrequeststream = do
+serveKeepLocked st su apiver lckid cu _ _ _ unlockrequeststream = do
        _ <- liftIO $ S.unSourceT unlockrequeststream go
        return (LockResult False Nothing)
   where
@@ -661,20 +659,20 @@ serveKeepLocked st apiver lckid cu su _ _ _ unlockrequeststream = do
        go (S.Yield (UnlockRequest True) _) = dropLock lckid st
 
 clientKeepLocked'
-       :: ProtocolVersion
+       :: B64UUID ServerSide
+       -> ProtocolVersion
        -> LockID
        -> B64UUID ClientSide
-       -> B64UUID ServerSide
        -> [B64UUID Bypass]
        -> Maybe ConnectionKeepAlive
        -> Maybe KeepAlive
        -> S.SourceT IO UnlockRequest
        -> ClientM LockResult
-clientKeepLocked' (ProtocolVersion ver) = case ver of
-       3 -> v3 V3
-       2 -> v2 V2
-       1 -> v1 V1
-       0 -> v0 V0
+clientKeepLocked' su (ProtocolVersion ver) = case ver of
+       3 -> v3 su V3
+       2 -> v2 su V2
+       1 -> v1 su V1
+       0 -> v0 su V0
        _ -> error "unsupported protocol version"
   where
        _ :<|> _ :<|> _ :<|> _ :<|>
@@ -697,7 +695,7 @@ clientKeepLocked
        -> TMVar Bool
        -> IO ()
 clientKeepLocked clientenv protover lckid cu su bypass keeplocked = do
-       let cli = clientKeepLocked' protover lckid cu su bypass
+       let cli = clientKeepLocked' su protover lckid cu bypass
                (Just connectionKeepAlive) (Just keepAlive)
                (S.fromStepT unlocksender)
        withClientM cli clientenv $ \case
@@ -724,9 +722,9 @@ type PV1 = Capture "v1" V1
 
 type PV0 = Capture "v0" V0
 
-type ClientUUID req = QueryParam' '[req] "clientuuid" (B64UUID ClientSide)
+type SU = Capture "serveruuid" (B64UUID ServerSide)
 
-type ServerUUID req = QueryParam' '[req] "serveruuid" (B64UUID ServerSide)
+type CU req = QueryParam' '[req] "clientuuid" (B64UUID ClientSide)
 
 type BypassUUIDs = QueryParams "bypass" (B64UUID Bypass)
 
index c8f9975769f208156f2bb0e53a65e4c31924d1cb..90c30295222bfa94a1024dfa4dae835380345b94 100644 (file)
@@ -45,18 +45,13 @@ back to an earlier protocol version.
 
 ## common request parameters
 
-Every request supports these common parameters, and unless documented
-otherwise, a request requires both of them to be included.
+Every request supports this parameter, and unless documented
+otherwise, a request it to be included.
 
 * `clientuuid`  
 
   The value is the UUID of the git-annex repository of the client.
 
-* `serveruuid`
-
-  The value is the UUID of the git-annex repository that the server
-  should serve.
-
 Any request may also optionally include these parameters:
 
 * `bypass`
@@ -71,15 +66,17 @@ Any request may also optionally include these parameters:
   This parameter is only available for v2 and above.
 
 [Internally, git-annex can use these common parameters, plus the protocol
-version, to create a P2P session. The P2P session is driven through
-the AUTH, VERSION, and BYPASS messages, leaving the session ready to
-service requests.]
+version, and remote UUID, to create a P2P session. The P2P session is
+driven through the AUTH, VERSION, and BYPASS messages, leaving the session
+ready to service requests.]
 
 ## requests
 
-### GET /git-annex/key/$key
+### GET /git-annex/$uuid/key/$key
+
+This is a simple, unversioned interface to get the content of a key
+from a repository.
 
-This is a simple, unversioned interface to get a key from the server.
 It is not part of the P2P protocol per se, but is provided to let
 other clients than git-annex easily download the content of keys from the
 http server.
@@ -87,21 +84,18 @@ http server.
 When the key is not present on the server, it will respond
 with 404 Not Found.
 
-### GET /git-annex/v3/key/$key
+### GET /git-annex/$uuid/v3/key/$key
 
-Get the content of a key from the server.
+Get the content of a key from the repository with the specified uuid.
 
 Example:
 
-    > GET /git-annex/v3/key/SHA1--foo&associatedfile=bar&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
+    > GET /git-annex/ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6/v3/key/SHA1--foo&associatedfile=bar&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925 HTTP/1.1
     < X-git-annex-data-length: 3
     < Content-Type: application/octet-stream
     < 
     < foo
 
-The key to get is the part of the url after "/git-annex/vN/key/"
-and before any url parameters.
-
 All parameters are optional, including the common parameters, and these:
 
 * `associatedfile`
@@ -135,26 +129,26 @@ an unlocked annexed file, which got modified while it was being sent.
 When the content is not present, the server will respond with 
 422 Unprocessable Content.
 
-### GET /git-annex/v2/key/$key
+### GET /git-annex/$uuid/v2/key/$key
 
 Identical to v3.
 
-### GET /git-annex/v1/key/$key
+### GET /git-annex/$uuid/v1/key/$key
 
 Identical to v3.
 
-### GET /git-annex/v0/key/$key
+### GET /git-annex/$uuid/v0/key/$key
 
 Same as v3, except the X-git-annex-data-length header is not used.
 Additional checking client-side will be required to validate the data.
 
-### POST /git-annex/v3/checkpresent
+### POST /git-annex/$uuid/v3/checkpresent
 
 Checks if a key is currently present on the server.
 
 Example:
 
-    > POST /git-annex/v3/checkpresent?key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
+    > POST /git-annex/ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6/v3/checkpresent?key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925 HTTP/1.1
     < {"present": true}
 
 There is one required additional parameter, `key`.
@@ -164,25 +158,25 @@ The body of the request is empty.
 The server responds with a JSON object with a "present" field that is true
 if the key is present, or false if it is not present.
 
-### POST /git-annex/v2/checkpresent
+### POST /git-annex/$uuid/v2/checkpresent
 
 Identical to v3.
 
-### POST /git-annex/v1/checkpresent
+### POST /git-annex/$uuid/v1/checkpresent
 
 Identical to v3.
 
-### POST /git-annex/v0/checkpresent
+### POST /git-annex/$uuid/v0/checkpresent
 
 Identical to v3.
 
-### POST /git-annex/v3/lockcontent
+### POST /git-annex/$uuid/v3/lockcontent
 
 Locks the content of a key on the server, preventing it from being removed.
 
 Example:
 
-    > POST /git-annex/v3/lockcontent?key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
+    > POST /git-annex/ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6/v3/lockcontent?key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925 HTTP/1.1
     < {"locked": true, "lockid": "foo"}
 
 There is one required additional parameter, `key`.
@@ -194,26 +188,26 @@ The key will remain locked for 10 minutes. But, usually `keeplocked`
 is used to control the lifetime of the lock, using the "lockid"
 parameter from the server's reply. (See below.)
 
-### POST /git-annex/v2/lockcontent
+### POST /git-annex/$uuid/v2/lockcontent
 
 Identical to v3.
 
-### POST /git-annex/v1/lockcontent
+### POST /git-annex/$uuid/v1/lockcontent
 
 Identical to v3.
 
-### POST /git-annex/v0/lockcontent
+### POST /git-annex/$uuid/v0/lockcontent
 
 Identical to v3.
 
-### POST /git-annex/v3/keeplocked
+### POST /git-annex/$uuid/v3/keeplocked
 
 Controls the lifetime of a lock on a key that was earlier obtained
 with `lockcontent`.
 
 Example:
 
-    > POST /git-annex/v3/keeplocked?lockid=foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
+    > POST /git-annex/ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6/v3/keeplocked?lockid=foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925 HTTP/1.1
     > Connection: Keep-Alive
     > Keep-Alive: timeout=1200
     [some time later]
@@ -240,25 +234,25 @@ If the connection is closed before the client sends `{"unlock": true},
 or even if the web server gets shut down, the content will remain
 locked for 10 minutes from the time it was first locked.
 
-### POST /git-annex/v2/keeplocked
+### POST /git-annex/$uuid/v2/keeplocked
 
 Identical to v3.
 
-### POST /git-annex/v1/keeplocked
+### POST /git-annex/$uuid/v1/keeplocked
 
 Identical to v3.
 
-### POST /git-annex/v0/keeplocked
+### POST /git-annex/$uuid/v0/keeplocked
 
 Identical to v3.
 
-### POST /git-annex/v3/remove
+### POST /git-annex/$uuid/v3/remove
 
 Remove a key's content from the server.
 
 Example:
 
-    > POST /git-annex/v3/remove?key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
+    > POST /git-annex/ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6/v3/remove?key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925 HTTP/1.1
     < {"removed": true}
 
 There is one required additional parameter, `key`.
@@ -272,25 +266,25 @@ or false if the key was not able to be removed.
 The JSON object can have an additional field "plusuuids" that is a list of
 UUIDs of other repositories that the content was removed from.
 
-### POST /git-annex/v2/remove
+### POST /git-annex/$uuid/v2/remove
 
 Identical to v3.
 
-### POST /git-annex/v1/remove
+### POST /git-annex/$uuid/v1/remove
 
 Same as v3, except the JSON will not include "plusuuids".
 
-### POST /git-annex/v0/remove
+### POST /git-annex/$uuid/v0/remove
 
 Identival to v1.
 
-## POST /git-annex/v3/remove-before
+## POST /git-annex/$uuid/v3/remove-before
 
 Remove a key's content from the server, but only before a specified time.
 
 Example:
 
-    > POST /git-annex/v3/remove-before?timestamp=4949292929&key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
+    > POST /git-annex/ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6/v3/remove-before?timestamp=4949292929&key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925 HTTP/1.1
     < {"removed": true}
 
 This is the same as the `remove` request, but with an additional parameter,
@@ -302,13 +296,13 @@ removal will fail and the server will respond with: `{"removed": false}`
 This is used to avoid removing content after a point in 
 time where it is no longer locked in other repostitories.
 
-## POST /git-annex/v3/gettimestamp
+## POST /git-annex/$uuid/v3/gettimestamp
 
 Gets the current timestamp from the server.
 
 Example:
 
-    > POST /git-annex/v3/gettimestamp?clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
+    > POST /git-annex/ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6/v3/gettimestamp?clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925 HTTP/1.1
     < {"timestamp": 59459392}
 
 The body of the request is empty.
@@ -319,13 +313,13 @@ current value of its monotonic clock, as a number of seconds.
 Important: If multiple servers are serving this protocol for the same
 repository, they MUST all use the same monotonic clock.
 
-### POST /git-annex/v3/put
+### POST /git-annex/$uuid/v3/put
 
 Store content on the server.
 
 Example:
 
-    > POST /git-annex/v3/put?key=SHA1--foo&associatedfile=bar&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
+    > POST /git-annex/ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6/v3/put?key=SHA1--foo&associatedfile=bar&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925 HTTP/1.1
     > Content-Type: application/octet-stream
     > X-git-annex-data-length: 3
     > 
@@ -363,20 +357,20 @@ that is true if it received the data and stored the content.
 The JSON object can have an additional field "plusuuids" that is a list of
 UUIDs of other repositories that the content was stored to.
 
-### POST /git-annex/v2/put
+### POST /git-annex/$uuid/v2/put
 
 Identical to v3.
 
-### POST /git-annex/v1/put
+### POST /git-annex/$uuid/v1/put
 
 Same as v3, except the JSON will not include "plusuuids".
 
-### POST /git-annex/v0/put
+### POST /git-annex/$uuid/v0/put
 
 Same as v1, except there is no X-git-annex-data-length header.
 Additional checking client-side will be required to validate the data.
 
-### POST /git-annex/v3/putoffset
+### POST /git-annex/$uuid/v3/putoffset
 
 Asks the server what `offset` can be used in a `put` of a key.
 
@@ -386,7 +380,7 @@ the `put` request failing.
 
 Example:
 
-    > POST /git-annex/v3/putoffset?key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925&serveruuid=ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6 HTTP/1.1
+    > POST /git-annex/ecf6d4ca-07e8-11ef-8990-9b8c1f696bf6/v3/putoffset?key=SHA1--foo&clientuuid=79a5a1f4-07e8-11ef-873d-97f93ca91925 HTTP/1.1
     < {"offset": 10}
 
 There is one required additional parameter, `key`.
@@ -408,11 +402,11 @@ part way through a `PUT`, a synthetic empty `DATA` followed by `INVALID`
 will be used to get the P2P protocol back into a state where it will accept
 any request.]
 
-### POST /git-annex/v2/putoffset
+### POST /git-annex/$uuid/v2/putoffset
 
 Identical to v3.
 
-### POST /git-annex/v1/putoffset
+### POST /git-annex/$uuid/v1/putoffset
 
 Same as v3, except the JSON will not include "plusuuids".