Skip to content

Commit a6d87d9

Browse files
committed
Modernize web.go to make it more compatible with the current http package:
- Remove request.go, servefile.go, and cookie.go, which were duplicating a lot of functionality from Go's HTTP versions. I created them to fix bugs in Go's http libraries, which have since been fixed - Remove web.Request, and use http.Request instead. Most of the custom functionality I needed has been added to http.Request - Move Params to web.Context - Create a wrapper for http.ResponseWriter that allows connections to be closed - Use http.ServeFile and cgi.RequestFromMap (better performance and reliability) - Lots of small fixes
1 parent 2f96b10 commit a6d87d9

File tree

8 files changed

+201
-914
lines changed

8 files changed

+201
-914
lines changed

Makefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
GOFMT=gofmt -s -tabs=false -tabwidth=4
22

33
GOFILES=\
4-
cookie.go\
54
fcgi.go\
6-
request.go\
75
scgi.go\
8-
servefile.go\
96
status.go\
107
web.go\
118

cookie.go

Lines changed: 0 additions & 219 deletions
This file was deleted.

fcgi.go

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import (
44
"bufio"
55
"bytes"
66
"encoding/binary"
7+
"errors"
78
"fmt"
89
"io"
10+
"io/ioutil"
911
"net"
1012
"net/http"
13+
"net/http/cgi"
1114
"strings"
1215
)
1316

@@ -90,6 +93,7 @@ func (er fcgiEndReq) bytes() []byte {
9093

9194
type fcgiConn struct {
9295
requestId uint16
96+
req *http.Request
9397
fd io.ReadWriteCloser
9498
headers http.Header
9599
wroteHeaders bool
@@ -129,51 +133,43 @@ func (conn *fcgiConn) fcgiWrite(data []byte) (err error) {
129133
}
130134

131135
func (conn *fcgiConn) Write(data []byte) (n int, err error) {
132-
var buf bytes.Buffer
133136
if !conn.wroteHeaders {
134-
conn.wroteHeaders = true
135-
for k, v := range conn.headers {
136-
for _, i := range v {
137-
buf.WriteString(k + ": " + i + "\r\n")
138-
}
139-
}
140-
buf.WriteString("\r\n")
141-
conn.fcgiWrite(buf.Bytes())
137+
conn.WriteHeader(200)
142138
}
143139

140+
if conn.req.Method == "HEAD" {
141+
return 0, errors.New("Body Not Allowed")
142+
}
144143
err = conn.fcgiWrite(data)
145-
146144
if err != nil {
147145
return 0, err
148146
}
149147

150148
return len(data), nil
151149
}
152150

153-
func (conn *fcgiConn) StartResponse(status int) {
154-
var buf bytes.Buffer
155-
text := statusText[status]
156-
fmt.Fprintf(&buf, "HTTP/1.1 %d %s\r\n", status, text)
157-
conn.fcgiWrite(buf.Bytes())
158-
}
151+
func (conn *fcgiConn) WriteHeader(status int) {
152+
if !conn.wroteHeaders {
153+
conn.wroteHeaders = true
159154

160-
func (conn *fcgiConn) SetHeader(hdr string, val string, unique bool) {
161-
if _, contains := conn.headers[hdr]; !contains {
162-
conn.headers[hdr] = []string{val}
163-
return
164-
}
155+
var buf bytes.Buffer
156+
text := statusText[status]
157+
fmt.Fprintf(&buf, "HTTP/1.1 %d %s\r\n", status, text)
165158

166-
if unique {
167-
//just overwrite the first value
168-
conn.headers[hdr][0] = val
169-
} else {
170-
newHeaders := make([]string, len(conn.headers)+1)
171-
copy(newHeaders, conn.headers[hdr])
172-
newHeaders[len(newHeaders)-1] = val
173-
conn.headers[hdr] = newHeaders
159+
for k, v := range conn.headers {
160+
for _, i := range v {
161+
buf.WriteString(k + ": " + i + "\r\n")
162+
}
163+
}
164+
buf.WriteString("\r\n")
165+
conn.fcgiWrite(buf.Bytes())
174166
}
175167
}
176168

169+
func (conn *fcgiConn) Header() http.Header {
170+
return conn.headers
171+
}
172+
177173
func (conn *fcgiConn) complete() {
178174
content := fcgiEndReq{appStatus: 200, protocolStatus: fcgiRequestComplete}.bytes()
179175
l := len(content)
@@ -213,7 +209,7 @@ func readFcgiParamSize(data []byte, index int) (int, int) {
213209
}
214210

215211
//read the fcgi parameters contained in data, and store them in storage
216-
func readFcgiParams(data []byte, storage http.Header) {
212+
func readFcgiParams(data []byte, storage map[string]string) {
217213
for idx := 0; len(data) > idx; {
218214
keySize, shift := readFcgiParamSize(data, idx)
219215
idx += shift
@@ -223,16 +219,16 @@ func readFcgiParams(data []byte, storage http.Header) {
223219
idx += keySize
224220
val := data[idx : idx+valSize]
225221
idx += valSize
226-
storage.Set(string(key), string(val))
222+
storage[string(key)] = string(val)
227223
}
228224
}
229225

230226
func (s *Server) handleFcgiConnection(fd io.ReadWriteCloser) {
231227
br := bufio.NewReader(fd)
232-
var req *Request
228+
var req *http.Request
233229
var fc *fcgiConn
234230
var body bytes.Buffer
235-
headers := make(http.Header)
231+
headers := map[string]string{}
236232

237233
for {
238234
var h fcgiHeader
@@ -247,8 +243,8 @@ func (s *Server) handleFcgiConnection(fd io.ReadWriteCloser) {
247243
content := make([]byte, h.ContentLength)
248244
_, err = io.ReadFull(br, content)
249245
if err != nil {
250-
s.Logger.Println("FCGI Error", err.Error())
251-
break
246+
s.Logger.Println("FCGI Error", err.Error())
247+
break
252248
}
253249

254250
//read padding
@@ -263,7 +259,7 @@ func (s *Server) handleFcgiConnection(fd io.ReadWriteCloser) {
263259

264260
switch h.Type {
265261
case fcgiBeginRequest:
266-
fc = &fcgiConn{h.RequestId, fd, make(map[string][]string), false}
262+
fc = &fcgiConn{h.RequestId, req, fd, make(map[string][]string), false}
267263

268264
case fcgiParams:
269265
if h.ContentLength > 0 {
@@ -273,7 +269,10 @@ func (s *Server) handleFcgiConnection(fd io.ReadWriteCloser) {
273269
if h.ContentLength > 0 {
274270
body.Write(content)
275271
} else if h.ContentLength == 0 {
276-
req = newRequestCgi(headers, &body)
272+
273+
req, _ = cgi.RequestFromMap(headers)
274+
req.Body = ioutil.NopCloser(&body)
275+
fc.req = req
277276
s.routeHandler(req, fc)
278277
//we close the connection after processing
279278
//TODO: is there a way to keep it open for future requests?

0 commit comments

Comments
 (0)