diff --git a/context.go b/context.go
index 139c1864..76afb229 100644
--- a/context.go
+++ b/context.go
@@ -3,12 +3,15 @@ package echo
import (
"encoding/json"
"encoding/xml"
+ "io"
"net/http"
"fmt"
"net/url"
+ "os"
+
"golang.org/x/net/websocket"
)
@@ -163,6 +166,21 @@ func (c *Context) XML(code int, i interface{}) error {
return xml.NewEncoder(c.response).Encode(i)
}
+// File sends a file as attachment.
+func (c *Context) File(name string) error {
+ file, err := os.Open(name)
+ if err != nil {
+ return err
+ }
+ fi, err := file.Stat()
+ if err != nil {
+ return err
+ }
+ c.response.Header().Set(ContentDisposition, "attachment; filename="+fi.Name())
+ _, err = io.Copy(c.response, file)
+ return err
+}
+
// NoContent sends a response with no body and a status code.
func (c *Context) NoContent(code int) error {
c.response.WriteHeader(code)
diff --git a/context_test.go b/context_test.go
index 4a3bde0c..21472d3e 100644
--- a/context_test.go
+++ b/context_test.go
@@ -88,7 +88,6 @@ func TestContext(t *testing.T) {
assert.Error(t, err)
// JSON
- req.Header.Set(Accept, ApplicationJSON)
rec = httptest.NewRecorder()
c = NewContext(req, NewResponse(rec), New())
err = c.JSON(http.StatusOK, user{"1", "Joe"})
@@ -99,7 +98,6 @@ func TestContext(t *testing.T) {
}
// JSONP
- req.Header.Set(Accept, ApplicationJavaScript)
rec = httptest.NewRecorder()
c = NewContext(req, NewResponse(rec), New())
callback := "callback"
@@ -111,7 +109,6 @@ func TestContext(t *testing.T) {
}
// XML
- req.Header.Set(Accept, ApplicationXML)
rec = httptest.NewRecorder()
c = NewContext(req, NewResponse(rec), New())
err = c.XML(http.StatusOK, user{"1", "Joe"})
@@ -122,7 +119,6 @@ func TestContext(t *testing.T) {
}
// String
- req.Header.Set(Accept, TextPlain)
rec = httptest.NewRecorder()
c = NewContext(req, NewResponse(rec), New())
err = c.String(http.StatusOK, "Hello, World!")
@@ -133,7 +129,6 @@ func TestContext(t *testing.T) {
}
// HTML
- req.Header.Set(Accept, TextHTML)
rec = httptest.NewRecorder()
c = NewContext(req, NewResponse(rec), New())
err = c.HTML(http.StatusOK, "Hello, World!")
@@ -143,6 +138,15 @@ func TestContext(t *testing.T) {
assert.Equal(t, "Hello, World!", rec.Body.String())
}
+ // File
+ rec = httptest.NewRecorder()
+ c = NewContext(req, NewResponse(rec), New())
+ err = c.File("test/fixture/walle.png")
+ if assert.NoError(t, err) {
+ assert.Equal(t, http.StatusOK, rec.Code)
+ assert.Equal(t, 219885, rec.Body.Len())
+ }
+
// NoContent
rec = httptest.NewRecorder()
c = NewContext(req, NewResponse(rec), New())
diff --git a/echo.go b/echo.go
index 5b1e5967..2d66ec5b 100644
--- a/echo.go
+++ b/echo.go
@@ -64,6 +64,11 @@ type (
binder struct {
}
+ // Validator is the interface that wraps the Validate method.
+ Validator interface {
+ Validate() error
+ }
+
// Renderer is the interface that wraps the Render method.
Renderer interface {
Render(w io.Writer, name string, data interface{}) error
@@ -119,7 +124,6 @@ const (
// Headers
//---------
- Accept = "Accept"
AcceptEncoding = "Accept-Encoding"
Authorization = "Authorization"
ContentDisposition = "Content-Disposition"
@@ -587,7 +591,7 @@ func wrapHandler(h Handler) HandlerFunc {
}
}
-func (*binder) Bind(r *http.Request, i interface{}) (err error) {
+func (binder) Bind(r *http.Request, i interface{}) (err error) {
ct := r.Header.Get(ContentType)
err = UnsupportedMediaType
if strings.HasPrefix(ct, ApplicationJSON) {
diff --git a/test/fixture/walle.png b/test/fixture/walle.png
new file mode 100644
index 00000000..493985d4
Binary files /dev/null and b/test/fixture/walle.png differ