fix static file serving
This commit is contained in:
parent
4ceca8d289
commit
88c9bd90af
@ -208,74 +208,89 @@ func WaitForServers() {
|
|||||||
func handleRequest(ctx *fasthttp.RequestCtx) {
|
func handleRequest(ctx *fasthttp.RequestCtx) {
|
||||||
path := string(ctx.Path())
|
path := string(ctx.Path())
|
||||||
|
|
||||||
// Check static handlers first
|
// Fast path for likely static files (has extension)
|
||||||
staticMu.RLock()
|
if isLikelyStaticFile(path) && tryStaticHandler(ctx, path) {
|
||||||
for prefix, fs := range staticHandlers {
|
return
|
||||||
if strings.HasPrefix(path, prefix) {
|
|
||||||
staticMu.RUnlock()
|
|
||||||
// Remove prefix and serve
|
|
||||||
ctx.Request.URI().SetPath(strings.TrimPrefix(path, prefix))
|
|
||||||
fs.NewRequestHandler()(ctx)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
staticMu.RUnlock()
|
|
||||||
|
|
||||||
// Fall back to Lua handling
|
// Try Lua routing
|
||||||
globalMu.RLock()
|
globalMu.RLock()
|
||||||
pool := globalWorkerPool
|
pool := globalWorkerPool
|
||||||
globalMu.RUnlock()
|
globalMu.RUnlock()
|
||||||
|
|
||||||
if pool == nil {
|
if pool != nil {
|
||||||
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
worker := pool.Get()
|
||||||
ctx.SetBodyString("Worker pool not initialized")
|
if worker != nil {
|
||||||
|
defer pool.Put(worker)
|
||||||
|
|
||||||
|
req := GetRequest()
|
||||||
|
defer PutRequest(req)
|
||||||
|
|
||||||
|
resp := GetResponse()
|
||||||
|
defer PutResponse(resp)
|
||||||
|
|
||||||
|
// Populate request
|
||||||
|
req.Method = string(ctx.Method())
|
||||||
|
req.Path = path
|
||||||
|
req.Body = string(ctx.Request.Body())
|
||||||
|
|
||||||
|
ctx.QueryArgs().VisitAll(func(key, value []byte) {
|
||||||
|
req.Query[string(key)] = string(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx.Request.Header.VisitAll(func(key, value []byte) {
|
||||||
|
req.Headers[string(key)] = string(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
err := worker.HandleRequest(req, resp)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
||||||
|
ctx.SetBodyString(fmt.Sprintf("Internal Server Error: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If Lua found a route, use it
|
||||||
|
if resp.StatusCode != 404 {
|
||||||
|
ctx.SetStatusCode(resp.StatusCode)
|
||||||
|
for key, value := range resp.Headers {
|
||||||
|
ctx.Response.Header.Set(key, value)
|
||||||
|
}
|
||||||
|
if resp.Body != "" {
|
||||||
|
ctx.SetBodyString(resp.Body)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lua 404, try static handlers if not already checked
|
||||||
|
if !isLikelyStaticFile(path) && tryStaticHandler(ctx, path) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
worker := pool.Get()
|
ctx.SetStatusCode(fasthttp.StatusNotFound)
|
||||||
defer pool.Put(worker)
|
ctx.SetBodyString("Not Found")
|
||||||
|
}
|
||||||
|
|
||||||
if worker == nil {
|
func tryStaticHandler(ctx *fasthttp.RequestCtx, path string) bool {
|
||||||
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
staticMu.RLock()
|
||||||
ctx.SetBodyString("No worker available")
|
defer staticMu.RUnlock()
|
||||||
return
|
|
||||||
|
for prefix, fs := range staticHandlers {
|
||||||
|
if strings.HasPrefix(path, prefix) {
|
||||||
|
ctx.Request.URI().SetPath(strings.TrimPrefix(path, prefix))
|
||||||
|
fs.NewRequestHandler()(ctx)
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
req := GetRequest()
|
func isLikelyStaticFile(path string) bool {
|
||||||
defer PutRequest(req)
|
// Check for file extension
|
||||||
|
lastSlash := strings.LastIndex(path, "/")
|
||||||
resp := GetResponse()
|
lastDot := strings.LastIndex(path, ".")
|
||||||
defer PutResponse(resp)
|
return lastDot > lastSlash && lastDot != -1
|
||||||
|
|
||||||
// Populate request
|
|
||||||
req.Method = string(ctx.Method())
|
|
||||||
req.Path = string(ctx.Path())
|
|
||||||
req.Body = string(ctx.Request.Body())
|
|
||||||
|
|
||||||
ctx.QueryArgs().VisitAll(func(key, value []byte) {
|
|
||||||
req.Query[string(key)] = string(value)
|
|
||||||
})
|
|
||||||
|
|
||||||
ctx.Request.Header.VisitAll(func(key, value []byte) {
|
|
||||||
req.Headers[string(key)] = string(value)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Let Lua handle everything
|
|
||||||
err := worker.HandleRequest(req, resp)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SetStatusCode(fasthttp.StatusInternalServerError)
|
|
||||||
ctx.SetBodyString(fmt.Sprintf("Internal Server Error: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply response
|
|
||||||
ctx.SetStatusCode(resp.StatusCode)
|
|
||||||
for key, value := range resp.Headers {
|
|
||||||
ctx.Response.Header.Set(key, value)
|
|
||||||
}
|
|
||||||
if resp.Body != "" {
|
|
||||||
ctx.SetBodyString(resp.Body)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterStaticHandler adds a static file handler
|
// RegisterStaticHandler adds a static file handler
|
||||||
|
Loading…
x
Reference in New Issue
Block a user