Documentation
¶
Index ¶
- type Breeze
- type Context
- func (ctx *Context) Abort()
- func (ctx *Context) GetParam(key string) string
- func (ctx *Context) GetParams() map[string]string
- func (ctx *Context) HTML(data []byte)
- func (ctx *Context) JSON(data any)
- func (ctx *Context) Next()
- func (ctx *Context) Param(key string) string
- func (ctx *Context) ParseMultipart(maxFileSize int64) (map[string][]*UploadedFile, map[string][]string, error)
- func (ctx *Context) Query(key string) string
- func (ctx *Context) SaveUploadedFile(fieldName, destPath string, maxFileSize int64) (string, error)
- func (ctx *Context) SetHeader(key, value string)
- func (ctx *Context) SetParam(key, value string)
- func (ctx *Context) SetParams(p map[string]string)
- func (ctx *Context) Status(code int)
- func (ctx *Context) WriteString(s string)
- type HTTPRequest
- type HTTPResponse
- type HandlerFunc
- type Method
- type Router
- func (r *Router) Find(req *HTTPRequest) (HandlerFunc, []HandlerFunc, map[string]string)
- func (r *Router) Handle(method Method, pattern string, handler HandlerFunc, middlewares ...HandlerFunc)
- func (r *Router) Routes() []*route
- func (r *Router) ServeStatic(prefix, root string)
- func (r *Router) SetStaticDir(dir string)
- func (r *Router) Use(mw ...HandlerFunc)
- type UploadedFile
- type WorkerPool
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Breeze ¶
type Breeze struct {
*gnet.BuiltinEventEngine
Router *Router
Pool *WorkerPool
// contains filtered or unexported fields
}
Breeze is the main server struct, embedding gnet's event engine.
Performance decisions:
- s.mu + s.Bufs[fd] uses per-connection buffering. The single mutex creates contention between gnet reactors when multicore=true. We mitigate this with sync.Map so each fd's read/write is independent.
- buf reslicing (buf = buf[consumed:]) kept the full backing array alive, leaking memory under pipelining. We now compact: when leftover bytes are small we copy them to a fresh slice so the large receive buffer can be GC'd.
- The exec closure captures ctx and c by value so the goroutine/worker doesn't pin the loop variable across iterations.
func New ¶
func New(router *Router, pool *WorkerPool) *Breeze
type Context ¶
type Context struct {
Conn gnet.Conn
Req *HTTPRequest
Res *HTTPResponse
// contains filtered or unexported fields
}
func (*Context) ParseMultipart ¶
func (ctx *Context) ParseMultipart(maxFileSize int64) (map[string][]*UploadedFile, map[string][]string, error)
ParseMultipart stores parsed files and fields into context (so handlers can reuse). It returns files and fields same as req.ParseMultipart.
func (*Context) SaveUploadedFile ¶
SaveUploadedFile saves the first uploaded file from fieldName to destPath using ctx.Req. Returns the original filename and error if any.
func (*Context) SetHeader ¶ added in v0.1.3
SetHeader adds or replaces a single response header.
When the response was built via JSON/WriteString/HTML, its Headers field points to a shared package-level map. SetHeader detects this via the headersShared flag and performs a copy-on-write before mutating, so the shared maps are never clobbered. Subsequent SetHeader calls on the same response are direct writes into the private copy.
func (*Context) Status ¶
Status sets (or overrides) the response status code. For bodyless responses (204, 304) call this alone. For responses with a body, call the body method first (JSON/WriteString/HTML), then call Status — those methods replace ctx.Res entirely.
func (*Context) WriteString ¶
type HTTPRequest ¶
type HTTPRequest struct {
Method Method
Path string
Query url.Values
Header map[string]string
Body []byte
}
HTTPRequest holds parsed HTTP request data.
func ParseHTTPRequest ¶
func ParseHTTPRequest(data []byte) (*HTTPRequest, int, error)
ParseHTTPRequest parses raw bytes into an HTTPRequest.
Performance decisions:
- b2s converts []byte → string with zero allocation (safe here because the string is only used within this function or stored in a map whose backing bytes outlive the function).
- We scan the request-line manually instead of bytes.Split to avoid allocating a [][]byte for the header lines.
- Header keys are lowercased in-place on a stack buffer up to 64 bytes.
func (*HTTPRequest) ParseMultipart ¶
func (req *HTTPRequest) ParseMultipart(maxFileSize int64) (map[string][]*UploadedFile, map[string][]string, error)
ParseMultipart parses a multipart/form-data request body and returns: - files: map[field][]*UploadedFile - fields: map[field][]string (other non-file form fields) If a file is bigger than maxFileSize, an error is returned for that part. Pass maxFileSize as 0 to allow unlimited (not recommended).
This function DOES NOT use http.Request; it operates on your HTTPRequest struct.
func (*HTTPRequest) SaveUploadedFileFromRequest ¶
func (req *HTTPRequest) SaveUploadedFileFromRequest(fieldName, destPath string, maxFileSize int64) (string, error)
SaveUploadedFileFromRequest parses the multipart form and saves the first file from fieldName to destPath. maxFileSize limits each file size in bytes (0 = unlimited). Returns the saved filename (original) and error if any.
type HTTPResponse ¶
type HTTPResponse struct {
Status int
Headers map[string]string
Body []byte
// contains filtered or unexported fields
}
HTTPResponse represents an HTTP response.
func (*HTTPResponse) Bytes ¶
func (r *HTTPResponse) Bytes() []byte
Bytes serializes the HTTPResponse to raw HTTP/1.1 bytes.
Performance decisions:
- No fmt.Sprintf: we use strconv.AppendInt for the status code and content-length, which writes directly into the buffer.
- We pre-size the buffer to avoid growth reallocations for typical responses.
- The status text lookup is a direct array index — O(1), no map hash.
type HandlerFunc ¶
type HandlerFunc func(*Context)
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
func (*Router) Find ¶
func (r *Router) Find(req *HTTPRequest) (HandlerFunc, []HandlerFunc, map[string]string)
Find matches the incoming request to a registered route.
Performance decisions:
- Path splitting uses a manual scanner instead of strings.Split so we can bail out early (wrong segment count) with zero allocations on a miss.
- The params map is only allocated when the route actually has :param segments, and is pre-sized to paramCount.
- paramIndex[] is a pre-computed bool slice so we avoid strings.HasPrefix inside the hot matching loop.
func (*Router) Handle ¶
func (r *Router) Handle(method Method, pattern string, handler HandlerFunc, middlewares ...HandlerFunc)
func (*Router) ServeStatic ¶ added in v0.1.2
ServeStatic registers handlers to serve files under `root` at URL prefix `prefix`. Example: ServeStatic("/static", "./public") will serve ./public/* at /static/*
func (*Router) SetStaticDir ¶ added in v0.1.2
func (*Router) Use ¶
func (r *Router) Use(mw ...HandlerFunc)
type UploadedFile ¶
type UploadedFile struct {
Field string // form field name
Filename string // uploaded filename
Header textproto.MIMEHeader // original part headers
ContentType string // detected content type (from header or sniff)
Size int64 // size in bytes
Content []byte // file bytes (nil if streamed)
}
UploadedFile holds a parsed uploaded file's metadata and content.
type WorkerPool ¶
type WorkerPool struct {
// contains filtered or unexported fields
}
func NewWorkerPool ¶
func NewWorkerPool(concurrency int) *WorkerPool
NewWorkerPool creates a pool with `concurrency` goroutines and a task queue of concurrency × defaultChannelMultiplier to absorb request bursts without blocking gnet's event loops.
func (*WorkerPool) Shutdown ¶
func (p *WorkerPool) Shutdown(ctx context.Context)
Shutdown waits for all in-flight tasks to complete or for ctx to expire.
func (*WorkerPool) Submit ¶
func (p *WorkerPool) Submit(f func())
Submit enqueues a task. It never blocks as long as the queue has capacity; if the queue is full it falls back to spawning a goroutine so the event loop is never stalled.