feat: Add CORS support to HeroServer
- Add `cors_enabled` and `allowed_origins` fields to `ServerArgs` - Add `cors_enabled` and `allowed_origins` to `HeroServerConfig` - Configure VEB CORS middleware when `cors_enabled` is true - Update `new` function to accept `cors_enabled` and `allowed_origins` - Add `cors_enabled` and `allowed_origins` to `HeroServer` struct
This commit is contained in:
@@ -7,9 +7,14 @@ import time
|
||||
fn main() {
|
||||
// Start the server in a background thread with authentication disabled for testing
|
||||
spawn fn () {
|
||||
rpc.start(port: 8080, auth_enabled: false) or {
|
||||
panic('Failed to start HeroModels server: ${err}')
|
||||
}
|
||||
rpc.start(
|
||||
port: 8080
|
||||
auth_enabled: false // Disable auth for testing
|
||||
cors_enabled: true
|
||||
allowed_origins: [
|
||||
'http://localhost:5173',
|
||||
]
|
||||
) or { panic('Failed to start HeroModels server: ${err}') }
|
||||
}()
|
||||
|
||||
// Keep the main thread alive
|
||||
|
||||
@@ -74,11 +74,19 @@ pub mut:
|
||||
port int = 8080
|
||||
host string = 'localhost'
|
||||
auth_enabled bool = true
|
||||
cors_enabled bool = true
|
||||
allowed_origins []string = ['*'] // Default allows all origins
|
||||
}
|
||||
|
||||
pub fn start(args ServerArgs) ! {
|
||||
// Create a new heroserver instance
|
||||
mut server := heroserver.new(port: args.port, host: args.host, auth_enabled: args.auth_enabled)!
|
||||
mut server := heroserver.new(
|
||||
port: args.port
|
||||
host: args.host
|
||||
auth_enabled: args.auth_enabled
|
||||
cors_enabled: args.cors_enabled
|
||||
allowed_origins: args.allowed_origins
|
||||
)!
|
||||
|
||||
// Create and register the heromodels handler
|
||||
handler := new_heromodels_handler()!
|
||||
|
||||
@@ -8,7 +8,7 @@ import veb
|
||||
// Create a new HeroServer instance
|
||||
pub fn new(config HeroServerConfig) !&HeroServer {
|
||||
// Initialize crypto client
|
||||
mut crypto_client := if c := config.crypto_client {
|
||||
crypto_client := if c := config.crypto_client {
|
||||
c
|
||||
} else {
|
||||
herocrypt.new_default()!
|
||||
@@ -22,6 +22,8 @@ pub fn new(config HeroServerConfig) !&HeroServer {
|
||||
handlers: map[string]&openrpc.Handler{}
|
||||
challenges: map[string]AuthChallenge{}
|
||||
auth_enabled: config.auth_enabled
|
||||
cors_enabled: config.cors_enabled
|
||||
allowed_origins: config.allowed_origins.clone()
|
||||
}
|
||||
|
||||
console.print_header('HeroServer created on port ${server.port}')
|
||||
@@ -36,19 +38,25 @@ pub fn (mut server HeroServer) register_handler(handler_type string, handler &op
|
||||
|
||||
// Start the server
|
||||
pub fn (mut server HeroServer) start() ! {
|
||||
// Configure CORS if enabled
|
||||
if server.cors_enabled {
|
||||
console.print_item('CORS enabled for origins: ${server.allowed_origins}')
|
||||
server.use(veb.cors[Context](veb.CorsOptions{
|
||||
origins: server.allowed_origins
|
||||
allowed_methods: [.get, .head, .patch, .put, .post, .delete, .options]
|
||||
allowed_headers: ['Content-Type', 'Authorization', 'X-Requested-With']
|
||||
allow_credentials: true
|
||||
}))
|
||||
}
|
||||
|
||||
// Start VEB server
|
||||
handler_name := server.handlers.keys()[0]
|
||||
console.print_green('Server starting on http://${server.host}:${server.port}')
|
||||
console.print_green('HTML Homepage: http://${server.host}:${server.port}/')
|
||||
console.print_green('JSON Info: http://${server.host}:${server.port}/json/${handler_name}')
|
||||
console.print_green('Documentation: http://${server.host}:${server.port}/doc/${handler_name}')
|
||||
console.print_green('Markdown Docs: http://${server.host}:${server.port}/md/${handler_name}')
|
||||
console.print_green('API Endpoint: http://${server.host}:${server.port}/api/${handler_name}')
|
||||
console.print_item('Server starting on http://${server.host}:${server.port}')
|
||||
console.print_item('HTML Homepage: http://${server.host}:${server.port}/')
|
||||
console.print_item('JSON Info: http://${server.host}:${server.port}/json/${handler_name}')
|
||||
console.print_item('Documentation: http://${server.host}:${server.port}/doc/${handler_name}')
|
||||
console.print_item('Markdown Docs: http://${server.host}:${server.port}/md/${handler_name}')
|
||||
console.print_item('API Endpoint: http://${server.host}:${server.port}/api/${handler_name}')
|
||||
|
||||
veb.run[HeroServer, Context](mut server, server.port)
|
||||
}
|
||||
|
||||
// Context struct for VEB
|
||||
pub struct Context {
|
||||
veb.Context
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ module heroserver
|
||||
import freeflowuniverse.herolib.crypt.herocrypt
|
||||
import freeflowuniverse.herolib.schemas.openrpc
|
||||
import time
|
||||
import veb
|
||||
|
||||
// Main server configuration
|
||||
@[params]
|
||||
@@ -11,12 +12,16 @@ pub mut:
|
||||
port int = 9977
|
||||
host string = 'localhost'
|
||||
auth_enabled bool = true // Whether to enable authentication
|
||||
// CORS configuration
|
||||
cors_enabled bool = true // Whether to enable CORS
|
||||
allowed_origins []string = ['*'] // Allowed origins for CORS, default allows all
|
||||
// Optional crypto client, will create default if not provided
|
||||
crypto_client ?&herocrypt.HeroCrypt
|
||||
}
|
||||
|
||||
// Main server struct
|
||||
pub struct HeroServer {
|
||||
veb.Middleware[Context]
|
||||
mut:
|
||||
port int
|
||||
host string
|
||||
@@ -24,6 +29,8 @@ mut:
|
||||
sessions map[string]Session // sessionkey -> Session
|
||||
handlers map[string]&openrpc.Handler // handlertype -> handler
|
||||
challenges map[string]AuthChallenge
|
||||
cors_enabled bool
|
||||
allowed_origins []string
|
||||
pub mut:
|
||||
auth_enabled bool = true // Whether authentication is required
|
||||
}
|
||||
@@ -157,3 +164,8 @@ pub:
|
||||
body string
|
||||
description string
|
||||
}
|
||||
|
||||
// Context struct for VEB
|
||||
pub struct Context {
|
||||
veb.Context
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ HeroServer is a secure web server built in V, designed for public key-based auth
|
||||
- **OpenRPC Integration**: Serve APIs defined with the OpenRPC specification.
|
||||
- **Automatic Documentation**: Generates HTML documentation from your OpenRPC schemas.
|
||||
- **Session Management**: Manages authenticated user sessions.
|
||||
- **CORS Support**: Configurable Cross-Origin Resource Sharing for frontend integration.
|
||||
- **Extensible**: Register multiple, independent handlers for different API groups.
|
||||
|
||||
## Usage
|
||||
@@ -17,8 +18,12 @@ import freeflowuniverse.herolib.hero.heroserver
|
||||
import freeflowuniverse.herolib.schemas.openrpc
|
||||
|
||||
fn main() {
|
||||
// 1. Create a new server instance
|
||||
mut server := heroserver.new(port: 8080)!
|
||||
// 1. Create a new server instance with CORS support
|
||||
mut server := heroserver.new(
|
||||
port: 8080
|
||||
cors_enabled: true
|
||||
allowed_origins: ['http://localhost:5173'] // Frontend dev server
|
||||
)!
|
||||
|
||||
// 2. Create and register your OpenRPC handlers
|
||||
// These handlers must conform to the `openrpc.OpenRPCHandler` interface.
|
||||
|
||||
Reference in New Issue
Block a user