@@ -47,6 +47,13 @@ const proxyFilter: ProxyOptions['filter'] = async (req, res) => {
4747 return false ;
4848 }
4949
50+ // For POST pack requests, use the raw body extracted by extractRawBody middleware
51+ if ( isPackPost ( req ) && ( req as any ) . bodyRaw ) {
52+ ( req as any ) . body = ( req as any ) . bodyRaw ;
53+ // Clean up the bodyRaw property before forwarding the request
54+ delete ( req as any ) . bodyRaw ;
55+ }
56+
5057 const action = await executeChain ( req , res ) ;
5158
5259 if ( action . error || action . blocked ) {
@@ -130,7 +137,7 @@ const proxyReqBodyDecorator: ProxyOptions['proxyReqBodyDecorator'] = (bodyConten
130137 return bodyContent ;
131138} ;
132139
133- const proxyErrorHandler : ProxyOptions [ 'proxyErrorHandler' ] = ( err , res , next ) => {
140+ const proxyErrorHandler : ProxyOptions [ 'proxyErrorHandler' ] = ( err , _res , next ) => {
134141 console . log ( `ERROR=${ err } ` ) ;
135142 next ( err ) ;
136143} ;
@@ -139,42 +146,24 @@ const isPackPost = (req: Request) =>
139146 req . method === 'POST' &&
140147 / ^ (?: \/ [ ^ / ] + ) * \/ [ ^ / ] + \. 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 ) ;
141148
142- const teeAndValidate = async ( req : Request , res : Response , next : NextFunction ) => {
149+ const extractRawBody = async ( req : Request , res : Response , next : NextFunction ) => {
143150 if ( ! isPackPost ( req ) ) {
144151 return next ( ) ;
145152 }
146153
147- const proxyStream = new PassThrough ( ) ;
148- const pluginStream = new PassThrough ( ) ;
154+ const proxyStream = new PassThrough ( {
155+ highWaterMark : 4 * 1024 * 1024 ,
156+ } ) ;
157+ const pluginStream = new PassThrough ( {
158+ highWaterMark : 4 * 1024 * 1024 ,
159+ } ) ;
149160
150161 req . pipe ( proxyStream ) ;
151162 req . pipe ( pluginStream ) ;
152163
153164 try {
154165 const buf = await getRawBody ( pluginStream , { limit : '1gb' } ) ;
155- ( req as any ) . body = buf ;
156- const verdict = await executeChain ( req , res ) ;
157- if ( verdict . error || verdict . blocked ) {
158- const message = verdict . errorMessage ?? verdict . blockedMessage ?? 'Unknown error' ;
159- const type = verdict . error ? ActionType . ERROR : ActionType . BLOCKED ;
160-
161- logAction ( req . url , req . headers ?. host , req . headers ?. [ 'user-agent' ] , type , message ) ;
162-
163- res
164- . set ( {
165- 'content-type' : 'application/x-git-receive-pack-result' ,
166- expires : 'Fri, 01 Jan 1980 00:00:00 GMT' ,
167- pragma : 'no-cache' ,
168- 'cache-control' : 'no-cache, max-age=0, must-revalidate' ,
169- vary : 'Accept-Encoding' ,
170- 'x-frame-options' : 'DENY' ,
171- connection : 'close' ,
172- } )
173- . status ( 200 ) // return status 200 to ensure that the error message is rendered by the git client
174- . send ( handleMessage ( message ) ) ;
175- return ;
176- }
177-
166+ ( req as any ) . bodyRaw = buf ;
178167 ( req as any ) . pipe = ( dest : any , opts : any ) => proxyStream . pipe ( dest , opts ) ;
179168 next ( ) ;
180169 } catch ( e ) {
@@ -186,7 +175,7 @@ const teeAndValidate = async (req: Request, res: Response, next: NextFunction) =
186175
187176const getRouter = async ( ) => {
188177 const router = Router ( ) ;
189- router . use ( teeAndValidate ) ;
178+ router . use ( extractRawBody ) ;
190179
191180 const originsToProxy = await getAllProxiedHosts ( ) ;
192181 const proxyKeys : string [ ] = [ ] ;
@@ -261,6 +250,6 @@ export {
261250 handleMessage ,
262251 handleRefsErrorMessage ,
263252 isPackPost ,
264- teeAndValidate ,
253+ extractRawBody ,
265254 validGitRequest ,
266255} ;
0 commit comments