-
Notifications
You must be signed in to change notification settings - Fork 0
/
response.go
90 lines (79 loc) · 2.13 KB
/
response.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright 2013 Liviu G. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package goscgi
import (
"net"
"net/http"
"strconv"
"time"
)
type Response struct {
ResponseCode []byte
ContentType []byte
Content []byte
Cookies []*http.Cookie
Header http.Header
}
var (
status = []byte("Status: ")
contentType = []byte("Content-Type: ")
contentLength = []byte("Content-Length: ")
crlf = []byte{0x0d, 0x0a}
sep = []byte{':'}
RespTypeHtml = []byte("text/html")
RespTypeText = []byte("text/plain")
RespTypeJson = []byte("text/json")
RespCodeOK = []byte("200 OK")
RespCodeNotFound = []byte("404 Not found")
RespCodeBadRequest = []byte("400 Bad request")
RespCodeInternalError = []byte("500 Internal error")
)
func NewResponse(respCode, contentType []byte, content []byte, cookies ...*http.Cookie) *Response {
resp := Response{}
resp.ResponseCode = respCode
resp.ContentType = contentType
resp.Content = content
resp.Header = http.Header{}
for _, cookie := range cookies {
resp.SetCookie(cookie)
}
return &resp
}
func (resp *Response) SetCookie(cookie *http.Cookie) {
if cookie != nil {
resp.Header.Add("Set-Cookie", cookie.String())
}
}
func (resp *Response) Write(conn net.Conn, timeout time.Duration) error {
var err error
// set a timeout for the first write
// just in case the user closed the connection
conn.SetWriteDeadline(time.Now().Add(timeout))
if _, err = conn.Write(status); err != nil {
return err
}
conn.Write(resp.ResponseCode)
conn.Write(crlf)
conn.Write(contentType)
conn.Write(resp.ContentType)
conn.Write(crlf)
contentSize := int64(len(resp.Content))
if contentSize > 0 {
conn.Write(contentLength)
conn.Write([]byte(strconv.FormatInt(contentSize, 10)))
conn.Write(crlf)
}
if err = resp.Header.Write(conn); err != nil {
return err
}
conn.Write(crlf)
if contentSize > 0 {
// set a timeout for sending (large?) content
conn.SetWriteDeadline(time.Now().Add(timeout))
if _, err = conn.Write(resp.Content); err != nil {
return err
}
}
return nil
}