@@ -18,7 +18,9 @@ export interface ProxyRouteOptions {
1818}
1919
2020export function proxyRoute ( options : ProxyRouteOptions ) : HTTPMiddleware {
21- let middleware : HTTPMiddleware & SitemapExtension = function * proxy ( request ) : Operation < Response > {
21+ let middleware : HTTPMiddleware & SitemapExtension = function * proxy (
22+ request ,
23+ ) : Operation < Response > {
2224 let website = new URL ( options . website ) ;
2325
2426 let target = new URL ( request . url ) ;
@@ -41,10 +43,7 @@ export function proxyRoute(options: ProxyRouteOptions): HTTPMiddleware {
4143 if ( [ 301 , 302 , 307 , 308 ] . includes ( response . status ) ) {
4244 let location = response . headers . get ( "location" ) ;
4345 if ( location ?. startsWith ( String ( website ) ) ) {
44- let headers : Record < string , string > = { } ;
45- for ( let [ key , value ] of response . headers . entries ( ) ) {
46- headers [ key ] = value ;
47- }
46+ let headers = copyHeaders ( response ) ;
4847
4948 let url = new URL ( request . url ) ;
5049
@@ -101,20 +100,18 @@ export function proxyRoute(options: ProxyRouteOptions): HTTPMiddleware {
101100 posixNormalize ( `${ base . pathname } ${ url } ` ) ,
102101 ) ;
103102 } else if ( properties . content . startsWith ( "http" ) ) {
104- properties . content = properties . content . replace ( target . origin , base . href . replace ( / \/ ? $ / , '' ) ) ;
103+ properties . content = properties . content . replace (
104+ target . origin ,
105+ base . href . replace ( / \/ ? $ / , "" ) ,
106+ ) ;
105107 }
106108 }
107109 }
108110 }
109- let headers : Record < string , string > = { } ;
110- for ( let [ key , value ] of response . headers . entries ( ) ) {
111- headers [ key ] = value ;
112- }
113-
114111 response = new Response ( toHtml ( tree ) , {
115112 status : response . status ,
116113 statusText : response . statusText ,
117- headers,
114+ headers : copyHeaders ( response ) ,
118115 } ) ;
119116 }
120117
@@ -123,7 +120,10 @@ export function proxyRoute(options: ProxyRouteOptions): HTTPMiddleware {
123120
124121 if ( options . prefix ) {
125122 middleware . sitemapExtension = function * ( ) : Operation < RoutePath [ ] > {
126- let sitemap = new URL ( `/${ options . root ?? "" } sitemap.xml` , options . website ) ;
123+ let sitemap = new URL (
124+ `/${ options . root ?? "" } sitemap.xml` ,
125+ options . website ,
126+ ) ;
127127 try {
128128 let response = yield * call ( ( ) => fetch ( sitemap ) ) ;
129129 if ( ! response . ok ) return [ ] ;
@@ -148,6 +148,28 @@ export function proxyRoute(options: ProxyRouteOptions): HTTPMiddleware {
148148 return middleware ;
149149}
150150
151+ // Copy an upstream response's headers, dropping the ones that describe how the
152+ // *original* body was framed on the wire. `fetch()` transparently decompresses
153+ // the body, so by the time we rebuild the response the payload is plain text —
154+ // carrying over the upstream `content-encoding` (e.g. gzip) or its stale
155+ // `content-length` makes us serve uncompressed bytes labelled as gzip, which
156+ // downstream clients then fail to decode ("Invalid gzip header"). Let the
157+ // server recompute these for the new body.
158+ function copyHeaders ( response : Response ) : Record < string , string > {
159+ let skip = new Set ( [
160+ "content-encoding" ,
161+ "content-length" ,
162+ "transfer-encoding" ,
163+ ] ) ;
164+ let headers : Record < string , string > = { } ;
165+ for ( let [ key , value ] of response . headers . entries ( ) ) {
166+ if ( ! skip . has ( key . toLowerCase ( ) ) ) {
167+ headers [ key ] = value ;
168+ }
169+ }
170+ return headers ;
171+ }
172+
151173function parseSitemapUrls (
152174 xml : string ,
153175 options : ProxyRouteOptions ,
@@ -159,7 +181,9 @@ function parseSitemapUrls(
159181 let loc = match [ 1 ] ;
160182 try {
161183 let url = new URL ( loc ) ;
162- let path = options . root ? url . pathname . replace ( `/${ options . root } ` , "/" ) : url . pathname ;
184+ let path = options . root
185+ ? url . pathname . replace ( `/${ options . root } ` , "/" )
186+ : url . pathname ;
163187 let pathname = posixNormalize ( `/${ options . prefix } ${ path } ` ) ;
164188 paths . push ( { pathname } ) ;
165189 } catch {
0 commit comments