[server] Update headers handling, finetune runtime parameters, remove almost all allocations
This commit is contained in:
parent
33c23ecadd
commit
1f319785bf
2 changed files with 64 additions and 40 deletions
|
@ -131,9 +131,9 @@ func archiveData (_context *context, _namespace string, _pathInArchive string, _
|
||||||
}
|
}
|
||||||
|
|
||||||
_metadata := make (map[string]string, 16)
|
_metadata := make (map[string]string, 16)
|
||||||
_metadata["content-type"] = _dataType
|
_metadata["Content-Type"] = _dataType
|
||||||
_metadata["content-encoding"] = _dataEncoding
|
_metadata["Content-Encoding"] = _dataEncoding
|
||||||
_metadata["etag"] = _fingerprint
|
_metadata["ETag"] = _fingerprint
|
||||||
|
|
||||||
var _metadataRaw []byte
|
var _metadataRaw []byte
|
||||||
if _metadataRaw_0, _error := MetadataEncode (_metadata); _error == nil {
|
if _metadataRaw_0, _error := MetadataEncode (_metadata); _error == nil {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import "net/http"
|
||||||
import "os"
|
import "os"
|
||||||
import "os/signal"
|
import "os/signal"
|
||||||
import "runtime"
|
import "runtime"
|
||||||
|
import "runtime/debug"
|
||||||
import "runtime/pprof"
|
import "runtime/pprof"
|
||||||
import "sync"
|
import "sync"
|
||||||
import "syscall"
|
import "syscall"
|
||||||
|
@ -40,31 +41,36 @@ type server struct {
|
||||||
|
|
||||||
|
|
||||||
func (_server *server) HandleHTTP (_context *fasthttp.RequestCtx) () {
|
func (_server *server) HandleHTTP (_context *fasthttp.RequestCtx) () {
|
||||||
_uri := _context.URI ()
|
|
||||||
// _request := &_context.Request
|
// _request := &_context.Request
|
||||||
_requestHeaders := &_context.Request.Header
|
_requestHeaders := &_context.Request.Header
|
||||||
_response := &_context.Response
|
_response := &_context.Response
|
||||||
_responseHeaders := &_context.Response.Header
|
_responseHeaders := &_context.Response.Header
|
||||||
|
|
||||||
_keyBuffer := [1024]byte {}
|
_keyBuffer := [1024]byte {}
|
||||||
_pathNewBuffer := [1024]byte {}
|
_pathBuffer := [1024]byte {}
|
||||||
_timestampBuffer := [128]byte {}
|
_timestampBuffer := [128]byte {}
|
||||||
|
|
||||||
_timestamp := time.Now ()
|
_timestamp := time.Now ()
|
||||||
_timestampHttp := _timestamp.AppendFormat (_timestampBuffer[:0], http.TimeFormat)
|
_timestampHttp := _timestamp.AppendFormat (_timestampBuffer[:0], http.TimeFormat)
|
||||||
|
|
||||||
// _responseHeaders.Set ("Content-Security-Policy", "upgrade-insecure-requests")
|
// _responseHeaders.SetCanonical ([]byte ("Content-Security-Policy"), []byte ("upgrade-insecure-requests"))
|
||||||
_responseHeaders.Set ("Referrer-Policy", "strict-origin-when-cross-origin")
|
_responseHeaders.SetCanonical ([]byte ("Referrer-Policy"), []byte ("strict-origin-when-cross-origin"))
|
||||||
_responseHeaders.Set ("X-Frame-Options", "SAMEORIGIN")
|
_responseHeaders.SetCanonical ([]byte ("X-Frame-Options"), []byte ("SAMEORIGIN"))
|
||||||
_responseHeaders.Set ("X-content-type-Options", "nosniff")
|
_responseHeaders.SetCanonical ([]byte ("X-content-type-Options"), []byte ("nosniff"))
|
||||||
_responseHeaders.Set ("X-XSS-Protection", "1; mode=block")
|
_responseHeaders.SetCanonical ([]byte ("X-XSS-Protection"), []byte ("1; mode=block"))
|
||||||
|
|
||||||
_responseHeaders.SetBytesV ("date", _timestampHttp)
|
_responseHeaders.SetCanonical ([]byte ("Date"), _timestampHttp)
|
||||||
_responseHeaders.SetBytesV ("last-modified", _timestampHttp)
|
_responseHeaders.SetCanonical ([]byte ("Last-Modified"), _timestampHttp)
|
||||||
_responseHeaders.Set ("age", "0")
|
_responseHeaders.SetCanonical ([]byte ("Age"), []byte ("0"))
|
||||||
|
|
||||||
_method := _requestHeaders.Method ()
|
_method := _requestHeaders.Method ()
|
||||||
_path := _uri.Path ()
|
|
||||||
|
_path := append (_pathBuffer[:0], _requestHeaders.RequestURI () ...)
|
||||||
|
if _pathLimit := bytes.IndexByte (_path, '?'); _pathLimit > 0 {
|
||||||
|
_path = _path[: _pathLimit]
|
||||||
|
}
|
||||||
|
// FIXME: Decode path according to `decodeArgAppendNoPlus`!
|
||||||
|
|
||||||
_pathLen := len (_path)
|
_pathLen := len (_path)
|
||||||
_pathIsRoot := _pathLen == 1
|
_pathIsRoot := _pathLen == 1
|
||||||
_pathHasSlash := !_pathIsRoot && (_path[_pathLen - 1] == '/')
|
_pathHasSlash := !_pathIsRoot && (_path[_pathLen - 1] == '/')
|
||||||
|
@ -96,10 +102,8 @@ func (_server *server) HandleHTTP (_context *fasthttp.RequestCtx) () {
|
||||||
_fingerprint = _value
|
_fingerprint = _value
|
||||||
if (_namespace == NamespaceFoldersContent) || (_namespace == NamespaceFoldersEntries) {
|
if (_namespace == NamespaceFoldersContent) || (_namespace == NamespaceFoldersEntries) {
|
||||||
if !_pathHasSlash {
|
if !_pathHasSlash {
|
||||||
_pathNew := _pathNewBuffer[:0]
|
_path = append (_path, '/')
|
||||||
_pathNew = append (_pathNew, _path_0 ...)
|
_server.ServeRedirect (_context, http.StatusTemporaryRedirect, _path)
|
||||||
_pathNew = append (_pathNew, '/')
|
|
||||||
_server.ServeRedirect (_context, http.StatusTemporaryRedirect, _pathNew)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,10 +147,10 @@ func (_server *server) HandleHTTP (_context *fasthttp.RequestCtx) () {
|
||||||
_server.ServeError (_context, http.StatusNotFound, nil)
|
_server.ServeError (_context, http.StatusNotFound, nil)
|
||||||
} else {
|
} else {
|
||||||
_data, _dataContentType := FaviconData ()
|
_data, _dataContentType := FaviconData ()
|
||||||
_responseHeaders.Set ("content-type", _dataContentType)
|
_responseHeaders.SetCanonical ([]byte ("Content-Type"), []byte (_dataContentType))
|
||||||
_responseHeaders.Set ("content-encoding", "identity")
|
_responseHeaders.SetCanonical ([]byte ("Content-Encoding"), []byte ("identity"))
|
||||||
_responseHeaders.Set ("etag", "f00f5f99bb3d45ef9806547fe5fe031a")
|
_responseHeaders.SetCanonical ([]byte ("ETag"), []byte ("f00f5f99bb3d45ef9806547fe5fe031a"))
|
||||||
_responseHeaders.Set ("cache-control", "public, immutable, max-age=3600")
|
_responseHeaders.SetCanonical ([]byte ("Cache-Control"), []byte ("public, immutable, max-age=3600"))
|
||||||
_response.SetStatusCode (http.StatusOK)
|
_response.SetStatusCode (http.StatusOK)
|
||||||
_response.SetBody (_data)
|
_response.SetBody (_data)
|
||||||
}
|
}
|
||||||
|
@ -180,7 +184,7 @@ func (_server *server) HandleHTTP (_context *fasthttp.RequestCtx) () {
|
||||||
_key = append (_key, _fingerprint ...)
|
_key = append (_key, _fingerprint ...)
|
||||||
if _value, _error := _server.cdbReader.GetWithCdbHash (_key); _error == nil {
|
if _value, _error := _server.cdbReader.GetWithCdbHash (_key); _error == nil {
|
||||||
if _value != nil {
|
if _value != nil {
|
||||||
if _error := MetadataDecodeIterate (_value, _responseHeaders.SetBytesKV); _error == nil {
|
if _error := MetadataDecodeIterate (_value, _responseHeaders.SetCanonical); _error == nil {
|
||||||
} else {
|
} else {
|
||||||
_server.ServeError (_context, http.StatusInternalServerError, _error)
|
_server.ServeError (_context, http.StatusInternalServerError, _error)
|
||||||
return
|
return
|
||||||
|
@ -200,10 +204,16 @@ func (_server *server) HandleHTTP (_context *fasthttp.RequestCtx) () {
|
||||||
// log.Printf ("[dd] [b15f3cad] serving for `%s`...\n", _path)
|
// log.Printf ("[dd] [b15f3cad] serving for `%s`...\n", _path)
|
||||||
}
|
}
|
||||||
|
|
||||||
_responseHeaders.Set ("cache-control", "public, immutable, max-age=3600")
|
_responseHeaders.SetCanonical ([]byte ("Cache-Control"), []byte ("public, immutable, max-age=3600"))
|
||||||
|
|
||||||
_response.SetStatusCode (http.StatusOK)
|
_response.SetStatusCode (http.StatusOK)
|
||||||
_response.SetBody (_data)
|
|
||||||
|
_dataSize := len (_data)
|
||||||
|
if _dataSize <= 32 * 1024 {
|
||||||
|
_response.SetBody (_data)
|
||||||
|
} else {
|
||||||
|
_response.SetBodyStream (bytes.NewReader (_data), _dataSize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,11 +223,11 @@ func (_server *server) ServeRedirect (_context *fasthttp.RequestCtx, _status uin
|
||||||
_response := &_context.Response
|
_response := &_context.Response
|
||||||
_responseHeaders := &_context.Response.Header
|
_responseHeaders := &_context.Response.Header
|
||||||
|
|
||||||
_responseHeaders.Set ("content-type", MimeTypeText)
|
_responseHeaders.SetCanonical ([]byte ("Content-Type"), []byte (MimeTypeText))
|
||||||
_responseHeaders.Set ("content-encoding", "identity")
|
_responseHeaders.SetCanonical ([]byte ("Content-Encoding"), []byte ("identity"))
|
||||||
_responseHeaders.Set ("etag", "7aa652d8d607b85808c87c1c2105fbb5")
|
_responseHeaders.SetCanonical ([]byte ("ETag"), []byte ("7aa652d8d607b85808c87c1c2105fbb5"))
|
||||||
_responseHeaders.Set ("cache-control", "public, immutable, max-age=3600")
|
_responseHeaders.SetCanonical ([]byte ("Cache-Control"), []byte ("public, immutable, max-age=3600"))
|
||||||
_responseHeaders.SetBytesV ("location", _path)
|
_responseHeaders.SetCanonical ([]byte ("Location"), _path)
|
||||||
|
|
||||||
_response.SetStatusCode (int (_status))
|
_response.SetStatusCode (int (_status))
|
||||||
// _response.SetBody ([]byte (fmt.Sprintf ("[%d] %s", _status, _path)))
|
// _response.SetBody ([]byte (fmt.Sprintf ("[%d] %s", _status, _path)))
|
||||||
|
@ -228,9 +238,9 @@ func (_server *server) ServeError (_context *fasthttp.RequestCtx, _status uint,
|
||||||
_response := &_context.Response
|
_response := &_context.Response
|
||||||
_responseHeaders := &_context.Response.Header
|
_responseHeaders := &_context.Response.Header
|
||||||
|
|
||||||
_responseHeaders.Set ("content-type", MimeTypeText)
|
_responseHeaders.SetCanonical ([]byte ("Content-Type"), []byte (MimeTypeText))
|
||||||
_responseHeaders.Set ("content-encoding", "identity")
|
_responseHeaders.SetCanonical ([]byte ("Content-Encoding"), []byte ("identity"))
|
||||||
_responseHeaders.Set ("cache-control", "no-cache")
|
_responseHeaders.SetCanonical ([]byte ("Cache-Control"), []byte ("no-cache"))
|
||||||
|
|
||||||
_response.SetStatusCode (int (_status))
|
_response.SetStatusCode (int (_status))
|
||||||
// _response.SetBody ([]byte (fmt.Sprintf ("[%d]", _status)))
|
// _response.SetBody ([]byte (fmt.Sprintf ("[%d]", _status)))
|
||||||
|
@ -320,6 +330,18 @@ func main_0 () (error) {
|
||||||
|
|
||||||
runtime.GOMAXPROCS (int (_threads))
|
runtime.GOMAXPROCS (int (_threads))
|
||||||
|
|
||||||
|
debug.SetGCPercent (50)
|
||||||
|
debug.SetMaxThreads (128)
|
||||||
|
debug.SetMaxStack (128 * 1024 * 1024)
|
||||||
|
|
||||||
|
_httpServerReduceMemory := false
|
||||||
|
|
||||||
|
if false {
|
||||||
|
if _error := syscall.Setrlimit (syscall.RLIMIT_DATA, & syscall.Rlimit { Max : 4 * 1024 * 1024 * 1024 }); _error != nil {
|
||||||
|
AbortError (_error, "[f661b4fe] failed to configure limits!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if _processes > 1 {
|
if _processes > 1 {
|
||||||
|
|
||||||
|
@ -549,20 +571,22 @@ func main_0 () (error) {
|
||||||
DisableHeaderNamesNormalizing : true,
|
DisableHeaderNamesNormalizing : true,
|
||||||
|
|
||||||
Concurrency : 4 * 1024,
|
Concurrency : 4 * 1024,
|
||||||
MaxRequestsPerConn : 256 * 1024,
|
|
||||||
MaxRequestBodySize : 0,
|
ReadBufferSize : 8 * 1024,
|
||||||
GetOnly : true,
|
WriteBufferSize : 32 * 1024,
|
||||||
|
|
||||||
ReadTimeout : 6 * time.Second,
|
ReadTimeout : 6 * time.Second,
|
||||||
WriteTimeout : 6 * time.Second,
|
WriteTimeout : 6 * time.Second,
|
||||||
MaxKeepaliveDuration : 60 * time.Second,
|
MaxKeepaliveDuration : 360 * time.Second,
|
||||||
|
MaxRequestsPerConn : 256 * 1024,
|
||||||
ReadBufferSize : 8 * 1024,
|
MaxRequestBodySize : 8 * 1024,
|
||||||
WriteBufferSize : 64 * 1024,
|
GetOnly : true,
|
||||||
|
|
||||||
TCPKeepalive : true,
|
TCPKeepalive : true,
|
||||||
TCPKeepalivePeriod : 6 * time.Second,
|
TCPKeepalivePeriod : 6 * time.Second,
|
||||||
|
|
||||||
|
ReduceMemoryUsage : _httpServerReduceMemory,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_server.httpServer = _httpServer
|
_server.httpServer = _httpServer
|
||||||
|
|
Loading…
Reference in a new issue