protocol version fallback on 404

and prettified errors
This commit is contained in:
Joey Hess 2024-07-23 14:58:49 -04:00
parent 4e15b786ca
commit b7454f1eeb
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 48 additions and 15 deletions

View file

@ -28,6 +28,8 @@ import Annex.Concurrent
import Servant import Servant
import Servant.Client.Streaming import Servant.Client.Streaming
import qualified Servant.Types.SourceT as S import qualified Servant.Types.SourceT as S
import Network.HTTP.Types.Status
import Network.HTTP.Client
import qualified Data.ByteString as B import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Internal as LI import qualified Data.ByteString.Lazy.Internal as LI
@ -44,7 +46,7 @@ type ClientAction a
-> B64UUID ClientSide -> B64UUID ClientSide
-> [B64UUID Bypass] -> [B64UUID Bypass]
-> Maybe Auth -> Maybe Auth
-> Annex a -> Annex (Either ClientError a)
p2pHttpClient p2pHttpClient
:: Remote :: Remote
@ -54,22 +56,38 @@ p2pHttpClient
#endif #endif
-> Annex a -> Annex a
#ifdef WITH_SERVANT #ifdef WITH_SERVANT
p2pHttpClient rmt _fallback clientaction = p2pHttpClient rmt fallback clientaction =
case p2pHttpBaseUrl <$> remoteAnnexP2PHttpUrl (gitconfig rmt) of case p2pHttpBaseUrl <$> remoteAnnexP2PHttpUrl (gitconfig rmt) of
Nothing -> error "internal" Nothing -> error "internal"
Just baseurl -> do Just baseurl -> do
myuuid <- getUUID
mgr <- httpManager <$> getUrlOptions mgr <- httpManager <$> getUrlOptions
let clientenv = mkClientEnv mgr baseurl let clientenv = mkClientEnv mgr baseurl
-- TODO: try other protocol versions go clientenv allProtocolVersions
where
go clientenv (v:vs) = do
myuuid <- getUUID
res <- clientaction clientenv v
(B64UUID (uuid rmt))
(B64UUID myuuid)
[]
Nothing
-- TODO: authentication -- TODO: authentication
-- TODO: catch 404 etc case res of
clientaction clientenv Right resp -> return resp
(ProtocolVersion 3) Left (FailureResponse _ resp)
(B64UUID (uuid rmt)) | statusCode (responseStatusCode resp) == 404 && not (null vs) ->
(B64UUID myuuid) go clientenv vs
[] | otherwise -> fallback $
Nothing show (statusCode (responseStatusCode resp))
++ " " ++
decodeBS (statusMessage (responseStatusCode resp))
Left (ConnectionError ex) -> case fromException ex of
Just (HttpExceptionRequest _ (ConnectionFailure err)) -> fallback $
"unable to connect to HTTP server: " ++ show err
_ -> fallback (show ex)
Left clienterror -> fallback $
"git-annex HTTP API server returned an unexpected response: " ++ show clienterror
go _ [] = error "internal"
#else #else
runP2PHttpClient rmt fallback = fallback "This remote uses an annex+http url, but this version of git-annex is not build with support for that." runP2PHttpClient rmt fallback = fallback "This remote uses an annex+http url, but this version of git-annex is not build with support for that."
#endif #endif
@ -134,8 +152,8 @@ gatherByteString = unsafeInterleaveIO . go
clientCheckPresent :: Key -> ClientAction Bool clientCheckPresent :: Key -> ClientAction Bool
clientCheckPresent key clientenv (ProtocolVersion ver) su cu bypass auth = clientCheckPresent key clientenv (ProtocolVersion ver) su cu bypass auth =
liftIO $ withClientM (cli su (B64Key key) cu bypass auth) clientenv $ \case liftIO $ withClientM (cli su (B64Key key) cu bypass auth) clientenv $ \case
Left err -> throwM err Left err -> return (Left err)
Right (CheckPresentResult res) -> return res Right (CheckPresentResult res) -> return (Right res)
where where
cli = case ver of cli = case ver of
3 -> flip v3 V3 3 -> flip v3 V3

View file

@ -63,6 +63,15 @@ defaultProtocolVersion = ProtocolVersion 0
maxProtocolVersion :: ProtocolVersion maxProtocolVersion :: ProtocolVersion
maxProtocolVersion = ProtocolVersion 3 maxProtocolVersion = ProtocolVersion 3
-- In order from newest to oldest.
allProtocolVersions :: [ProtocolVersion]
allProtocolVersions =
[ ProtocolVersion 3
, ProtocolVersion 2
, ProtocolVersion 1
, ProtocolVersion 0
]
newtype ProtoAssociatedFile = ProtoAssociatedFile AssociatedFile newtype ProtoAssociatedFile = ProtoAssociatedFile AssociatedFile
deriving (Show) deriving (Show)

View file

@ -28,12 +28,15 @@ Planned schedule of work:
## work notes ## work notes
* Rest of Remote.Git needs implementing.
* git-annex p2phttp needs to support https. Including serving .well-known
for ACME.
* A Locker should expire the lock on its own after 10 minutes, * A Locker should expire the lock on its own after 10 minutes,
initially. Once keeplocked is called, the expiry should end with the end initially. Once keeplocked is called, the expiry should end with the end
of that call. of that call.
* Allow using annex+http urls in remote.name.annexUrl
* Make http server support proxies and clusters. * Make http server support proxies and clusters.
* `git-annex p2phttp` could support systemd socket activation. This would * `git-annex p2phttp` could support systemd socket activation. This would
@ -52,6 +55,8 @@ Planned schedule of work:
* added git-annex p2phttp command to serve HTTP P2P protocol * added git-annex p2phttp command to serve HTTP P2P protocol
* Allow using annex+http urls in remote.name.annexUrl
## items deferred until later for [[design/passthrough_proxy]] ## items deferred until later for [[design/passthrough_proxy]]
* Check annex.diskreserve when proxying for special remotes * Check annex.diskreserve when proxying for special remotes

View file

@ -320,6 +320,7 @@ Executable git-annex
servant, servant,
servant-server, servant-server,
servant-client, servant-client,
servant-client-core,
warp (>= 3.2.8), warp (>= 3.2.8),
warp-tls (>= 3.2.2) warp-tls (>= 3.2.2)
CPP-Options: -DWITH_SERVANT CPP-Options: -DWITH_SERVANT