Skip to content

Commit 848e472

Browse files
author
Michael Hoisie
committed
Instead of having web.Conn be a menber of web.Context, it's now embedded. This lets you do ctx.Write(), ctx.StartResponse, etc, without having to use ctx.Conn. This makes things simpler and fits the go paradigm better. Now you can use ctx as a io.Writer and write to it directly.
1 parent e35baf0 commit 848e472

File tree

5 files changed

+49
-40
lines changed

5 files changed

+49
-40
lines changed

fcgi.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,6 @@ func (conn *fcgiConn) Write(data []byte) (n int, err os.Error) {
150150
return len(data), nil
151151
}
152152

153-
func (conn *fcgiConn) WriteString(data string) {
154-
var buf bytes.Buffer
155-
buf.WriteString(data)
156-
conn.Write(buf.Bytes())
157-
}
158-
159153
func (conn *fcgiConn) StartResponse(status int) {
160154
var buf bytes.Buffer
161155
text := statusText[status]

scgi.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@ func (conn *scgiConn) Write(data []byte) (n int, err os.Error) {
5757
return conn.fd.Write(data)
5858
}
5959

60-
func (conn *scgiConn) WriteString(data string) {
61-
var buf bytes.Buffer
62-
buf.WriteString(data)
63-
conn.Write(buf.Bytes())
64-
}
65-
6660
func (conn *scgiConn) Close() { conn.fd.Close() }
6761

6862
func readScgiRequest(buf *bytes.Buffer) *Request {

servefile.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,18 @@ func serveFile(ctx *Context, name string) {
5454
ext := path.Ext(name)
5555

5656
if ctype, ok := contentByExt[ext]; ok {
57-
ctx.Conn.SetHeader("Content-Type", ctype, true)
57+
ctx.SetHeader("Content-Type", ctype, true)
5858
} else {
5959
// read first chunk to decide between utf-8 text and binary
6060
var buf [1024]byte
6161
n, _ := io.ReadFull(f, &buf)
6262
b := buf[0:n]
6363
if isText(b) {
64-
ctx.Conn.SetHeader("Content-Type", "text-plain; charset=utf-8", true)
64+
ctx.SetHeader("Content-Type", "text-plain; charset=utf-8", true)
6565
} else {
66-
ctx.Conn.SetHeader("Content-Type", "application/octet-stream", true) // generic binary
66+
ctx.SetHeader("Content-Type", "application/octet-stream", true) // generic binary
6767
}
68-
ctx.Conn.Write(b)
68+
ctx.Write(b)
6969
}
70-
io.Copy(ctx.Conn, f)
70+
io.Copy(ctx, f)
7171
}

web.go

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,52 @@ import (
1111
"rand"
1212
"reflect"
1313
"regexp"
14+
"strings"
1415
"time"
1516
)
1617

17-
var rgen = rand.New( rand.NewSource( time.Nanoseconds() ) )
18+
var rgen = rand.New(rand.NewSource(time.Nanoseconds()))
1819

19-
type Conn interface {
20+
type conn interface {
2021
StartResponse(status int)
2122
SetHeader(hdr string, val string, unique bool)
2223
Write(data []byte) (n int, err os.Error)
23-
WriteString(content string)
2424
Close()
2525
}
2626

2727
type Context struct {
2828
*Request
29-
Session *session
30-
Conn
29+
*conn
30+
Session *session
3131
responseStarted bool
3232
}
3333

34-
func (ctx *Context) Abort(status int, body string) {
35-
ctx.Conn.StartResponse(status)
36-
ctx.Conn.WriteString(body)
34+
func (ctx *Context) StartResponse(status int) {
35+
ctx.conn.StartResponse(status)
3736
ctx.responseStarted = true
3837
}
3938

39+
func (ctx *Context) Write(data []byte) (n int, err os.Error) {
40+
if !ctx.responseStarted {
41+
ctx.StartResponse(200)
42+
}
43+
return ctx.conn.Write(data)
44+
}
45+
func (ctx *Context) WriteString(content string) {
46+
ctx.Write(strings.Bytes(content))
47+
}
48+
49+
func (ctx *Context) Abort(status int, body string) {
50+
ctx.StartResponse(status)
51+
ctx.WriteString(body)
52+
}
53+
4054
func (ctx *Context) Redirect(status int, url string) {
4155
//note := "<a href=\"%v\">" + statusText[code] + "</a>.\n"
4256

43-
ctx.Conn.SetHeader("Location", url, true)
44-
ctx.Conn.StartResponse(status)
45-
ctx.Conn.WriteString("")
46-
ctx.responseStarted = true
57+
ctx.SetHeader("Location", url, true)
58+
ctx.StartResponse(status)
59+
ctx.WriteString("")
4760
}
4861
//Sets a cookie -- duration is the amount of time in seconds. 0 = forever
4962
func (ctx *Context) SetCookie(name string, value string, duration int64) {
@@ -56,7 +69,7 @@ func (ctx *Context) SetCookie(name string, value string, duration int64) {
5669
expires := utc1.RFC1123()
5770
expires = expires[0:len(expires)-3] + "GMT"
5871
cookie := fmt.Sprintf("%s=%s; expires=%s", name, value, expires)
59-
ctx.Conn.SetHeader("Set-Cookie", cookie, false)
72+
ctx.SetHeader("Set-Cookie", cookie, false)
6073
}
6174

6275
var sessionMap = make(map[string]*session)
@@ -158,7 +171,7 @@ func httpHandler(c *http.Conn, req *http.Request) {
158171
routeHandler(wreq, &conn)
159172
}
160173

161-
func routeHandler(req *Request, conn Conn) {
174+
func routeHandler(req *Request, c conn) {
162175
requestPath := req.URL.Path
163176

164177
//log the request
@@ -190,7 +203,7 @@ func routeHandler(req *Request, conn Conn) {
190203
}
191204
}
192205

193-
ctx := Context{req, s, conn, false}
206+
ctx := Context{req, &c, s, false}
194207

195208
//try to serve a static file
196209
staticFile := path.Join(staticDir, requestPath)
@@ -200,8 +213,8 @@ func routeHandler(req *Request, conn Conn) {
200213
}
201214

202215
//set default encoding
203-
conn.SetHeader("Content-Type", "text/html; charset=utf-8", true)
204-
conn.SetHeader("Server", "web.go", true)
216+
ctx.SetHeader("Content-Type", "text/html; charset=utf-8", true)
217+
ctx.SetHeader("Server", "web.go", true)
205218

206219
for cr, route := range routes {
207220
if req.Method != route.method {
@@ -245,19 +258,25 @@ func routeHandler(req *Request, conn Conn) {
245258
for i, j := range (args) {
246259
valArgs[i] = j.(reflect.Value)
247260
}
248-
ret := route.handler.Call(valArgs)[0].(*reflect.StringValue).Get()
249261

250-
if !ctx.responseStarted {
262+
ret := route.handler.Call(valArgs)
263+
264+
if len(ret) == 0 {
265+
return
266+
}
267+
268+
sval, ok := ret[0].(*reflect.StringValue)
269+
270+
if ok && !ctx.responseStarted {
251271
//check if session data is stored
252272
if len(s.Data) > 0 {
253273
s.save()
254274
//set the session for half an hour
255275
ctx.SetCookie(sessionKey, s.Id, 1800)
256276
}
257277

258-
conn.StartResponse(200)
259-
ctx.responseStarted = true
260-
conn.WriteString(ret)
278+
ctx.StartResponse(200)
279+
ctx.WriteString(sval.Get())
261280
}
262281

263282
return

web_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ func init() {
123123
ctx.Abort(n, message)
124124
return ""
125125
})
126+
127+
Get("/writetest", func(ctx *Context) { ctx.WriteString("hello") })
126128
}
127129

128130
var tests = []Test{
@@ -134,7 +136,7 @@ var tests = []Test{
134136
//long url
135137
Test{"GET", "/echo/" + strings.Repeat("0123456789", 100), "", 200, strings.Repeat("0123456789", 100)},
136138

137-
Test{"GET", "/", "", 200, "index"},
139+
Test{"GET", "/writetest", "", 200, "hello"},
138140
Test{"GET", "/doesnotexist", "", 404, "Page not found"},
139141
Test{"POST", "/doesnotexist", "", 404, "Page not found"},
140142
Test{"GET", "/error/code/500", "", 500, statusText[500]},

0 commit comments

Comments
 (0)