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