@@ -45,6 +45,13 @@ const proxyFilter: ProxyOptions['filter'] = async (req, res) => {
4545 return false ;
4646 }
4747
48+ // For POST pack requests, use the raw body extracted by extractRawBody middleware
49+ if ( isPackPost ( req ) && ( req as any ) . bodyRaw ) {
50+ ( req as any ) . body = ( req as any ) . bodyRaw ;
51+ // Clean up the bodyRaw property before forwarding the request
52+ delete ( req as any ) . bodyRaw ;
53+ }
54+
4855 const action = await executeChain ( req , res ) ;
4956
5057 if ( action . error || action . blocked ) {
@@ -128,7 +135,7 @@ const proxyReqBodyDecorator: ProxyOptions['proxyReqBodyDecorator'] = (bodyConten
128135 return bodyContent ;
129136} ;
130137
131- const proxyErrorHandler : ProxyOptions [ 'proxyErrorHandler' ] = ( err , res , next ) => {
138+ const proxyErrorHandler : ProxyOptions [ 'proxyErrorHandler' ] = ( err , _res , next ) => {
132139 console . log ( `ERROR=${ err } ` ) ;
133140 next ( err ) ;
134141} ;
@@ -137,42 +144,24 @@ const isPackPost = (req: Request) =>
137144 req . method === 'POST' &&
138145 / ^ (?: \/ [ ^ / ] + ) * \/ [ ^ / ] + \. g i t \/ (?: g i t - u p l o a d - p a c k | g i t - r e c e i v e - p a c k ) $ / . test ( req . url ) ;
139146
140- const teeAndValidate = async ( req : Request , res : Response , next : NextFunction ) => {
147+ const extractRawBody = async ( req : Request , res : Response , next : NextFunction ) => {
141148 if ( ! isPackPost ( req ) ) {
142149 return next ( ) ;
143150 }
144151
145- const proxyStream = new PassThrough ( ) ;
146- const pluginStream = new PassThrough ( ) ;
152+ const proxyStream = new PassThrough ( {
153+ highWaterMark : 4 * 1024 * 1024 ,
154+ } ) ;
155+ const pluginStream = new PassThrough ( {
156+ highWaterMark : 4 * 1024 * 1024 ,
157+ } ) ;
147158
148159 req . pipe ( proxyStream ) ;
149160 req . pipe ( pluginStream ) ;
150161
151162 try {
152163 const buf = await getRawBody ( pluginStream , { limit : '1gb' } ) ;
153- ( req as any ) . body = buf ;
154- const verdict = await executeChain ( req , res ) ;
155- if ( verdict . error || verdict . blocked ) {
156- const message = verdict . errorMessage ?? verdict . blockedMessage ?? 'Unknown error' ;
157- const type = verdict . error ? ActionType . ERROR : ActionType . BLOCKED ;
158-
159- logAction ( req . url , req . headers ?. host , req . headers ?. [ 'user-agent' ] , type , message ) ;
160-
161- res
162- . set ( {
163- 'content-type' : 'application/x-git-receive-pack-result' ,
164- expires : 'Fri, 01 Jan 1980 00:00:00 GMT' ,
165- pragma : 'no-cache' ,
166- 'cache-control' : 'no-cache, max-age=0, must-revalidate' ,
167- vary : 'Accept-Encoding' ,
168- 'x-frame-options' : 'DENY' ,
169- connection : 'close' ,
170- } )
171- . status ( 200 ) // return status 200 to ensure that the error message is rendered by the git client
172- . send ( handleMessage ( message ) ) ;
173- return ;
174- }
175-
164+ ( req as any ) . bodyRaw = buf ;
176165 ( req as any ) . pipe = ( dest : any , opts : any ) => proxyStream . pipe ( dest , opts ) ;
177166 next ( ) ;
178167 } catch ( e ) {
@@ -184,7 +173,7 @@ const teeAndValidate = async (req: Request, res: Response, next: NextFunction) =
184173
185174const getRouter = async ( ) => {
186175 const router = Router ( ) ;
187- router . use ( teeAndValidate ) ;
176+ router . use ( extractRawBody ) ;
188177
189178 const originsToProxy = await getAllProxiedHosts ( ) ;
190179 const proxyKeys : string [ ] = [ ] ;
@@ -259,6 +248,6 @@ export {
259248 handleMessage ,
260249 handleRefsErrorMessage ,
261250 isPackPost ,
262- teeAndValidate ,
251+ extractRawBody ,
263252 validGitRequest ,
264253} ;
0 commit comments