Skip to content

Commit

Permalink
view execute to buffer before write to response (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
acoshift committed Aug 8, 2018
1 parent b6480f7 commit e35f606
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 4 deletions.
9 changes: 8 additions & 1 deletion result.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,17 @@ func (ctx *Context) View(name string, data interface{}) error {
panic(newErrTemplateNotFound(name))
}

buf := bytes.Buffer{}
err := t.Execute(&buf, data)
if err != nil {
return err
}

return ctx.invokeBeforeRender(func() error {
ctx.setContentType("text/html; charset=utf-8")
ctx.w.WriteHeader(ctx.statusCode())
return filterRenderError(t.Execute(ctx.w, data))
_, err = io.Copy(ctx.w, &buf)
return filterRenderError(err)
})
}

Expand Down
77 changes: 77 additions & 0 deletions result_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hime

import (
"fmt"
"io"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -240,4 +241,80 @@ func TestResult(t *testing.T) {

assert.Panics(t, func() { invokeHandler(app, "GET", "/", nil) })
})

t.Run("View", func(t *testing.T) {
t.Parallel()

app := New()

app.Template().Dir("testdata").Root("root").Parse("index", "hello.tmpl")

app.
Handler(Handler(func(ctx *Context) error {
return ctx.View("index", nil)
}))

w := invokeHandler(app, "GET", "/", nil)
assert.Equal(t, http.StatusOK, w.Result().StatusCode)
assert.Equal(t, "text/html; charset=utf-8", w.Header().Get("Content-Type"))
assert.Equal(t, "hello", w.Body.String())
})
}

func panicRecovery(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprint(w, err)
}
}()
h.ServeHTTP(w, r)
})
}

func TestPanicInView(t *testing.T) {
t.Parallel()

t.Run("MinifyDisabled", func(t *testing.T) {
t.Parallel()

app := New()

app.TemplateFunc("panic", func() string { panic("panic") })
app.Template().Dir("testdata").Root("root").Parse("index", "panic.tmpl")

app.
Handler(Handler(func(ctx *Context) error {
return ctx.View("index", nil)
}))

ts := httptest.NewServer(panicRecovery(app))
defer ts.Close()

resp, err := http.Get(ts.URL)
assert.NoError(t, err)
assert.Equal(t, http.StatusInternalServerError, resp.StatusCode)
})

t.Run("MinifyEnabled", func(t *testing.T) {
t.Parallel()

app := New()

app.TemplateFunc("panic", func() string { panic("panic") })
app.Template().Dir("testdata").Root("root").Parse("index", "panic.tmpl").Minify()

app.
Handler(Handler(func(ctx *Context) error {
return ctx.View("index", nil)
}))

ts := httptest.NewServer(panicRecovery(app))
defer ts.Close()

resp, err := http.Get(ts.URL)
assert.NoError(t, err)
assert.Equal(t, http.StatusInternalServerError, resp.StatusCode)
})
}
7 changes: 4 additions & 3 deletions template.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ type tmpl struct {
m *minify.M
}

func (t *tmpl) Execute(wr io.Writer, data interface{}) error {
func (t *tmpl) Execute(w io.Writer, data interface{}) error {
// t.m.Writer is too slow for short data (html)

if t.m == nil {
return t.Template.Execute(wr, data)
return t.Template.Execute(w, data)
}

// TODO: this can optimize using pool
Expand All @@ -67,7 +67,8 @@ func (t *tmpl) Execute(wr io.Writer, data interface{}) error {
if err != nil {
return err
}
return t.m.Minify("text/html", wr, &buf)

return t.m.Minify("text/html", w, &buf)
}

// Template is template loader
Expand Down
1 change: 1 addition & 0 deletions testdata/hello.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{define "root"}}hello{{end}}
3 changes: 3 additions & 0 deletions testdata/panic.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{define "root"}}
{{ panic }}
{{end}}

0 comments on commit e35f606

Please sign in to comment.