@@ -348,17 +348,16 @@ func (this *Signer) ServeHTTP(resp http.ResponseWriter, req *http.Request, param
348
348
proxy (resp , fetchResp , nil )
349
349
return
350
350
}
351
+ var act string
351
352
var transformVersion int64
352
353
if this .requireHeaders {
353
354
header_value := GetJoined (req .Header , "AMP-Cache-Transform" )
354
- var act string
355
355
act , transformVersion = amp_cache_transform .ShouldSendSXG (header_value )
356
356
if act == "" {
357
357
log .Println ("Not packaging because AMP-Cache-Transform request header is invalid:" , header_value )
358
358
proxy (resp , fetchResp , nil )
359
359
return
360
360
}
361
- resp .Header ().Set ("AMP-Cache-Transform" , act )
362
361
} else {
363
362
var err error
364
363
transformVersion , err = transformer .SelectVersion (nil )
@@ -387,17 +386,8 @@ func (this *Signer) ServeHTTP(resp http.ResponseWriter, req *http.Request, param
387
386
proxy (resp , fetchResp , nil )
388
387
return
389
388
}
390
- fetchResp .Header .Del (header )
391
389
}
392
390
393
- // Mutate the fetched CSP to make sure it cannot break AMP pages.
394
- fetchResp .Header .Set (
395
- "Content-Security-Policy" ,
396
- MutateFetchedContentSecurityPolicy (
397
- fetchResp .Header .Get ("Content-Security-Policy" )))
398
-
399
- fetchResp .Header .Del ("Link" ) // Ensure there are no privacy-violating Link:rel=preload headers.
400
-
401
391
if fetchResp .Header .Get ("Variants" ) != "" || fetchResp .Header .Get ("Variant-Key" ) != "" ||
402
392
// Include versioned headers per https://github.com/WICG/webpackage/pull/406.
403
393
fetchResp .Header .Get ("Variants-04" ) != "" || fetchResp .Header .Get ("Variant-Key-04" ) != "" {
@@ -408,7 +398,7 @@ func (this *Signer) ServeHTTP(resp http.ResponseWriter, req *http.Request, param
408
398
return
409
399
}
410
400
411
- this .serveSignedExchange (resp , fetchResp , signURL , transformVersion )
401
+ this .serveSignedExchange (resp , fetchResp , signURL , act , transformVersion )
412
402
413
403
case 304 :
414
404
// If fetchURL returns a 304, then also return a 304 with appropriate headers.
@@ -451,9 +441,7 @@ func formatLinkHeader(preloads []*rpb.Metadata_Preload) (string, error) {
451
441
}
452
442
453
443
// serveSignedExchange does the actual work of transforming, packaging and signed and writing to the response.
454
- func (this * Signer ) serveSignedExchange (resp http.ResponseWriter , fetchResp * http.Response , signURL * url.URL , transformVersion int64 ) {
455
- fetchResp .Header .Set ("X-Content-Type-Options" , "nosniff" )
456
-
444
+ func (this * Signer ) serveSignedExchange (resp http.ResponseWriter , fetchResp * http.Response , signURL * url.URL , act string , transformVersion int64 ) {
457
445
// After this, fetchResp.Body is consumed, and attempts to read or proxy it will result in an empty body.
458
446
fetchBody , err := ioutil .ReadAll (io .LimitReader (fetchResp .Body , maxBodyLength ))
459
447
if err != nil {
@@ -470,17 +458,43 @@ func (this *Signer) serveSignedExchange(resp http.ResponseWriter, fetchResp *htt
470
458
proxy (resp , fetchResp , fetchBody )
471
459
return
472
460
}
473
- fetchResp .Header .Set ("Content-Length" , strconv .Itoa (len (transformed )))
461
+
462
+ // Validate and format Link header.
474
463
linkHeader , err := formatLinkHeader (metadata .Preloads )
475
464
if err != nil {
476
465
log .Println ("Not packaging due to Link header error:" , err )
477
466
proxy (resp , fetchResp , fetchBody )
478
467
return
479
468
}
469
+
470
+ // Begin mutations on original fetch response. From this point forward, do
471
+ // not fall-back to proxy().
472
+
473
+ // Remove stateful headers.
474
+ for header := range statefulResponseHeaders {
475
+ fetchResp .Header .Del (header )
476
+ }
477
+
478
+ // Set Link header if formatting returned a valid value, otherwise, delete
479
+ // it to ensure there are no privacy-violating Link:rel=preload headers.
480
480
if linkHeader != "" {
481
481
fetchResp .Header .Set ("Link" , linkHeader )
482
+ } else {
483
+ fetchResp .Header .Del ("Link" )
482
484
}
483
485
486
+ // Set content length.
487
+ fetchResp .Header .Set ("Content-Length" , strconv .Itoa (len (transformed )))
488
+
489
+ // Set general security headers.
490
+ fetchResp .Header .Set ("X-Content-Type-Options" , "nosniff" )
491
+
492
+ // Mutate the fetched CSP to make sure it cannot break AMP pages.
493
+ fetchResp .Header .Set (
494
+ "Content-Security-Policy" ,
495
+ MutateFetchedContentSecurityPolicy (
496
+ fetchResp .Header .Get ("Content-Security-Policy" )))
497
+
484
498
exchange := signedexchange .NewExchange (
485
499
accept .SxgVersion , /*uri=*/ signURL .String (), /*method=*/ "GET" ,
486
500
http.Header {}, fetchResp .StatusCode , fetchResp .Header , []byte (transformed ))
@@ -520,6 +534,13 @@ func (this *Signer) serveSignedExchange(resp http.ResponseWriter, fetchResp *htt
520
534
util .NewHTTPError (http .StatusInternalServerError , "Error serializing exchange: " , err ).LogAndRespond (resp )
521
535
}
522
536
537
+ // If requireHeaders was true when constructing signer, the
538
+ // AMP-Cache-Transform outer response header is required (and has already
539
+ // been validated)
540
+ if (act != "" ) {
541
+ resp .Header ().Set ("AMP-Cache-Transform" , act )
542
+ }
543
+
523
544
// TODO(twifkak): Add Cache-Control: public with expiry to match when we think the AMP Cache
524
545
// should fetch an update (half-way between signature date & expires).
525
546
resp .Header ().Set ("Content-Type" , accept .SxgContentType )
0 commit comments