add readonly mode to serve P2P protocol

This will be used by git-annex-shell when configured to be readonly.

This commit was sponsored by Nick Daly on Patreon.
This commit is contained in:
Joey Hess 2018-03-07 13:15:55 -04:00
parent bd8c13e75b
commit 572a45ae00
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 33 additions and 18 deletions

View file

@ -351,10 +351,13 @@ serveAuth myuuid = serverLoop handler
return ServerContinue
handler _ = return ServerUnexpected
data ServerMode = ServeReadOnly | ServeReadWrite
-- | Serve the protocol, with a peer that has authenticated.
serveAuthed :: UUID -> Proto ()
serveAuthed myuuid = void $ serverLoop handler
serveAuthed :: ServerMode -> UUID -> Proto ()
serveAuthed servermode myuuid = void $ serverLoop handler
where
readonlyerror = net $ sendMessage (ERROR "this repository is read-only; write access denied")
handler (LOCKCONTENT key) = do
local $ tryLockContent key $ \locked -> do
sendSuccess locked
@ -367,27 +370,39 @@ serveAuthed myuuid = void $ serverLoop handler
handler (CHECKPRESENT key) = do
sendSuccess =<< local (checkContentPresent key)
return ServerContinue
handler (REMOVE key) = do
sendSuccess =<< local (removeContent key)
return ServerContinue
handler (PUT af key) = do
have <- local $ checkContentPresent key
if have
then net $ sendMessage ALREADY_HAVE
else do
let sizer = tmpContentSize key
let storer = storeContent key af
ok <- receiveContent nullMeterUpdate sizer storer PUT_FROM
when ok $
local $ setPresent key myuuid
return ServerContinue
handler (REMOVE key) = case servermode of
ServeReadWrite -> do
sendSuccess =<< local (removeContent key)
return ServerContinue
ServeReadOnly -> do
readonlyerror
return ServerContinue
handler (PUT af key) = case servermode of
ServeReadWrite -> do
have <- local $ checkContentPresent key
if have
then net $ sendMessage ALREADY_HAVE
else do
let sizer = tmpContentSize key
let storer = storeContent key af
ok <- receiveContent nullMeterUpdate sizer storer PUT_FROM
when ok $
local $ setPresent key myuuid
return ServerContinue
ServeReadOnly -> do
readonlyerror
return ServerContinue
handler (GET offset key af) = do
void $ sendContent af key offset nullMeterUpdate
-- setPresent not called because the peer may have
-- requested the data but not permanently stored it.
return ServerContinue
handler (CONNECT service) = do
net $ relayService service
let goahead = net $ relayService service
case (servermode, service) of
(ServeReadWrite, _) -> goahead
(ServeReadOnly, UploadPack) -> goahead
(ServeReadOnly, ReceivePack) -> readonlyerror
-- After connecting to git, there may be unconsumed data
-- from the git processes hanging around (even if they
-- exited successfully), so stop serving this connection.