Skip to content

Commit f07a561

Browse files
committed
Some comments cleanup,
added SetWriter, WriteStream to ServerResponse
1 parent 62747af commit f07a561

File tree

7 files changed

+185
-167
lines changed

7 files changed

+185
-167
lines changed

compress.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func CompressFilter(c *Controller, fc []Filter) {
6161
if ok {
6262
writer.parentNotify = w.CloseNotify()
6363
}
64-
c.Response.Out = &writer
64+
c.Response.Out.SetWriter(&writer)
6565
} else {
6666
TRACE.Printf("Compression disabled for response status (%d)", c.Response.Status)
6767
}

controller.go

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,20 @@ type Controller struct {
3939
ViewArgs map[string]interface{} // Variables passed to the template.
4040
Validation *Validation // Data validation helpers
4141
}
42-
type BaseController struct {
43-
SetAppController (interface{})
44-
}
4542

4643
// NewController returns new controller instance for Request and Response
4744
func NewControllerEmpty() *Controller {
4845
return &Controller{}
4946
}
47+
48+
// New controller, creates a new instance wrapping the request and response in it
5049
func NewController(req *Request, resp *Response) *Controller {
51-
return &Controller{
52-
Request: req,
53-
Response: resp,
54-
Params: new(Params),
55-
Args: map[string]interface{}{},
56-
ViewArgs: map[string]interface{}{
57-
"RunMode": RunMode,
58-
"DevMode": DevMode,
59-
},
60-
}
50+
c := NewControllerEmpty()
51+
c.SetController(req, resp)
52+
return c
6153
}
54+
55+
// Sets the request and the response for the controller
6256
func (c *Controller) SetController(req *Request, resp *Response) {
6357

6458
c.Request = req
@@ -362,17 +356,19 @@ func (c *Controller) SetAction(controllerName, methodName string) error {
362356
c.AppController = cachedControllerMap[c.Name].Pop()
363357
c.setAppControllerFields()
364358

365-
// TODO Old method, remove c.AppController = initNewAppController(c.Type, c).Interface()
366-
367359
return nil
368360
}
361+
362+
// Injects this instance (c) into the AppController instance
369363
func (c *Controller) setAppControllerFields() {
370-
appController := reflect.ValueOf(c.AppController).Elem() //.(reflect.Value).Elem()
364+
appController := reflect.ValueOf(c.AppController).Elem()
371365
cValue := reflect.ValueOf(c)
372366
for _, index := range c.Type.ControllerIndexes {
373367
appController.FieldByIndex(index).Set(cValue)
374368
}
375369
}
370+
371+
// Removes this instance (c) from the AppController instance
376372
func (c *Controller) resetAppControllerFields() {
377373
appController := reflect.ValueOf(c.AppController).Elem()
378374
// Zero out controller
@@ -381,22 +377,6 @@ func (c *Controller) resetAppControllerFields() {
381377
}
382378
}
383379

384-
// This is a helper that initializes (zeros) a new app controller value.
385-
// Specifically, it sets all *revel.Controller embedded types to the provided controller.
386-
// Returns a value representing a pointer to the new app controller.
387-
// TODO Unneeded method
388-
//func initNewAppController(appControllerType *ControllerType, c *Controller) reflect.Value {
389-
// var (
390-
// appControllerPtr = reflect.New(appControllerType.Type)
391-
// appController = appControllerPtr.Elem()
392-
// cValue = reflect.ValueOf(c)
393-
// )
394-
// for _, index := range appControllerType.ControllerIndexes {
395-
// appController.FieldByIndex(index).Set(cValue)
396-
// }
397-
// return appControllerPtr
398-
//}
399-
400380
func findControllers(appControllerType reflect.Type) (indexes [][]int) {
401381
// It might be a multi-level embedding. To find the controllers, we follow
402382
// every anonymous field, using breadth-first search.

engine_adapter_go.go

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"io"
1111
"mime/multipart"
1212
"net/url"
13+
"strconv"
1314
)
1415

1516
// Register the GOHttpServer engine
@@ -76,7 +77,7 @@ func (g *GOHttpServer) Handle(w http.ResponseWriter, r *http.Request) {
7677
goRequestStack.Push(request)
7778
}()
7879
request.Set(r)
79-
response.Set(w)
80+
response.Set(w,r)
8081

8182
if upgrade == "websocket" || upgrade == "Websocket" {
8283
websocket.Handler(func(ws *websocket.Conn) {
@@ -129,6 +130,8 @@ type (
129130
GOResponse struct {
130131
Original http.ResponseWriter
131132
Goheader *GOHeader
133+
Writer io.Writer
134+
Request *http.Request
132135
}
133136
GOMultipartForm struct {
134137
Form *multipart.Form
@@ -207,24 +210,66 @@ func (r *GORequest) Destroy() {
207210
r.ParsedForm = nil
208211
}
209212
func (r *GOResponse) GetWriter() io.Writer {
210-
return r.Original
213+
return r.Writer
211214
}
212215
func (r *GOResponse) Header() ServerHeader {
213216
return r.Goheader
214217
}
215218
func (r *GOResponse) GetRaw() interface{} {
216219
return r.Original
217220
}
221+
func (r *GOResponse) SetWriter(writer io.Writer) {
222+
r.Writer = writer
223+
}
224+
func (r *GOResponse) WriteStream(name string, contentlen int64, modtime time.Time,reader io.Reader) error {
225+
226+
if rs, ok := reader.(io.ReadSeeker); ok {
227+
// http.ServeContent doesn't know about response.ContentType, so we set the respective header.
228+
http.ServeContent(r.Original, r.Request, name, modtime, rs)
229+
} else {
230+
// Else, do a simple io.Copy.
231+
ius := r.Request.Header.Get("If-Unmodified-Since")
232+
if t, err := http.ParseTime(ius); err == nil && !modtime.IsZero() {
233+
// The Date-Modified header truncates sub-second precision, so
234+
// use mtime < t+1s instead of mtime <= t to check for unmodified.
235+
if modtime.Before(t.Add(1 * time.Second)) {
236+
h := r.Original.Header()
237+
delete(h, "Content-Type")
238+
delete(h, "Content-Length")
239+
if h.Get("Etag") != "" {
240+
delete(h, "Last-Modified")
241+
}
242+
r.Original.WriteHeader(http.StatusNotModified)
243+
return nil
244+
}
245+
}
246+
247+
if contentlen != -1 {
248+
r.Original.Header().Set("Content-Length", strconv.FormatInt(contentlen, 10))
249+
}
250+
if _, err := io.Copy(r.Writer, reader); err != nil {
251+
r.Original.WriteHeader(http.StatusInternalServerError)
252+
return err
253+
} else {
254+
r.Original.WriteHeader(http.StatusOK)
255+
}
256+
}
257+
return nil
258+
}
218259

219260
func (r *GOResponse) Destroy() {
220-
if c, ok := r.Original.(io.Closer); ok {
261+
if c, ok := r.Writer.(io.Closer); ok {
221262
c.Close()
222263
}
223264
r.Goheader.Source = nil
224265
r.Original = nil
266+
r.Writer = nil
267+
r.Request = nil
225268
}
226-
func (r *GOResponse) Set(w http.ResponseWriter) {
269+
func (r *GOResponse) Set(w http.ResponseWriter, request *http.Request) {
227270
r.Original = w
271+
r.Writer = w
272+
r.Request = request
228273
r.Goheader.Source = r
229274
r.Goheader.isResponse = true
230275

http.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ package revel
77
import (
88
"bytes"
99
"fmt"
10-
// "net/http"
1110
"sort"
1211
"strconv"
1312
"strings"
14-
// "golang.org/x/net/websocket"
1513
)
1614

1715
// Request Revel's HTTP request object structure

invoker.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,10 @@ package revel
77
import (
88
"io"
99
"reflect"
10-
//"golang.org/x/net/websocket"
1110
)
1211

1312
var (
14-
controllerType = reflect.TypeOf(Controller{})
1513
controllerPtrType = reflect.TypeOf(&Controller{})
16-
//websocketType = reflect.TypeOf((*websocket.Conn)(nil))
17-
// websocketType = reflect.TypeOf((ServerWebSocket)(nil))
1814
websocketType = reflect.TypeOf((*ServerWebSocket)(nil)).Elem()
1915
)
2016

results.go

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -358,30 +358,27 @@ func (r *BinaryResult) Apply(req *Request, resp *Response) {
358358
if r.Name != "" {
359359
disposition += fmt.Sprintf(`; filename="%s"`, r.Name)
360360
}
361-
resp.Out.Header().Set("Content-Disposition", disposition)
362-
363-
//// TODO Remove this block
364-
//// If we have a ReadSeeker, delegate to http.ServeContent
365-
//if rs, ok := r.Reader.(io.ReadSeeker); ok {
366-
// // http.ServeContent doesn't know about response.ContentType, so we set the respective header.
367-
// if resp.ContentType != "" {
368-
// resp.Out.Header().Set("Content-Type", resp.ContentType)
369-
// } else {
370-
// contentType := ContentTypeByFilename(r.Name)
371-
// resp.Out.Header().Set("Content-Type", contentType)
372-
// }
373-
// http.ServeContent(resp.Out, req.Request, r.Name, r.ModTime, rs)
374-
//} else {
375-
// Else, do a simple io.Copy.
376-
if r.Length != -1 {
377-
resp.Out.Header().Set("Content-Length", strconv.FormatInt(r.Length, 10))
378-
}
379-
resp.WriteHeader(http.StatusOK, ContentTypeByFilename(r.Name))
380-
381-
if _, err := io.Copy(resp.Out.GetWriter(), r.Reader); err != nil {
382-
ERROR.Println("Response write failed:", err)
383-
}
384-
//}
361+
header := resp.Out.Header()
362+
header.Set("Content-Disposition", disposition)
363+
if resp.ContentType != "" {
364+
header.Set("Content-Type", resp.ContentType)
365+
} else {
366+
contentType := ContentTypeByFilename(r.Name)
367+
header.Set("Content-Type", contentType)
368+
}
369+
if content,ok:=r.Reader.(io.ReadSeeker);ok && r.Length<0 {
370+
// get the size from the stream
371+
if size, err := content.Seek(0, io.SeekEnd); err == nil {
372+
if _, err = content.Seek(0, io.SeekStart); err == nil {
373+
r.Length = size
374+
}
375+
}
376+
}
377+
378+
// Write stream writes the status code to the header as well
379+
if err := resp.Out.WriteStream( r.Name, r.Length, r.ModTime, r.Reader);err!=nil {
380+
ERROR.Println("Response write failed:", err)
381+
}
385382

386383
// Close the Reader if we can
387384
if v, ok := r.Reader.(io.Closer); ok {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy