Git clone over HTTP(S) using git binary

This commit is contained in:
fr33domlover 2016-07-27 15:17:03 +00:00
parent c26fb389cf
commit 188905f9aa
2 changed files with 40 additions and 4 deletions

View file

@ -81,8 +81,8 @@
/s/#ShrIdent/r/#RpIdent/_darcs/+Texts DarcsDownloadR GET /s/#ShrIdent/r/#RpIdent/_darcs/+Texts DarcsDownloadR GET
/s/#ShrIdent/r/#RpIdent/git/info/refs GitRefDiscoverR GET /s/#ShrIdent/r/#RpIdent/info/refs GitRefDiscoverR GET
--/s/#ShrIdent/r/#RpIdent/git/git-upload-pack GitUploadRequestR POST /s/#ShrIdent/r/#RpIdent/git-upload-pack GitUploadRequestR POST
/s/#ShrIdent/p ProjectsR GET POST /s/#ShrIdent/p ProjectsR GET POST
/s/#ShrIdent/p/!new ProjectNewR GET /s/#ShrIdent/p/!new ProjectNewR GET

View file

@ -15,12 +15,13 @@
module Vervis.Handler.Git module Vervis.Handler.Git
( getGitRefDiscoverR ( getGitRefDiscoverR
--, postGitUploadRequestR , postGitUploadRequestR
) )
where where
import Prelude import Prelude
import Control.Monad (unless)
import Control.Monad.IO.Class (liftIO) import Control.Monad.IO.Class (liftIO)
import Data.Binary.Put import Data.Binary.Put
import Data.Git.Harder (ObjId (..)) import Data.Git.Harder (ObjId (..))
@ -34,11 +35,15 @@ import Network.Git.Get (parseService)
import Network.Git.Transport.HTTP.Fetch.RefDiscovery import Network.Git.Transport.HTTP.Fetch.RefDiscovery
import Network.Git.Transport.HTTP.Fetch.UploadRequest import Network.Git.Transport.HTTP.Fetch.UploadRequest
import Network.Git.Types import Network.Git.Types
import Network.Wai (strictRequestBody)
import System.IO (hClose)
import System.Process (CreateProcess (..), StdStream (..), createProcess, proc) import System.Process (CreateProcess (..), StdStream (..), createProcess, proc)
import Yesod.Core.Content import Yesod.Core.Content
import Yesod.Core.Handler import Yesod.Core.Handler
import qualified Data.ByteString as B (hGetContents) import qualified Data.ByteString as B (null, hGetContents, hGet)
import qualified Data.ByteString.Lazy as BL (hPut)
import qualified Data.ByteString.Lazy.Internal as BLI (defaultChunkSize)
import Vervis.BinaryBody (decodeRequestBody) import Vervis.BinaryBody (decodeRequestBody)
import Vervis.Content import Vervis.Content
@ -103,6 +108,37 @@ getGitRefDiscoverR shar repo = do
else notFound else notFound
-} -}
postGitUploadRequestR :: ShrIdent -> RpIdent -> Handler TypedContent
postGitUploadRequestR shr rp = do
let typ = "application/x-git-upload-pack-result"
path <- askRepoDir shr rp
let pathG = fromString path
seemsThere <- liftIO $ isRepo pathG
if seemsThere
then do
getBody <- strictRequestBody <$> waiRequest
body <- liftIO getBody
let settings =
( proc "git"
[ "upload-pack"
, "--stateless-rpc"
, path
]
)
{ std_in = CreatePipe
, std_out = CreatePipe
}
(Just hin, Just hout, _, _) <- liftIO $ createProcess settings
liftIO $ BL.hPut hin body >> hClose hin
setHeader "Cache-Control" "no-cache"
let loop = do
b <- liftIO $ B.hGet hout BLI.defaultChunkSize
unless (B.null b) $ do
sendChunkBS b
loop
respondSource typ loop
else notFound
{- This is commented out for now because it doesn't work. The 'collectObjIds' {- This is commented out for now because it doesn't work. The 'collectObjIds'
- function file descriptor exhaustion. I don't know whether and how I can fix - function file descriptor exhaustion. I don't know whether and how I can fix
- that. Maybe dive deep into what happens under the hood in 'hit', or make a - that. Maybe dive deep into what happens under the hood in 'hit', or make a