From 33e8afb7f65598e80f6478061cab7ced90549e25 Mon Sep 17 00:00:00 2001 From: Aum Patel Date: Sun, 4 Jan 2026 19:24:56 +0530 Subject: [PATCH] render: add PDF renderer and tests --- context.go | 6 ++++++ render/pdf.go | 26 ++++++++++++++++++++++++++ render/render.go | 1 + render/render_test.go | 16 ++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 render/pdf.go diff --git a/context.go b/context.go index 92fb3704..5174033e 100644 --- a/context.go +++ b/context.go @@ -1224,6 +1224,12 @@ func (c *Context) XML(code int, obj any) { c.Render(code, render.XML{Data: obj}) } +// PDF writes the given PDF binary data into the response body. +// It also sets the Content-Type as "application/pdf". +func (c *Context) PDF(code int, data []byte) { + c.Render(code, render.PDF{Data: data}) +} + // YAML serializes the given struct as YAML into the response body. func (c *Context) YAML(code int, obj any) { c.Render(code, render.YAML{Data: obj}) diff --git a/render/pdf.go b/render/pdf.go new file mode 100644 index 00000000..b20ab865 --- /dev/null +++ b/render/pdf.go @@ -0,0 +1,26 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package render + +import "net/http" + +// PDF contains the given PDF binary data. +type PDF struct { + Data []byte +} + +var pdfContentType = []string{"application/pdf"} + +// Render (PDF) writes PDF data with custom ContentType. +func (r PDF) Render(w http.ResponseWriter) error { + r.WriteContentType(w) + _, err := w.Write(r.Data) + return err +} + +// WriteContentType (PDF) writes PDF ContentType for response. +func (r PDF) WriteContentType(w http.ResponseWriter) { + writeContentType(w, pdfContentType) +} diff --git a/render/render.go b/render/render.go index 4bdcfa23..28bc0f5d 100644 --- a/render/render.go +++ b/render/render.go @@ -31,6 +31,7 @@ var ( _ Render = (*AsciiJSON)(nil) _ Render = (*ProtoBuf)(nil) _ Render = (*TOML)(nil) + _ Render = (*PDF)(nil) ) func writeContentType(w http.ResponseWriter, value []string) { diff --git a/render/render_test.go b/render/render_test.go index b48ab3d3..f63878b9 100644 --- a/render/render_test.go +++ b/render/render_test.go @@ -466,6 +466,22 @@ func TestRenderXMLError(t *testing.T) { assert.Contains(t, err.Error(), "xml: unsupported type: chan int") } +func TestRenderPDF(t *testing.T) { + w := httptest.NewRecorder() + data := []byte("%Test pdf content") + + pdf := PDF{data} + + pdf.WriteContentType(w) + assert.Equal(t, "application/pdf", w.Header().Get("Content-Type")) + + err := pdf.Render(w) + require.NoError(t, err) + + assert.Equal(t, data, w.Body.Bytes()) + assert.Equal(t, "application/pdf", w.Header().Get("Content-Type")) +} + func TestRenderRedirect(t *testing.T) { req, err := http.NewRequest(http.MethodGet, "/test-redirect", nil) require.NoError(t, err)