p2phttp: Added --socket option
Used protectedOutput to set up a umask that makes the socket only accessible by the current user. Authentication is still needed when using this option unless it is combined with --wideopen. It was just simpler to keep authentication separate from this.
This commit is contained in:
parent
66b009a0f6
commit
492c484a82
6 changed files with 57 additions and 5 deletions
|
@ -1,6 +1,7 @@
|
|||
git-annex (10.20250631) UNRELEASED; urgency=medium
|
||||
|
||||
* p2phttp: Scan multilevel directories with --directory.
|
||||
* p2phttp: Added --socket option.
|
||||
|
||||
-- Joey Hess <id@joeyh.name> Mon, 07 Jul 2025 15:59:42 -0400
|
||||
|
||||
|
|
|
@ -22,11 +22,13 @@ import qualified Git.Construct
|
|||
import qualified Annex
|
||||
import Types.Concurrency
|
||||
import qualified Utility.RawFilePath as R
|
||||
import Utility.FileMode
|
||||
|
||||
import Servant
|
||||
import qualified Network.Wai.Handler.Warp as Warp
|
||||
import qualified Network.Wai.Handler.WarpTLS as Warp
|
||||
import Network.Socket (PortNumber)
|
||||
import qualified Network.Socket as Socket
|
||||
import System.PosixCompat.Files (isSymbolicLink)
|
||||
import qualified Data.Map as M
|
||||
import Data.String
|
||||
|
@ -42,6 +44,7 @@ cmd = noMessages $ dontCheck repoExists $
|
|||
data Options = Options
|
||||
{ portOption :: Maybe PortNumber
|
||||
, bindOption :: Maybe String
|
||||
, socketOption :: Maybe FilePath
|
||||
, certFileOption :: Maybe FilePath
|
||||
, privateKeyFileOption :: Maybe FilePath
|
||||
, chainFileOption :: [FilePath]
|
||||
|
@ -67,6 +70,10 @@ optParser _ = Options
|
|||
( long "bind" <> metavar paramAddress
|
||||
<> help "specify address to bind to"
|
||||
))
|
||||
<*> optional (strOption
|
||||
( long "socket" <> metavar paramPath
|
||||
<> help "bind to unix domain socket"
|
||||
))
|
||||
<*> optional (strOption
|
||||
( long "certfile" <> metavar paramFile
|
||||
<> help "TLS certificate file for HTTPS"
|
||||
|
@ -174,12 +181,20 @@ runServer o mst = go `finally` serverShutdownCleanup mst
|
|||
let settings = Warp.setPort port $ Warp.setHost host $
|
||||
Warp.defaultSettings
|
||||
mstv <- newTMVarIO mst
|
||||
let app = p2pHttpApp mstv
|
||||
case (certFileOption o, privateKeyFileOption o) of
|
||||
(Nothing, Nothing) -> Warp.runSettings settings (p2pHttpApp mstv)
|
||||
(Just certfile, Just privatekeyfile) -> do
|
||||
(Nothing, Nothing) -> case socketOption o of
|
||||
Nothing -> Warp.runSettings settings app
|
||||
Just socketpath ->
|
||||
withsocket socketpath $ \sock ->
|
||||
Warp.runSettingsSocket settings sock app
|
||||
(Just certfile, Just privatekeyfile) ->
|
||||
case socketOption o of
|
||||
Nothing -> do
|
||||
let tlssettings = Warp.tlsSettingsChain
|
||||
certfile (chainFileOption o) privatekeyfile
|
||||
Warp.runTLS tlssettings settings (p2pHttpApp mstv)
|
||||
Warp.runTLS tlssettings settings app
|
||||
Just _socketpath -> giveup "HTTPS is not supported with --socket"
|
||||
_ -> giveup "You must use both --certfile and --privatekeyfile options to enable HTTPS."
|
||||
port = maybe
|
||||
(fromIntegral defaultP2PHttpProtocolPort)
|
||||
|
@ -189,6 +204,13 @@ runServer o mst = go `finally` serverShutdownCleanup mst
|
|||
(fromString "*") -- both ipv4 and ipv6
|
||||
fromString
|
||||
(bindOption o)
|
||||
withsocket socketpath =
|
||||
bracket (opensocket socketpath) Socket.close
|
||||
opensocket socketpath = protectedOutput $ do
|
||||
sock <- Socket.socket Socket.AF_UNIX Socket.Stream 0
|
||||
Socket.bind sock $ Socket.SockAddrUnix socketpath
|
||||
Socket.listen sock Socket.maxListenQueue
|
||||
return sock
|
||||
|
||||
mkServerState :: Options -> M.Map Auth P2P.ServerMode -> Annex P2PHttpServerState
|
||||
mkServerState o authenv =
|
||||
|
|
|
@ -103,6 +103,12 @@ convenient way to download the content of any key, by using the path
|
|||
|
||||
What address to bind to. The default is to bind to all addresses.
|
||||
|
||||
* `--socket=path`
|
||||
|
||||
Rather than binding to an address, create and listen to a unix domain
|
||||
socket at the specified location. This can be useful when proxying
|
||||
to `git-annex p2phttp`.
|
||||
|
||||
* `--certfile=filename`
|
||||
|
||||
TLS certificate file to use. Combining this with `--privatekeyfile`
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
For p2phttp support in forgejo-aneksajo I decided to just spawn a `git annex p2phttp --wideopen` server, do authentication on the Forgejo side, and then proxy requests to p2phttp. Since p2phttp only supports serving one repository at the moment this means that I have to allocate one free port per repository. Actually finding a free port adds complexity and a race condition, as there also seems to be no way to set `--port 0` for p2phttp and then figure out which port it bound to.
|
||||
|
||||
This would be simplified if p2phttp could listen on unix domain sockets instead.
|
||||
|
||||
> [[done]] --[[Joey]]
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
[[!comment format=mdwn
|
||||
username="joey"
|
||||
subject="""comment 3"""
|
||||
date="2025-07-07T19:26:56Z"
|
||||
content="""
|
||||
I've made it support nested directories, which was easy.
|
||||
|
||||
Should be possible to make it use runSettingsSocket indeed though.
|
||||
"""]]
|
|
@ -0,0 +1,12 @@
|
|||
[[!comment format=mdwn
|
||||
username="joey"
|
||||
subject="""comment 4"""
|
||||
date="2025-07-07T20:28:38Z"
|
||||
content="""
|
||||
Implemented a --socket option. I have not tried connecting to it as a
|
||||
client, but it seems to be listening to it, so I assume all is good.
|
||||
|
||||
Note that it still checks for authentication when using the socket,
|
||||
so you will probably want to combine it with --wideopen. The socket mode
|
||||
allows only the current user to access it.
|
||||
"""]]
|
Loading…
Add table
Add a link
Reference in a new issue