Skip to content

Commit ebddcd5

Browse files
authored
Add arbitrary preload attributes to Link header (#475)
1 parent 62ad49f commit ebddcd5

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

packager/signer/signer.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,12 +447,26 @@ func formatLinkHeader(preloads []*rpb.Metadata_Preload) (string, error) {
447447
return "", errors.Errorf("Missing `as` attribute for preload URL: %q\n", preload.Url)
448448
}
449449

450+
valid := true
450451
var value strings.Builder
451452
value.WriteByte('<')
452453
value.WriteString(u.String())
453454
value.WriteString(">;rel=preload;as=")
454455
value.WriteString(preload.As)
455-
values = append(values, value.String())
456+
for _, attr := range preload.GetAttributes() {
457+
value.WriteByte(';')
458+
value.WriteString(attr.Key)
459+
value.WriteByte('=')
460+
quotedVal, err := util.QuotedString(attr.Val)
461+
if err != nil {
462+
valid = false
463+
break
464+
}
465+
value.WriteString(quotedVal)
466+
}
467+
if valid {
468+
values = append(values, value.String())
469+
}
456470
}
457471
return strings.Join(values, ","), nil
458472
}

packager/signer/signer_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,15 +479,15 @@ func (this *SignerSuite) TestAddsLinkHeaders() {
479479
Sign: &util.URLPattern{[]string{"https"}, "", this.httpsHost(), stringPtr("/amp/.*"), []string{}, stringPtr(""), false, 2000, nil}}}
480480
this.fakeHandler = func(resp http.ResponseWriter, req *http.Request) {
481481
resp.Header().Set("Content-Type", "text/html; charset=utf-8")
482-
resp.Write([]byte("<html amp><head><link rel=stylesheet href=foo><script src=bar>"))
482+
resp.Write([]byte(`<html amp><head><link rel=stylesheet href=foo><script src=bar></script><link rel=preload as=image href=baz imagesizes="100vw" imagesrcset="qux">`))
483483
}
484484
target := "/priv/doc?sign=" + url.QueryEscape(this.httpsURL()+fakePath)
485485
resp := pkgt.NewRequest(this.T(), this.new(urlSets), target).SetHeaders("", header).Do()
486486
this.Assert().Equal(http.StatusOK, resp.StatusCode, "incorrect status: %#v", resp)
487487

488488
exchange, err := signedexchange.ReadExchange(resp.Body)
489489
this.Require().NoError(err)
490-
this.Assert().Equal("<foo>;rel=preload;as=style,<bar>;rel=preload;as=script", exchange.ResponseHeaders.Get("Link"))
490+
this.Assert().Equal("<foo>;rel=preload;as=style,<bar>;rel=preload;as=script,<baz>;rel=preload;as=image;imagesizes=\"100vw\";imagesrcset=\"qux\"", exchange.ResponseHeaders.Get("Link"))
491491
}
492492

493493
func (this *SignerSuite) TestEscapesLinkHeaders() {
@@ -500,15 +500,15 @@ func (this *SignerSuite) TestEscapesLinkHeaders() {
500500
// However, it would be nice to limit the impact that could be
501501
// caused by transformation of an invalid AMP, e.g. on a
502502
// same-origin impression.
503-
resp.Write([]byte(`<html amp><head><script src="https://foo.com/a,b>c?d>e|f">`))
503+
resp.Write([]byte(`<html amp><head><script src="https://foo.com/a,b>c?d>e|f"></script><link rel=preload as=image href=bar imagesrcset='test"ing'>`))
504504
}
505505
target := "/priv/doc?sign=" + url.QueryEscape(this.httpsURL()+fakePath)
506506
resp := pkgt.NewRequest(this.T(), this.new(urlSets), target).SetHeaders("", header).Do()
507507
this.Assert().Equal(http.StatusOK, resp.StatusCode, "incorrect status: %#v", resp)
508508

509509
exchange, err := signedexchange.ReadExchange(resp.Body)
510510
this.Require().NoError(err)
511-
this.Assert().Equal("<https://foo.com/a,b%3Ec?d%3Ee%7Cf>;rel=preload;as=script", exchange.ResponseHeaders.Get("Link"))
511+
this.Assert().Equal("<https://foo.com/a,b%3Ec?d%3Ee%7Cf>;rel=preload;as=script,<bar>;rel=preload;as=image;imagesrcset=\"test\\\"ing\"", exchange.ResponseHeaders.Get("Link"))
512512
}
513513

514514
func (this *SignerSuite) TestRemovesHopByHopHeaders() {

0 commit comments

Comments
 (0)