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:
parent
bd8c13e75b
commit
572a45ae00
2 changed files with 33 additions and 18 deletions
|
@ -351,10 +351,13 @@ serveAuth myuuid = serverLoop handler
|
||||||
return ServerContinue
|
return ServerContinue
|
||||||
handler _ = return ServerUnexpected
|
handler _ = return ServerUnexpected
|
||||||
|
|
||||||
|
data ServerMode = ServeReadOnly | ServeReadWrite
|
||||||
|
|
||||||
-- | Serve the protocol, with a peer that has authenticated.
|
-- | Serve the protocol, with a peer that has authenticated.
|
||||||
serveAuthed :: UUID -> Proto ()
|
serveAuthed :: ServerMode -> UUID -> Proto ()
|
||||||
serveAuthed myuuid = void $ serverLoop handler
|
serveAuthed servermode myuuid = void $ serverLoop handler
|
||||||
where
|
where
|
||||||
|
readonlyerror = net $ sendMessage (ERROR "this repository is read-only; write access denied")
|
||||||
handler (LOCKCONTENT key) = do
|
handler (LOCKCONTENT key) = do
|
||||||
local $ tryLockContent key $ \locked -> do
|
local $ tryLockContent key $ \locked -> do
|
||||||
sendSuccess locked
|
sendSuccess locked
|
||||||
|
@ -367,27 +370,39 @@ serveAuthed myuuid = void $ serverLoop handler
|
||||||
handler (CHECKPRESENT key) = do
|
handler (CHECKPRESENT key) = do
|
||||||
sendSuccess =<< local (checkContentPresent key)
|
sendSuccess =<< local (checkContentPresent key)
|
||||||
return ServerContinue
|
return ServerContinue
|
||||||
handler (REMOVE key) = do
|
handler (REMOVE key) = case servermode of
|
||||||
sendSuccess =<< local (removeContent key)
|
ServeReadWrite -> do
|
||||||
return ServerContinue
|
sendSuccess =<< local (removeContent key)
|
||||||
handler (PUT af key) = do
|
return ServerContinue
|
||||||
have <- local $ checkContentPresent key
|
ServeReadOnly -> do
|
||||||
if have
|
readonlyerror
|
||||||
then net $ sendMessage ALREADY_HAVE
|
return ServerContinue
|
||||||
else do
|
handler (PUT af key) = case servermode of
|
||||||
let sizer = tmpContentSize key
|
ServeReadWrite -> do
|
||||||
let storer = storeContent key af
|
have <- local $ checkContentPresent key
|
||||||
ok <- receiveContent nullMeterUpdate sizer storer PUT_FROM
|
if have
|
||||||
when ok $
|
then net $ sendMessage ALREADY_HAVE
|
||||||
local $ setPresent key myuuid
|
else do
|
||||||
return ServerContinue
|
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
|
handler (GET offset key af) = do
|
||||||
void $ sendContent af key offset nullMeterUpdate
|
void $ sendContent af key offset nullMeterUpdate
|
||||||
-- setPresent not called because the peer may have
|
-- setPresent not called because the peer may have
|
||||||
-- requested the data but not permanently stored it.
|
-- requested the data but not permanently stored it.
|
||||||
return ServerContinue
|
return ServerContinue
|
||||||
handler (CONNECT service) = do
|
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
|
-- After connecting to git, there may be unconsumed data
|
||||||
-- from the git processes hanging around (even if they
|
-- from the git processes hanging around (even if they
|
||||||
-- exited successfully), so stop serving this connection.
|
-- exited successfully), so stop serving this connection.
|
||||||
|
|
|
@ -128,7 +128,7 @@ serveClient th u r q = bracket setup cleanup start
|
||||||
authed conn theiruuid =
|
authed conn theiruuid =
|
||||||
bracket watchChangedRefs (liftIO . maybe noop stopWatchingChangedRefs) $ \crh -> do
|
bracket watchChangedRefs (liftIO . maybe noop stopWatchingChangedRefs) $ \crh -> do
|
||||||
v' <- runFullProto (Serving theiruuid crh) conn $
|
v' <- runFullProto (Serving theiruuid crh) conn $
|
||||||
P2P.serveAuthed u
|
P2P.serveAuthed P2P.ServeReadWrite u
|
||||||
case v' of
|
case v' of
|
||||||
Right () -> return ()
|
Right () -> return ()
|
||||||
Left e -> liftIO $ debugM "remotedaemon" ("Tor connection error: " ++ e)
|
Left e -> liftIO $ debugM "remotedaemon" ("Tor connection error: " ++ e)
|
||||||
|
|
Loading…
Reference in a new issue