web

package module
v0.0.0-...-7351cbd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2025 License: MIT Imports: 20 Imported by: 0

README

🌐 web - Flask-inspired Web Framework for Starlark

Go Reference Go Report Card License

Flask-inspired web framework for building server-side applications in Starlark.

Overview

The web module provides a comprehensive web framework for Starlark that enables building modern web applications with:

  • Flask-inspired API: Familiar routing and request handling patterns
  • Flexible Authentication: Multiple authentication methods (Basic, Bearer, API Key)
  • Rich Middleware System: 10+ built-in middleware functions for common tasks
  • Response Builders: Convenient functions for HTML, JSON, and other response types
  • Route Management: Support for route groups, path parameters, and HTTP methods
  • Static File Serving: Built-in static file serving capabilities
  • File Upload Support: Handle multipart form data and file uploads

Installation

go get github.com/1set/starpkg/web

Configuration

The web module supports the following configuration options:

Option Type Default Description
host string "localhost" Server host address
port int 8080 Server port
read_timeout int 30 Read timeout in seconds
write_timeout int 30 Write timeout in seconds
max_header_size int 1048576 Maximum header size in bytes
server_header string "Starlark-Web" Server header value

Basic Usage

Creating a Server
load("web", "create_server", "html_response")

def main():
    srv = create_server(port=8080, host="localhost")
    
    def hello(req):
        return html_response("<h1>Hello, World!</h1>")
    
    srv.get("/", hello)
    srv.run()

main()
Route Registration
# HTTP method-specific routes
srv.get("/users", list_users)
srv.post("/users", create_user)
srv.put("/users/{id}", update_user)
srv.delete("/users/{id}", delete_user)

# Multiple methods for same route
srv.route(["GET", "POST"], "/contact", handle_contact)

# Route with path parameters
def user_profile(req):
    user_id = req.param("id")
    return json_response({"user_id": user_id})

srv.get("/users/{id}", user_profile)
Request Handling
def handle_request(req):
    # HTTP method and path
    method = req.method
    path = req.path
    
    # Path parameters
    user_id = req.param("id")
    
    # Query parameters
    page = req.query("page", "1")
    
    # Headers
    auth_header = req.header("Authorization")
    
    # Form data
    form_data = req.form()
    name = form_data.get("name") if form_data else None
    
    # JSON data
    json_data = req.json()
    
    # File uploads
    file_data = req.file("upload")
    
    return json_response({"status": "ok"})

Unified Middleware System

The web module provides a unified middleware system where all middleware has path patterns. This provides consistent behavior and powerful routing capabilities.

Key Concepts
  • Global middleware uses the pattern "/*" to match all paths
  • Path-specific middleware uses patterns like "/api/*" or "/admin/*"
  • Exact path middleware uses patterns like "/api/upload"
  • Complex patterns support wildcards like "/files/*/download"
  • Parameter patterns support Flask-style parameters like "/users/{id}"

The use() method is simply shorthand for use_for("/*", middleware) - both approaches are equivalent.

Core Middleware Functions
1. Logging Middleware

Logs all HTTP requests with customizable format.

load("web", "logging_middleware")

# Basic logging
srv.use(logging_middleware())

# Custom format
srv.use(logging_middleware(
    format="{remote_addr} - {method} {path} - {status} ({duration}ms) - {user_agent}"
))

# Skip certain paths
srv.use(logging_middleware(
    skip_paths=["/health", "/metrics"]
))

Parameters:

  • format (string): Log format template with placeholders:
    • {remote_addr}: Client IP address
    • {method}: HTTP method
    • {path}: Request path
    • {status}: Response status code
    • {duration}: Request duration in milliseconds
    • {user_agent}: User agent string
    • {referer}: Referer header
  • skip_paths (list): List of paths to skip logging
  • output (string): Log output destination ("stdout", "stderr", or file path)
2. CORS Middleware

Handles Cross-Origin Resource Sharing (CORS) headers.

load("web", "cors_middleware")

# Basic CORS (allows all origins)
srv.use(cors_middleware())

# Custom CORS configuration
srv.use(cors_middleware(
    origins=["https://example.com", "https://app.example.com"],
    methods=["GET", "POST", "PUT", "DELETE"],
    headers=["Content-Type", "Authorization", "X-API-Key"],
    exposed_headers=["X-Total-Count"],
    credentials=True,
    max_age=3600
))

Parameters:

  • origins (list): Allowed origin domains (default: ["*"])
  • methods (list): Allowed HTTP methods (default: ["GET", "POST", "PUT", "DELETE", "OPTIONS"])
  • headers (list): Allowed request headers (default: ["*"])
  • exposed_headers (list): Headers exposed to the client (default: [])
  • credentials (bool): Allow credentials (default: False)
  • max_age (int): Preflight cache duration in seconds (default: 300)
3. Compression Middleware

Compresses response bodies using gzip.

load("web", "compression_middleware")

# Basic compression
srv.use(compression_middleware())

# Custom compression settings
srv.use(compression_middleware(
    level=6,
    min_size=1024,
    types=["text/html", "application/json", "text/css", "application/javascript"]
))

