Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version: 1.19
go-version: 1.25

- name: Build
run: go build -v ./
run: go build -v ./...

- name: Test
run: go test -v ./
run: go test -v ./...
117 changes: 117 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# AGENTS.md - Lightning Framework

## Commands

```bash
# Build
go build ./...

# Run all tests
go test ./...

# Run a single test
go test -v -run TestName ./

# Run tests with coverage
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out

# Run tests for a specific file
go test -v -run TestName context_test.go context.go request.go response.go consts.go json.go context_data.go cookie.go

# Makefile
make test # runs tests with coverage, generates coverage.html
```

**Note:** Go 1.20+ required. The `make test` target generates `coverage.out` and `coverage.html` (both gitignored).

## Code Style

### Imports
- Two groups separated by blank line: stdlib first, then third-party.
- No vendoring. Use fully qualified import paths.
```go
import (
"encoding/json"
"os"
"strings"

"github.com/valyala/fasthttp"
)
```

### Formatting
- Use `gofmt` (tabs for indentation, standard Go style).
- No line length limit enforced.

### Types & Structs
- Exported fields: `PascalCase`; unexported fields: `camelCase`.
- Each field on its own line.
- Function types over interfaces where possible (`type Middleware = HandlerFunc`).
- Custom map types for simple wrappers: `type cookiesMap map[string]string`.

### Naming Conventions
- **Constructors:** `NewXxx()` (exported), `newXxx()` (unexported).
- **Methods:** Verb-first: `Get()`, `Post()`, `SetData()`, `SetHeader()`, `AddRoute()`.
- **Constants:** `PascalCase` with category prefix: `StatusOK`, `MethodGet`, `HeaderContentType`, `MIMEApplicationJSON`.
- **Package:** `lightning` (lowercase, single word).

### Error Handling
- Return `error` for recoverable failures: `ParamInt() (int, error)`, `File() error`.
- Silent failure on marshal errors in `JSON()`/`XML()` (no error propagation).
- Panic only in `resolveAddress()` (too many params) and `LoadHTMLGlob()` (via `template.Must`).
- `Recovery()` middleware catches panics and returns 500.
- No custom error types; use standard `error` interface.

### Comments
- Every exported function/type/method must have a doc comment starting with its name.
- Unexported functions should also have descriptive comments.
- Use section comments in `consts.go` to group constants.

## Architecture

### Key Patterns
- **Handlers:** `func(ctx *Context)` — never expose `*fasthttp.RequestCtx` directly.
- **Middleware:** Same signature as handlers (`type Middleware = HandlerFunc`). Chain via `ctx.Next()`.
- **Context pooling:** `sync.Pool` with `acquireContext()`/`releaseContext()`. Always call `reset()` before returning.
- **Router:** Trie-based with per-method roots. Supports `:param` and `*wildcard` patterns.
- **Request serving:** `app.serveRequest(ctx)` for testing; `app.RequestHandler()` for fasthttp server.

### Response Helpers
- `ctx.JSON(code, obj)` — sets Content-Type to `application/json`.
- `ctx.Text(code, text)` — sets Content-Type to `text/plain`.
- `ctx.HTML(code, name, data)` — renders named template.
- `ctx.XML(code, obj)` — sets Content-Type to `application/xml`.
- `ctx.Success(data)` — returns `{"code":0,"message":"ok","data":...}`.
- `ctx.Fail(code, msg)` — returns `{"code":N,"message":"..."}` with 200 status.

## Testing

- All tests in `package lightning` (same package).
- Use `createTestContext(method, path, body)` for full Context with request/response.
- Use `newTestCtx(method, path)` for bare `*fasthttp.RequestCtx`.
- Use `app.serveRequest(ctx)` to simulate requests without a real server.
- Table-driven tests with `t.Run()` for parameterized cases.
- No third-party test libraries (no testify).
- Target coverage: **≥90%** (currently ~90.1%).

## Project Structure

All source files at root level (single package):

| File | Purpose |
|------|---------|
| `lightning.go` | Application struct, config, server startup, context pooling |
| `context.go` | Context API — params, queries, headers, response methods |
| `router.go` | Trie-based router with `:param` and `*wildcard` support |
| `group.go` | Route grouping with prefix inheritance and middleware |
| `request.go` | Internal request wrapper (fasthttp delegation) |
| `response.go` | Internal response wrapper (status, body, redirect, file) |
| `consts.go` | HTTP constants: status codes, methods, MIME types, headers |
| `logger.go` / `recovery.go` | Built-in middleware |
| `cookie.go` / `context_data.go` | Simple map wrappers for cookies and per-request data |

## CI

GitHub Actions (`.github/workflows/go.yml`): runs `go build` and `go test` on push/PR to `main`.
No linting configured (no golangci-lint, go vet, or staticcheck).
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
# Changelog

## [0.9.0] - Apr 1, 2026

### Added

