#281: /raw streams attachment blob for all attachment mimes
handleRaw only streamed the blob behind an isImageMime gate (#221), so non-image attachment pastes fell through to empty row.Content and /raw served 0 bytes. Serve the blob for every attachment mime, passing the sniffed mime through serveContentType so active-content types (html, svg, xml) still serve as text/plain per the #34 rule. Regression tests cover text and html attachments (size, Content-Type, byte equality).
This commit is contained in:
@@ -306,3 +306,64 @@ func TestMultipartPasswordFieldAccepted(t *testing.T) {
|
||||
t.Fatalf("paste should require password, got %d", rec2.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// #281: /raw/{id} must stream the attachment blob for ALL attachment mimes,
|
||||
// not just raster images (the old isImageMime gate left non-image
|
||||
// attachments serving an empty body from row.Content).
|
||||
func TestRawStreamsNonImageAttachment(t *testing.T) {
|
||||
s := testServer(t)
|
||||
h := s.routes()
|
||||
|
||||
body := []byte("hello, this is a plain text attachment body")
|
||||
rec, resp := multipartCreate(t, h, "notes.txt", body, nil)
|
||||
if rec.Code != 201 {
|
||||
t.Fatalf("create: %d %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
if resp["attachment"] == nil {
|
||||
t.Fatalf("no attachment in response: %v", resp)
|
||||
}
|
||||
id, _ := resp["id"].(string)
|
||||
|
||||
req := httptest.NewRequest("GET", "/raw/"+id, nil)
|
||||
rec2 := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec2, req)
|
||||
if rec2.Code != 200 {
|
||||
t.Fatalf("raw: %d %s", rec2.Code, rec2.Body.String())
|
||||
}
|
||||
if got := rec2.Header().Get("Content-Type"); got != "text/plain; charset=utf-8" {
|
||||
t.Fatalf("Content-Type = %q", got)
|
||||
}
|
||||
if got := rec2.Header().Get("X-Content-Type-Options"); got != "nosniff" {
|
||||
t.Fatalf("nosniff = %q", got)
|
||||
}
|
||||
if !bytes.Equal(rec2.Body.Bytes(), body) {
|
||||
t.Fatalf("raw bytes differ: got %d bytes want %d", rec2.Body.Len(), len(body))
|
||||
}
|
||||
}
|
||||
|
||||
// #281: active-content attachment types still get forced to text/plain on
|
||||
// /raw, same rule as the /f/ serving path (#34).
|
||||
func TestRawHtmlAttachmentServesAsPlainText(t *testing.T) {
|
||||
s := testServer(t)
|
||||
h := s.routes()
|
||||
|
||||
html := []byte("<html><body><script>alert(1)</script></body></html>")
|
||||
rec, resp := multipartCreate(t, h, "page.html", html, nil)
|
||||
if rec.Code != 201 {
|
||||
t.Fatalf("create: %d %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
id, _ := resp["id"].(string)
|
||||
|
||||
req := httptest.NewRequest("GET", "/raw/"+id, nil)
|
||||
rec2 := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec2, req)
|
||||
if rec2.Code != 200 {
|
||||
t.Fatalf("raw: %d %s", rec2.Code, rec2.Body.String())
|
||||
}
|
||||
if got := rec2.Header().Get("Content-Type"); got != "text/plain; charset=utf-8" {
|
||||
t.Fatalf("Content-Type = %q", got)
|
||||
}
|
||||
if !bytes.Equal(rec2.Body.Bytes(), html) {
|
||||
t.Fatal("raw bytes differ from upload")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user