implemented responses for PUT and OPTIONS
This commit is contained in:
@@ -92,7 +92,7 @@ func (conn *Connection) Start() {
|
||||
conn.log.Info(req.Method, " ", req.Url, " ", req.Protocol)
|
||||
conn.log.Trace("request headers: ", HeadersToString(req.Headers, SecretHeaders))
|
||||
res = conn.callback(req)
|
||||
if req.HasUnreadBody() {
|
||||
if !res.CloseConnection && req.HasUnreadBody() {
|
||||
res = conn.CreateErrorResponse(req, true, ErrHasUnreadBody)
|
||||
}
|
||||
}
|
||||
@@ -107,7 +107,7 @@ func (conn *Connection) Start() {
|
||||
}
|
||||
|
||||
// it is set by CreateResponse
|
||||
if res.Headers["connection"] == "close" {
|
||||
if res.CloseConnection {
|
||||
conn.lingeringClose()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package http
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"net/url"
|
||||
sh "serveg/internal/string_helper"
|
||||
"strconv"
|
||||
@@ -104,20 +105,26 @@ func (req *Request) HasUnreadBody() bool {
|
||||
return req.bodyReader.N > 0
|
||||
}
|
||||
|
||||
// maxBodyLen: pass -1 to disable limit
|
||||
// returns HttpError
|
||||
func (req *Request) GetBodyReader(maxBodyLen int64) (io.Reader, error) {
|
||||
if maxBodyLen < 0 {
|
||||
maxBodyLen = math.MaxInt64
|
||||
}
|
||||
if req.ContentLength > maxBodyLen {
|
||||
return nil, NewHttpError(StatusRequestEntityTooLarge,
|
||||
fmt.Sprintf("content-length %d > maxBodyLen %d",
|
||||
fmt.Sprintf("content-length (%d) > maxBodyLen (%d)",
|
||||
req.ContentLength, maxBodyLen))
|
||||
}
|
||||
if req.ContentLength == 0 {
|
||||
// body reader with N=0 is a valid reader that just returns EOF
|
||||
return &req.bodyReader, nil
|
||||
}
|
||||
if !req.HasUnreadBody() {
|
||||
return nil, ErrBodyHasBeenAlreadyRead
|
||||
}
|
||||
|
||||
if req.ContentLength != 0 {
|
||||
// body reader with N=0 is a valid reader that just returns EOF
|
||||
req.bodyReader.N = min(req.bodyReader.N, maxBodyLen)
|
||||
}
|
||||
req.bodyReader.N = min(req.bodyReader.N, maxBodyLen)
|
||||
return &req.bodyReader, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ type Response struct {
|
||||
Status StatusCode
|
||||
// keys are in lower case
|
||||
Headers HeadersMap
|
||||
// close connection after sending response
|
||||
CloseConnection bool
|
||||
// don't add body and content-* headers for HEAD request
|
||||
omitBody bool
|
||||
bodySize int64
|
||||
@@ -42,6 +44,7 @@ func (res *Response) reset() {
|
||||
res.needsReset = false
|
||||
res.Status = StatusNotInitialized
|
||||
clear(res.Headers)
|
||||
res.CloseConnection = false
|
||||
res.omitBody = false
|
||||
res.bodySize = 0
|
||||
res.bodyType = responseBodyEmpty
|
||||
@@ -74,6 +77,7 @@ func (conn *Connection) CreateResponse(status StatusCode, req *Request, wantsClo
|
||||
}
|
||||
|
||||
if wantsClose || !req.WantsKeepAlive {
|
||||
res.CloseConnection = true
|
||||
res.Headers["connection"] = "close"
|
||||
} else if req.Protocol == "HTTP/1.0" {
|
||||
res.Headers["connection"] = "keep-alive"
|
||||
|
||||
@@ -18,6 +18,7 @@ func (c StatusCode) String() string {
|
||||
|
||||
// HTTP status codes as registered with IANA.
|
||||
// See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||||
// Details: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
||||
const (
|
||||
StatusNotInitialized StatusCode = 0 // for Response.reset
|
||||
StatusContinue StatusCode = 100 // RFC 9110, 15.2.1
|
||||
|
||||
Reference in New Issue
Block a user