- AGENTS.md with comprehensive project guidelines for AI agents
- HTTP status code constants (StatusOK, StatusNotFound, StatusInternalServerError, etc.)
- HTTP method constants (MethodGet, MethodPost, MethodPut, etc.)
- MIME type constants (MIMEApplicationJSON, MIMETextHTML, etc.)
- Header key constants (HeaderContentType, HeaderAccept, HeaderAuthorization, etc.)
- Additional Context methods: IsAjax(), IsWebSocket(), AcceptedLanguages(), RemoteAddr()
- Middleware caching in route groups

### Changed

- **Major**: Refactor from net/http to fasthttp for better performance
- Upgrade Go minimum version requirement to 1.25
- Upgrade fasthttp from v1.52.0 to v1.69.0
- Upgrade validator/v10 from v10.12.0 to v10.30.2
- Upgrade golang.org/x/crypto from v0.19.0 to v0.49.0
- Upgrade golang.org/x/sys from v0.17.0 to v0.42.0
- Upgrade golang.org/x/text from v0.14.0 to v0.35.0
- Router optimization: matchChild from O(n) to O(1)
- Replace interface{} with any throughout codebase
- Simplified cookiesMap to store string values instead of http.Cookie pointers
- Update examples for fasthttp compatibility
- Update HTTP constants to match fasthttp

### Fixed

- Improved test coverage for lightning.go (Run, Shutdown, Static, Context pooling)
- Fixed route matching issues
- Fixed context pool reuse bug where data wasn't being reset properly
- Fixed X-Forwarded-For header parsing for comma-separated IP addresses

### Performance

- Test coverage improved from 90.1% to 96.0%
- Context pooling via sync.Pool for reduced GC pressure

## [0.8.0] - Mar 29, 2026

### Added
Expand Down
86 changes: 82 additions & 4 deletions consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,92 @@ package lightning

// MIME types
const (
MIMETextPlain = "text/plain"
MIMETextHTML = "text/html"
MIMEApplicationXML = "application/xml"
MIMEApplicationJSON = "application/json"
MIMETextPlain = "text/plain"
MIMETextHTML = "text/html"
MIMEApplicationXML = "application/xml"
MIMEApplicationJSON = "application/json"
MIMEApplicationXMLCharsetUTF8 = "application/xml; charset=utf-8"
MIMEApplicationJSONCharsetUTF8 = "application/json; charset=utf-8"
MIMEMultipartForm = "multipart/form-data"
MIMEOctetStream = "application/octet-stream"
)

// Header keys
const (
HeaderContentType = "Content-Type"
HeaderContentDisposition = "Content-Disposition"
HeaderContentEncoding = "Content-Encoding"
HeaderContentLength = "Content-Length"
HeaderAccept = "Accept"
HeaderAcceptEncoding = "Accept-Encoding"
HeaderAcceptLanguage = "Accept-Language"
HeaderAuthorization = "Authorization"
HeaderCacheControl = "Cache-Control"
HeaderConnection = "Connection"
HeaderCookie = "Cookie"
HeaderHost = "Host"
HeaderOrigin = "Origin"
HeaderReferer = "Referer"
HeaderUserAgent = "User-Agent"
HeaderXRequestedWith = "X-Requested-With"
HeaderXRealIP = "X-Real-IP"
HeaderXForwardedFor = "X-Forwarded-For"
HeaderLocation = "Location"
HeaderUpgrade = "Upgrade"
)

// HTTP status codes
const (
StatusContinue = 100
StatusSwitchingProtocols = 101
StatusOK = 200
StatusCreated = 201
StatusAccepted = 202
StatusNoContent = 204
StatusMultipleChoices = 300
StatusMovedPermanently = 301
StatusFound = 302
StatusSeeOther = 303
StatusNotModified = 304
StatusUseProxy = 305
StatusTemporaryRedirect = 307
StatusBadRequest = 400
StatusUnauthorized = 401
StatusPaymentRequired = 402
StatusForbidden = 403
StatusNotFound = 404
StatusMethodNotAllowed = 405
StatusNotAcceptable = 406
StatusProxyAuthRequired = 407
StatusRequestTimeout = 408
StatusConflict = 409
StatusGone = 410
StatusLengthRequired = 411
StatusPreconditionFailed = 412
StatusRequestEntityTooLarge = 413
StatusRequestURITooLarge = 414
StatusUnsupportedMediaType = 415
StatusRequestedRangeNotSatisfiable = 416
StatusExpectationFailed = 417
StatusTeapot = 418
StatusUpgradeRequired = 426
StatusInternalServerError = 500
StatusNotImplemented = 501
StatusBadGateway = 502
StatusServiceUnavailable = 503
StatusGatewayTimeout = 504
StatusHTTPVersionNotSupported = 505
)

// HTTP methods
const (
MethodGet = "GET"
MethodHead = "HEAD"
MethodPost = "POST"
MethodPut = "PUT"
MethodPatch = "PATCH"
MethodDelete = "DELETE"
MethodConnect = "CONNECT"
MethodOptions = "OPTIONS"
MethodTrace = "TRACE"
)
Loading
Loading