Parameters:

  • level (int): Compression level 1-9 (default: 6)
  • min_size (int): Minimum response size to compress in bytes (default: 1024)
  • types (list): MIME types to compress (default: text/* and application/json)
4. Security Headers Middleware

Adds common security headers to responses.

load("web", "security_headers_middleware")

# Basic security headers
srv.use(security_headers_middleware())

# Custom security configuration
srv.use(security_headers_middleware(
    content_type_options="nosniff",
    frame_options="DENY",
    xss_protection="1; mode=block",
    hsts_max_age=31536000,
    hsts_include_subdomains=True,
    content_security_policy="default-src 'self'",
    referrer_policy="strict-origin-when-cross-origin"
))

Parameters:

  • content_type_options (string): X-Content-Type-Options header (default: "nosniff")
  • frame_options (string): X-Frame-Options header (default: "DENY")
  • xss_protection (string): X-XSS-Protection header (default: "1; mode=block")
  • hsts_max_age (int): HSTS max-age in seconds (default: 31536000)
  • hsts_include_subdomains (bool): Include subdomains in HSTS (default: False)
  • content_security_policy (string): Content-Security-Policy header (default: None)
  • referrer_policy (string): Referrer-Policy header (default: "strict-origin-when-cross-origin")
5. Rate Limiting Middleware

Limits request rate per client IP address.

load("web", "rate_limiting_middleware")

# Basic rate limiting (60 requests per minute)
srv.use(rate_limiting_middleware())

# Custom rate limiting
srv.use(rate_limiting_middleware(
    requests_per_minute=100,
    burst_size=10,
    window_size=60,
    key_func=lambda req: req.header("X-API-Key") or req.remote_addr
))

Parameters:

  • requests_per_minute (int): Maximum requests per minute (default: 60)
  • burst_size (int): Maximum burst requests (default: 10)
  • window_size (int): Time window in seconds (default: 60)
  • key_func (function): Function to generate rate limit key (default: uses IP address)
  • skip_successful (bool): Skip rate limiting for successful requests (default: False)
  • headers (bool): Include rate limit headers in response (default: True)
6. Timing Middleware

Adds response timing information.

load("web", "timing_middleware")

# Basic timing
srv.use(timing_middleware())

# Custom timing configuration
srv.use(timing_middleware(
    header="X-Response-Time",
    unit="ms",
    precision=2
))

Parameters:

  • header (string): Response header name (default: "X-Response-Time")
  • unit (string): Time unit ("ms", "s", "us") (default: "ms")
  • precision (int): Decimal precision for timing (default: 2)
7. Request Size Middleware

Limits request body and header sizes.

load("web", "request_size_middleware")

# Basic size limits
srv.use(request_size_middleware())

# Custom size limits
srv.use(request_size_middleware(
    max_body_size=10485760,  # 10MB
    max_header_size=8192,    # 8KB
    max_url_length=2048,     # 2KB
    max_headers_count=50
))

Parameters:

  • max_body_size (int): Maximum request body size in bytes (default: 1048576)
  • max_header_size (int): Maximum header size in bytes (default: 4096)
  • max_url_length (int): Maximum URL length (default: 2048)
  • max_headers_count (int): Maximum number of headers (default: 50)
8. Recovery Middleware

Recovers from panics and returns error responses.

load("web", "recovery_middleware")

# Basic recovery
srv.use(recovery_middleware())

# Custom recovery configuration
srv.use(recovery_middleware(
    log_panics=True,
    debug_mode=False,
    recovery_handler=lambda req, err: error_response(500, "Internal Server Error")
))

Parameters:

  • log_panics (bool): Log panic details (default: True)
  • debug_mode (bool): Include stack trace in response (default: False)
  • recovery_handler (function): Custom recovery handler function
9. Caching Middleware

Adds HTTP caching headers to responses.

load("web", "caching_middleware")

# Basic caching
srv.use(caching_middleware())

# Custom caching configuration
srv.use(caching_middleware(
    max_age=3600,
    private=False,
    no_cache=False,
    no_store=False,
    must_revalidate=False,
    etag_func=lambda req: generate_etag(req.path)
))

Parameters:

  • max_age (int): Cache max-age in seconds (default: 3600)
  • private (bool): Set cache as private (default: False)
  • no_cache (bool): Set no-cache directive (default: False)
  • no_store (bool): Set no-store directive (default: False)
  • must_revalidate (bool): Set must-revalidate directive (default: False)
  • etag_func (function): Function to generate ETag values
10. Unified Middleware Application

Apply middleware using path patterns. All middleware functions in the unified system require a path pattern.

# Global middleware (applies to all routes using "/*" pattern)
srv.use(logging_middleware())  # Equivalent to srv.use_for("/*", logging_middleware())
srv.use(cors_middleware())

# Path-specific middleware
srv.use_for("/api/*", rate_limit_middleware())
srv.use_for("/admin/*", security_headers_middleware())

# Exact path middleware
srv.use_for("/api/upload", request_size_middleware())

# Complex wildcard patterns
srv.use_for("/files/*/download", security_headers_middleware())

# Parameter patterns
srv.use_for("/users/{id}", timing_middleware())
srv.use_for("/users/{id}/posts/{post_id}", compression_middleware())
Custom Middleware

Create custom middleware functions:

def custom_middleware():
    def middleware(req, next):
        # Add custom header to all responses
        resp = next(req)
        resp.set_header("X-Custom-Server", "Starlark-Web")
        # Return a response to short-circuit the chain
        return resp
    return middleware

srv.use(custom_middleware())

Authentication System

The web module supports multiple authentication methods that can be used independently or combined.

Basic Authentication

HTTP Basic Authentication with username/password.

load("web", "basic_auth")

# Create basic auth with users
auth = basic_auth(
    users={"admin": "secret", "user": "password"},
    realm="Protected Area"
)

# Apply to specific routes
srv.use_for("/admin/*", auth.middleware())

# Access auth info in handlers
def protected_handler(req):
    basic_info = req.basic_auth()
    if basic_info:
        username, password = basic_info
        return html_response("Welcome, {}!".format(username))
    return error_response(401, "Unauthorized")
Bearer Token Authentication

Token-based authentication using Authorization header.

load("web", "bearer_auth")

# Create bearer auth with tokens
auth = bearer_auth(
    tokens={"token123": "admin", "token456": "user"},
    realm="API Access"
)

# Apply to API routes
srv.use_for("/api/*", auth.middleware())

# Access token info in handlers
def api_handler(req):
    token_info = req.bearer_token()
    if token_info:
        return json_response({"user": token_info})
    return error_response(401, "Invalid token")
API Key Authentication

API key authentication using custom headers.

load("web", "api_key_auth")

# Create API key auth
auth = api_key_auth(
    api_keys={"key123": "admin", "key456": "user"},
    header="X-API-Key"
)

# Apply to API endpoints
srv.use_for("/api/*", auth.middleware())

# Access API key info in handlers
def api_handler(req):
    api_key_info = req.api_key()
    if api_key_info:
        return json_response({"user": api_key_info})
    return error_response(401, "Invalid API key")

Response Builders

Convenient functions for creating different types of responses.

HTML Response
load("web", "html_response")

def home(req):
    return html_response("""
    <!DOCTYPE html>
    <html>
    <head><title>My App</title></head>
    <body><h1>Welcome!</h1></body>
    </html>
    """)

# With custom status code
def not_found(req):
    return html_response("<h1>Not Found</h1>", status=404)

# With custom headers
def custom_html(req):
    return html_response(
        "<h1>Custom</h1>",
        headers={"X-Custom": "value"}
    )
JSON Response
load("web", "json_response")

def api_users(req):
    return json_response({
        "users": [
            {"id": 1, "name": "Alice"},
            {"id": 2, "name": "Bob"}
        ]
    })

# With custom status code
def api_create_user(req):
    return json_response(
        {"id": 123, "name": "New User"},
        status=201
    )
Error Response
load("web", "error_response")

def handle_error(req):
    return error_response(400, "Bad Request")

# With custom error details
def detailed_error(req):
    return error_response(
        422,
        "Validation Error",
        details={"field": "email", "message": "Invalid email format"}
    )
Redirect Response
load("web", "redirect")

def old_page(req):
    return redirect("/new-page")

# With custom status code
def permanent_redirect(req):
    return redirect("/new-location", status=301)
File Response
load("web", "file_response")

def download_file(req):
    return file_response(
        "/path/to/file.pdf",
        filename="document.pdf",
        content_type="application/pdf"
    )

Static File Serving

Serve static files from directories:

# Serve static files from a directory
srv.static("/static", "./public")

# Serve single file
srv.static_file("/favicon.ico", "./assets/favicon.ico")

# With custom middleware for static files
srv.use_for("/static/*", [
    caching_middleware(max_age=86400),  # 24 hours
    compression_middleware()
])

Complete Example

Here's a complete example demonstrating the unified middleware system:

load("web", "create_server", "html_response", "json_response", "error_response", 
     "basic_auth", "cors_middleware", "logging_middleware", "compression_middleware", 
     "security_headers_middleware")

def main():
    srv = create_server(port=8080, server_header="MyApp/1.0")
    
    # Authentication
    auth = basic_auth(users={"admin": "secret"}, realm="Admin")
    
    # Routes
    def home(req):
        return html_response("""
        <!DOCTYPE html>
        <html>
        <head><title>My App</title></head>
            <body>
            <h1>Welcome!</h1>
            <p><a href="/api/status">API Status</a></p>
            <p><a href="/admin">Admin Area</a></p>
            </body>
        </html>
        """)
    
    def admin_area(req):
        basic_info = req.basic_auth()
        username = basic_info[0] if basic_info else "unknown"
        return html_response("<h1>Admin: {}</h1>".format(username))
    
    def api_status(req):
        return json_response({"status": "ok", "version": "1.0"})
    
    # Register routes
    srv.get("/", home)
    srv.get("/api/status", api_status)
    srv.get("/admin", admin_area)
    
    # ========================================
    # UNIFIED MIDDLEWARE SYSTEM
    # ========================================
    # All middleware now has path patterns
    
    # Global middleware (applies to all routes using "/*" pattern)
    srv.use(logging_middleware())  # Same as srv.use_for("/*", logging_middleware())
    srv.use(cors_middleware())
    
    # API-specific middleware (applies only to /api/* routes)
    srv.use_for("/api/*", compression_middleware())
    srv.use_for("/api/*", security_headers_middleware())
    
    # Admin-specific middleware (applies only to /admin/* routes)
    srv.use_for("/admin/*", auth.middleware())  # Authentication required
    srv.use_for("/admin/*", security_headers_middleware())
    
    # Static files
    srv.static("/static", "./public")
    
    print("Server running on http://localhost:8080")
    print("Features demonstrated:")
    print("- Global middleware using /* pattern")
    print("- Path-specific middleware for API and admin routes")
    print("- Authentication protection for admin area")
    print("- Multiple middleware layers combining correctly")
    srv.run()

main()

API Reference

Server Methods
  • create_server(**config): Create a new server instance
  • srv.get(path, handler): Register GET route
  • srv.post(path, handler): Register POST route
  • srv.put(path, handler): Register PUT route
  • srv.delete(path, handler): Register DELETE route
  • srv.route(methods, path, handler): Register route with multiple methods
  • srv.use(middleware): Apply global middleware
  • srv.use_for(path, middleware): Apply middleware to specific paths
  • srv.static(path, directory): Serve static files
  • srv.static_file(path, file): Serve single static file
  • srv.run(): Start the server
Request Methods
  • req.method: HTTP method
  • req.path: Request path
  • req.remote_addr: Client IP address
  • req.param(name): Get path parameter
  • req.query(name, default=None): Get query parameter
  • req.header(name): Get header value
  • req.form(): Get form data as dict
  • req.json(): Parse JSON body
  • req.file(name): Get uploaded file
  • req.basic_auth(): Get basic auth credentials
  • req.bearer_token(): Get bearer token
  • req.api_key(): Get API key
Response Functions
  • html_response(content, status=200, headers=None): Create HTML response
  • json_response(data, status=200, headers=None): Create JSON response
  • error_response(status, message, details=None): Create error response
  • redirect(url, status=302): Create redirect response
  • file_response(path, filename=None, content_type=None): Create file response
Authentication Functions
  • basic_auth(users, realm="Restricted"): Create basic authentication
  • bearer_auth(tokens, realm="API"): Create bearer token authentication
  • api_key_auth(api_keys, header="X-API-Key"): Create API key authentication
Middleware Functions
  • logging_middleware(**options): Request logging
  • cors_middleware(**options): CORS headers
  • compression_middleware(**options): Response compression
  • security_headers_middleware(**options): Security headers
  • rate_limiting_middleware(**options): Rate limiting
  • timing_middleware(**options): Response timing
  • request_size_middleware(**options): Request size limits
  • recovery_middleware(**options): Panic recovery
  • caching_middleware(**options): HTTP caching headers

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Overview

Package web provides a Starlark module for server-side web applications. It offers a Flask-inspired API for building HTTP servers with routing, middleware, request/response handling, and session management capabilities.

Example (BasicWebServer)
script := `
load("web", "create_server", "response", "json_response")

def main():
    # Create server
    srv = create_server(host="localhost", port=8080)
    
    # Simple text response
    def home(req):
        return response("Welcome to Starlark Web!")
    
    # JSON API endpoint
    def api_info(req):
        return json_response({
            "name": "Starlark Web API",
            "version": "1.0",
            "method": req.method,
            "path": req.path,
        })
    
    # Register routes
    srv.get("/", home)
    srv.get("/api/info", api_info)
    
    print("Server created successfully")
    
    # Start server
    srv.start()
    
    # TODO: make something calling via http package to verify the response
    
    # Stop server
    srv.stop()

main()
`

// Create machine with web module
machine := starlet.NewWithNames(starlet.StringAnyMap{}, []string{"go_idiomatic", "http"}, []string{})
machine.SetPrintFunc(func(thread *starlark.Thread, msg string) {
	// Print function for testing
	fmt.Println(msg)
})

// Load web module
webModule := NewModule()
machine.AddLazyloadModules(starlet.ModuleLoaderMap{
	ModuleName: webModule.LoadModule(),
})

_, err := machine.RunScript([]byte(script), nil)
if err != nil {
	panic(err)
}
Output:
Server created successfully

Index

Examples

Constants

View Source
const (
	MIMEApplicationJSON        = "application/json"
	MIMEApplicationJavaScript  = "application/javascript"
	MIMETextHTML               = "text/html"
	MIMETextPlain              = "text/plain"
	MIMETextCSS                = "text/css"
	MIMETextJavaScript         = "text/javascript"
	MIMEMultipartForm          = "multipart/form-data"
	MIMEApplicationForm        = "application/x-www-form-urlencoded"
	MIMEApplicationOctetStream = "application/octet-stream"
)

MIME types

View Source
const (
	HeaderContentType        = "Content-Type"
	HeaderContentLength      = "Content-Length"
	HeaderContentDisposition = "Content-Disposition"
	HeaderContentEncoding    = "Content-Encoding"
	HeaderAuthorization      = "Authorization"
	HeaderWWWAuthenticate    = "WWW-Authenticate"
	HeaderAPIKey             = "X-API-Key"
	HeaderCacheControl       = "Cache-Control"
	HeaderServer             = "Server"
	HeaderLocation           = "Location"
	HeaderVary               = "Vary"
	HeaderRetryAfter         = "Retry-After"

	// CORS headers
	HeaderAccessControlAllowOrigin      = "Access-Control-Allow-Origin"
	HeaderAccessControlAllowMethods     = "Access-Control-Allow-Methods"
	HeaderAccessControlAllowHeaders     = "Access-Control-Allow-Headers"
	HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"

	// Response time header
	HeaderXResponseTime = "X-Response-Time"

	// Rate limiting headers
	HeaderXRateLimitLimit     = "X-RateLimit-Limit"
	HeaderXRateLimitRemaining = "X-RateLimit-Remaining"
	HeaderXRateLimitReset     = "X-RateLimit-Reset"
)

Header names

View Source
const ModuleName = "web"

ModuleName defines the expected name for this module when used in Starlark's load() function

Variables

View Source
var DefaultPathMatcher = NewPathMatcher()

DefaultPathMatcher is a singleton instance for global use.

Functions

func ExtractParams

func ExtractParams(requestPath, pattern string) map[string]string

ExtractParams is a convenience function that uses the default PathMatcher.

func IsValidPattern

func IsValidPattern(pattern string) bool

IsValidPattern is a convenience function that uses the default PathMatcher.

func MatchesAny

func MatchesAny(requestPath string, patterns []string) bool

MatchesAny is a convenience function that uses the default PathMatcher.

func MatchesPattern

func MatchesPattern(requestPath, pattern string) bool

MatchesPattern is a convenience function that uses the default PathMatcher.

func NormalizePath

func NormalizePath(inputPath string) string

NormalizePath is a convenience function that uses the default PathMatcher.

Types

type AuthResult

type AuthResult struct {
	Success   bool
	UserInfo  interface{}
	ErrorCode int
	Message   string
}

AuthResult represents the result of authentication

type Authenticator

type Authenticator struct {
	// contains filtered or unexported fields
}

Authenticator represents an authentication handler that can be used as middleware

func (*Authenticator) Middleware

func (a *Authenticator) Middleware() MiddlewareFunc

Middleware returns a middleware function for this authenticator

type AuthenticatorWrapper

type AuthenticatorWrapper struct {
	// contains filtered or unexported fields
}

AuthenticatorWrapper wraps the Authenticator for Starlark

func NewAuthenticatorWrapper

func NewAuthenticatorWrapper(auth *Authenticator) *AuthenticatorWrapper

NewAuthenticatorWrapper creates a new wrapper

func (*AuthenticatorWrapper) Attr

func (aw *AuthenticatorWrapper) Attr(name string) (starlark.Value, error)

Attr returns the named attribute

func (*AuthenticatorWrapper) AttrNames

func (aw *AuthenticatorWrapper) AttrNames() []string

AttrNames returns available attributes

func (*AuthenticatorWrapper) Freeze

func (aw *AuthenticatorWrapper) Freeze()

Freeze makes the object immutable

func (*AuthenticatorWrapper) Hash

func (aw *AuthenticatorWrapper) Hash() (uint32, error)

Hash returns a hash value

func (*AuthenticatorWrapper) String

func (aw *AuthenticatorWrapper) String() string

String returns string representation

func (*AuthenticatorWrapper) Truth

func (aw *AuthenticatorWrapper) Truth() starlark.Bool

Truth returns the truth value

func (*AuthenticatorWrapper) Type

func (aw *AuthenticatorWrapper) Type() string

Type returns the Starlark type name

type ErrorHandler

type ErrorHandler struct {
	// contains filtered or unexported fields
}

ErrorHandler represents a custom error handler function

type ErrorHandlerRegistry

type ErrorHandlerRegistry struct {
	// contains filtered or unexported fields
}

ErrorHandlerRegistry manages custom error handlers

func NewErrorHandlerRegistry

func NewErrorHandlerRegistry() *ErrorHandlerRegistry

NewErrorHandlerRegistry creates a new error handler registry

func (*ErrorHandlerRegistry) GetHandler

func (ehr *ErrorHandlerRegistry) GetHandler(statusCode int) starlark.Callable

GetHandler returns the handler for a specific status code

func (*ErrorHandlerRegistry) HandleError

func (ehr *ErrorHandlerRegistry) HandleError(statusCode int, req *Request) *Response

HandleError calls the appropriate error handler or returns a default error response

func (*ErrorHandlerRegistry) RegisterHandler

func (ehr *ErrorHandlerRegistry) RegisterHandler(statusCodes []int, handler starlark.Callable)

RegisterHandler registers an error handler for specific status codes

type ErrorResponse

type ErrorResponse struct {
	Error   string `json:"error"`
	Message string `json:"message,omitempty"`
	Code    int    `json:"code"`
}

ErrorResponse represents a standardized error response. This structure provides a consistent format for all HTTP error responses throughout the web module, including error message, HTTP status code, and description.

type HTTPMethod

type HTTPMethod string

HTTPMethod represents the supported HTTP methods

const (
	MethodGet     HTTPMethod = http.MethodGet
	MethodPost    HTTPMethod = http.MethodPost
	MethodPut     HTTPMethod = http.MethodPut
	MethodDelete  HTTPMethod = http.MethodDelete
	MethodPatch   HTTPMethod = http.MethodPatch
	MethodOptions HTTPMethod = http.MethodOptions
	MethodHead    HTTPMethod = http.MethodHead
)

type MemoryRateLimitStorage

type MemoryRateLimitStorage struct {
	// contains filtered or unexported fields
}

MemoryRateLimitStorage implements in-memory rate limiting storage

func NewMemoryRateLimitStorage

func NewMemoryRateLimitStorage() *MemoryRateLimitStorage

NewMemoryRateLimitStorage creates a new memory-based rate limit storage

func (*MemoryRateLimitStorage) Get

func (m *MemoryRateLimitStorage) Get(key string) (int, error)

func (*MemoryRateLimitStorage) Increment

func (m *MemoryRateLimitStorage) Increment(key string, ttl time.Duration) (int, error)

func (*MemoryRateLimitStorage) Set

func (m *MemoryRateLimitStorage) Set(key string, value int, ttl time.Duration) error

type Middleware

type Middleware struct {
	Pattern string
	Handler MiddlewareFunc
}

Middleware represents middleware with a specific path pattern. All middleware in the system has an associated path pattern. Global middleware uses the pattern "/*" to match all paths.

func (*Middleware) MatchesPath

func (m *Middleware) MatchesPath(path string) bool

MatchesPath checks if the given path matches the middleware pattern. Uses the unified PathMatcher for consistent path matching behavior.

type MiddlewareFunc

type MiddlewareFunc func(*Request, NextFunc) *Response

MiddlewareFunc represents a middleware function

type MiddlewareWrapper

type MiddlewareWrapper struct {
	// contains filtered or unexported fields
}

MiddlewareWrapper wraps a middleware function for Starlark

func NewMiddlewareWrapper

func NewMiddlewareWrapper(middleware MiddlewareFunc) *MiddlewareWrapper

NewMiddlewareWrapper creates a new middleware wrapper

func (*MiddlewareWrapper) Attr

func (mw *MiddlewareWrapper) Attr(name string) (starlark.Value, error)

Attr returns the named attribute (none for now)

func (*MiddlewareWrapper) AttrNames

func (mw *MiddlewareWrapper) AttrNames() []string

AttrNames returns available attributes

func (*MiddlewareWrapper) Execute

func (mw *MiddlewareWrapper) Execute(req *Request, next NextFunc) *Response

Execute runs the middleware function

func (*MiddlewareWrapper) Freeze

func (mw *MiddlewareWrapper) Freeze()

Freeze makes the object immutable

func (*MiddlewareWrapper) Hash

func (mw *MiddlewareWrapper) Hash() (uint32, error)

Hash returns a hash value

func (*MiddlewareWrapper) String

func (mw *MiddlewareWrapper) String() string

String returns string representation

func (*MiddlewareWrapper) Truth

func (mw *MiddlewareWrapper) Truth() starlark.Bool

Truth returns the truth value

func (*MiddlewareWrapper) Type

func (mw *MiddlewareWrapper) Type() string

Type returns the Starlark type name

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module wraps the ConfigurableModule with specific functionality for web server

func NewModule

func NewModule() *Module

NewModule creates a new instance of Module with default configurations. This is the primary entry point for creating a web module that can be loaded into a Starlark environment. The module provides functions for creating HTTP servers, handling requests and responses, and managing web application lifecycle.

func (*Module) LoadModule

func (m *Module) LoadModule() starlet.ModuleLoader

LoadModule returns the Starlark module loader with web-specific functions. This method provides the complete set of web module functions that can be called from Starlark scripts, including server creation and response builders.

type NextFunc

type NextFunc func(*Request) *Response

NextFunc represents the next handler in the middleware chain

type PathMatcher

type PathMatcher struct{}

PathMatcher provides unified path matching functionality using sophisticated algorithms. This utility consolidates all path matching logic in the web package and provides consistent path matching behavior across the module.

func NewPathMatcher

func NewPathMatcher() *PathMatcher

NewPathMatcher creates a new PathMatcher instance.

func (*PathMatcher) ExtractParams

func (pm *PathMatcher) ExtractParams(requestPath, pattern string) map[string]string

ExtractParams extracts path parameters from a request path using a parameter pattern. Returns a map of parameter names to values, or nil if the pattern doesn't match.

func (*PathMatcher) IsValidPattern

func (pm *PathMatcher) IsValidPattern(pattern string) bool

IsValidPattern checks if a pattern is valid for path matching. This validates the pattern syntax and ensures it's properly formatted.

func (*PathMatcher) MatchesAny

func (pm *PathMatcher) MatchesAny(requestPath string, patterns []string) bool

MatchesAny checks if a path matches any of the given patterns. This is useful for middleware that needs to apply to multiple patterns.

func (*PathMatcher) MatchesPattern

func (pm *PathMatcher) MatchesPattern(requestPath, pattern string) bool

MatchesPattern checks if a path matches a glob-like pattern. This method supports various pattern types: - Exact matches: "/api/users" matches "/api/users" exactly - Glob patterns: "/api/*" matches "/api/users", "/api/posts", etc. - Prefix patterns: "/api/admin/*" matches "/api/admin/users", "/api/admin/posts", etc. - Parameter patterns: "/users/{id}" matches "/users/123", "/users/abc", etc.

The method leverages Gin's internal path matching algorithm for consistency with the main router's behavior.

func (*PathMatcher) NormalizePath

func (pm *PathMatcher) NormalizePath(inputPath string) string

NormalizePath normalizes a path by cleaning it and ensuring it has proper format. This uses Go's standard path.Clean function for consistency.

type RateLimitStorage

type RateLimitStorage interface {
	Get(key string) (int, error)
	Set(key string, value int, ttl time.Duration) error
	Increment(key string, ttl time.Duration) (int, error)
}

RateLimitStorage interface for rate limiting storage backends

type Request

type Request struct {
	Method   string                 `json:"method"`
	URL      string                 `json:"url"`
	Path     string                 `json:"path"`
	Host     string                 `json:"host"`
	Remote   string                 `json:"remote"`
	ClientIP string                 `json:"client_ip"`
	Proto    string                 `json:"proto"`
	Headers  map[string]string      `json:"headers"`
	Query    map[string]string      `json:"query"`
	Context  map[string]interface{} `json:"context"`
	// contains filtered or unexported fields
}

Request represents an HTTP request. This structure holds the complete request data including method, URL, headers, query parameters, and provides access to the underlying gin context for advanced request processing.

type RequestWrapper

type RequestWrapper struct {
	// contains filtered or unexported fields
}

RequestWrapper wraps the Request struct to provide Starlark-compatible interface. This wrapper exposes request properties and methods to Starlark scripts, allowing access to request data, headers, parameters, and body content.

func NewRequestWrapper

func NewRequestWrapper(request *Request) *RequestWrapper

NewRequestWrapper creates a new RequestWrapper. This function wraps a Request to make it accessible from Starlark with proper attribute access and method calls.

func (*RequestWrapper) Attr

func (rw *RequestWrapper) Attr(name string) (starlark.Value, error)

Attr returns the value of a request attribute. This method provides access to request properties and methods from Starlark.

func (*RequestWrapper) AttrNames

func (rw *RequestWrapper) AttrNames() []string

AttrNames returns the list of available attributes.

func (*RequestWrapper) Freeze

func (rw *RequestWrapper) Freeze()

Freeze makes the request immutable (required by Starlark).

func (*RequestWrapper) Hash

func (rw *RequestWrapper) Hash() (uint32, error)

Hash returns a hash of the request (not supported).

func (*RequestWrapper) String

func (rw *RequestWrapper) String() string

String returns a string representation of the request.

func (*RequestWrapper) Truth

func (rw *RequestWrapper) Truth() starlark.Bool

Truth returns the truth value of the request (always true).

func (*RequestWrapper) Type

func (rw *RequestWrapper) Type() string

Type returns the Starlark type name.

type Response

type Response struct {
	StatusCode int               `json:"status_code"`
	Headers    map[string]string `json:"headers"`
	Body       string            `json:"body"`
	FilePath   string            `json:"file_path,omitempty"`
}

Response represents an HTTP response. This structure holds the complete response data including status code, headers, body content, and optional file path for file responses.

type ResponseWrapper

type ResponseWrapper struct {
	// contains filtered or unexported fields
}

ResponseWrapper wraps the Response struct to provide Starlark-compatible interface. This wrapper exposes response properties and methods to Starlark scripts, allowing manipulation of cookies and access to response metadata.

func NewResponseWrapper

func NewResponseWrapper(response *Response) *ResponseWrapper

NewResponseWrapper creates a new ResponseWrapper. This function wraps a Response to make it accessible from Starlark with proper attribute access and method calls.

func (*ResponseWrapper) Attr

func (rw *ResponseWrapper) Attr(name string) (starlark.Value, error)

Attr returns the value of the specified attribute

func (*ResponseWrapper) AttrNames

func (rw *ResponseWrapper) AttrNames() []string

AttrNames returns the list of available attributes

func (*ResponseWrapper) Freeze

func (rw *ResponseWrapper) Freeze()

Freeze marks the response as frozen (immutable)

func (*ResponseWrapper) Hash

func (rw *ResponseWrapper) Hash() (uint32, error)

Hash returns the hash of the response (not supported)

func (*ResponseWrapper) SetField

func (rw *ResponseWrapper) SetField(name string, value starlark.Value) error

SetField sets the value of the specified field

func (*ResponseWrapper) String

func (rw *ResponseWrapper) String() string

String returns the string representation of the response

func (*ResponseWrapper) Truth

func (rw *ResponseWrapper) Truth() starlark.Bool

Truth returns the truth value of the response

func (*ResponseWrapper) Type

func (rw *ResponseWrapper) Type() string

Type returns the type name for Starlark

type RouteGroup

type RouteGroup struct {
	// contains filtered or unexported fields
}

RouteGroup represents a group of routes with a common prefix. This structure provides a way to organize related routes together and apply common middleware or configuration to them.

func (*RouteGroup) Delete

func (rg *RouteGroup) Delete(path string, handler starlark.Callable) error

func (*RouteGroup) Get

func (rg *RouteGroup) Get(path string, handler starlark.Callable) error

HTTP method handlers for RouteGroup

func (*RouteGroup) Head

func (rg *RouteGroup) Head(path string, handler starlark.Callable) error

func (*RouteGroup) Options

func (rg *RouteGroup) Options(path string, handler starlark.Callable) error

func (*RouteGroup) Patch

func (rg *RouteGroup) Patch(path string, handler starlark.Callable) error

func (*RouteGroup) Post

func (rg *RouteGroup) Post(path string, handler starlark.Callable) error

func (*RouteGroup) Put

func (rg *RouteGroup) Put(path string, handler starlark.Callable) error

func (*RouteGroup) RegisterRoute

func (rg *RouteGroup) RegisterRoute(method HTTPMethod, path string, handler gin.HandlerFunc) error

RegisterRoute implements RouteRegistrar for RouteGroup

type RouteGroupWrapper

type RouteGroupWrapper struct {
	// contains filtered or unexported fields
}

RouteGroupWrapper wraps the RouteGroup struct to provide Starlark-compatible method names. This wrapper exposes route group methods to Starlark scripts with lowercase names that match the expected API conventions.

func NewRouteGroupWrapper

func NewRouteGroupWrapper(group *RouteGroup) *RouteGroupWrapper

NewRouteGroupWrapper creates a new RouteGroupWrapper with initialized method map

func (*RouteGroupWrapper) Attr

func (rgw *RouteGroupWrapper) Attr(name string) (starlark.Value, error)

Attr returns the value of the named attribute using efficient map lookup.

func (*RouteGroupWrapper) AttrNames

func (rgw *RouteGroupWrapper) AttrNames() []string

AttrNames returns the names of all attributes.

func (*RouteGroupWrapper) Freeze

func (rgw *RouteGroupWrapper) Freeze()

Freeze makes this object immutable.

func (*RouteGroupWrapper) Hash

func (rgw *RouteGroupWrapper) Hash() (uint32, error)

Hash returns a hash value for this object.

func (*RouteGroupWrapper) String

func (rgw *RouteGroupWrapper) String() string

String returns a string representation of the RouteGroupWrapper.

func (*RouteGroupWrapper) Truth

func (rgw *RouteGroupWrapper) Truth() starlark.Bool

Truth returns the truth value of this object.

func (*RouteGroupWrapper) Type

func (rgw *RouteGroupWrapper) Type() string

Type returns the Starlark type name for this object.

type RouteRegistrar

type RouteRegistrar interface {
	RegisterRoute(method HTTPMethod, path string, handler gin.HandlerFunc) error
}

RouteRegistrar defines the interface for registering routes

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server represents an HTTP server instance

func (*Server) Delete

func (s *Server) Delete(path string, handler starlark.Callable) error

func (*Server) Get

func (s *Server) Get(path string, handler starlark.Callable) error

HTTP method handlers for Server

func (*Server) Group

func (s *Server) Group(prefix string) *RouteGroup

Group creates a route group. This method creates a new route group with the specified prefix, allowing for organized route registration and middleware application to related endpoints.

func (*Server) Head

func (s *Server) Head(path string, handler starlark.Callable) error

func (*Server) IsRunning

func (s *Server) IsRunning() bool

IsRunning returns whether the server is running

func (*Server) Options

func (s *Server) Options(path string, handler starlark.Callable) error

func (*Server) Patch

func (s *Server) Patch(path string, handler starlark.Callable) error

func (*Server) Post

func (s *Server) Post(path string, handler starlark.Callable) error

func (*Server) Put

func (s *Server) Put(path string, handler starlark.Callable) error

func (*Server) RegisterRoute

func (s *Server) RegisterRoute(method HTTPMethod, path string, handler gin.HandlerFunc) error

RegisterRoute implements RouteRegistrar for Server

func (*Server) Route

func (s *Server) Route(methods interface{}, path string, handler starlark.Callable) error

Route adds a route with specific method(s). This method accepts either a single method string or a list of method strings, allowing the same handler to respond to multiple HTTP methods on the same path.

func (*Server) Run

func (s *Server) Run() error

Run starts the server and blocks. This method starts the HTTP server and blocks the current thread until the server is stopped or encounters an error, suitable for simple applications.

func (*Server) Start

func (s *Server) Start() error

Start starts the server in a goroutine. This method begins listening for HTTP requests on the configured host and port without blocking the current thread, allowing for asynchronous server operation.

func (*Server) Stop

func (s *Server) Stop() error

Stop stops the server

type ServerWrapper

type ServerWrapper struct {
	// contains filtered or unexported fields
}

ServerWrapper wraps the Server struct to provide Starlark-compatible method names

func NewServerWrapper

func NewServerWrapper(server *Server) *ServerWrapper

NewServerWrapper creates a new ServerWrapper with initialized method maps

func (*ServerWrapper) Attr

func (sw *ServerWrapper) Attr(name string) (starlark.Value, error)

func (*ServerWrapper) AttrNames

func (sw *ServerWrapper) AttrNames() []string

func (*ServerWrapper) Freeze

func (sw *ServerWrapper) Freeze()

func (*ServerWrapper) Hash

func (sw *ServerWrapper) Hash() (uint32, error)

func (*ServerWrapper) String

func (sw *ServerWrapper) String() string

func (*ServerWrapper) Truth

func (sw *ServerWrapper) Truth() starlark.Bool

func (*ServerWrapper) Type

func (sw *ServerWrapper) Type() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL