implemented responses for PUT and OPTIONS

This commit is contained in:
Altair-sh
2026-11-06 03:09:01 +01:00
parent 7a43e7f8c9
commit 2098082aa6
11 changed files with 206 additions and 33 deletions
+2 -2
View File
@@ -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
}
+12 -5
View File
@@ -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
}
+4
View File
@@ -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"
+1
View File
@@ -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