keep fastcgi connection open

This commit is contained in:
Echsecutor 2016-09-01 10:53:44 +02:00
parent a122304196
commit 05d7ae88fa
2 changed files with 25 additions and 8 deletions

View file

@ -16,6 +16,9 @@ import (
"github.com/mholt/caddy/caddyhttp/httpserver" "github.com/mholt/caddy/caddyhttp/httpserver"
) )
// for persistent fastcgi connections
var persistent_connections map[string]*FCGIClient
// Handler is a middleware type that can handle requests as a FastCGI client. // Handler is a middleware type that can handle requests as a FastCGI client.
type Handler struct { type Handler struct {
Next httpserver.Handler Next httpserver.Handler
@ -73,10 +76,23 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
// Connect to FastCGI gateway // Connect to FastCGI gateway
network, address := rule.parseAddress() network, address := rule.parseAddress()
fcgiBackend, err := Dial(network, address)
// re use connection, if possible
if persistent_connections == nil{
persistent_connections = make(map[string]*FCGIClient)
}
fcgiBackend, ok := persistent_connections[network+address]
// otherwise dial:
if(!ok || fcgiBackend == nil){
var err error
persistent_connections[network+address], err = Dial(network, address)
if err != nil { if err != nil {
return http.StatusBadGateway, err return http.StatusBadGateway, err
} }
fcgiBackend = persistent_connections[network+address]
}
var resp *http.Response var resp *http.Response
contentLength, _ := strconv.Atoi(r.Header.Get("Content-Length")) contentLength, _ := strconv.Atoi(r.Header.Get("Content-Length"))
@ -91,11 +107,10 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
resp, err = fcgiBackend.Post(env, r.Method, r.Header.Get("Content-Type"), r.Body, contentLength) resp, err = fcgiBackend.Post(env, r.Method, r.Header.Get("Content-Type"), r.Body, contentLength)
} }
if resp.Body != nil {
defer resp.Body.Close()
}
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
persistent_connections[network+address].Close()
persistent_connections[network+address] = nil
return http.StatusBadGateway, err return http.StatusBadGateway, err
} }
@ -112,6 +127,8 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
if fcgiBackend.stderr.Len() != 0 { if fcgiBackend.stderr.Len() != 0 {
// Remove trailing newline, error logger already does this. // Remove trailing newline, error logger already does this.
err = LogError(strings.TrimSuffix(fcgiBackend.stderr.String(), "\n")) err = LogError(strings.TrimSuffix(fcgiBackend.stderr.String(), "\n"))
persistent_connections[network+address].Close()
persistent_connections[network+address] = nil
} }
// Normally we would return the status code if it is an error status (>= 400), // Normally we would return the status code if it is an error status (>= 400),

View file

@ -385,7 +385,7 @@ func (w *streamReader) Read(p []byte) (n int, err error) {
// Do made the request and returns a io.Reader that translates the data read // Do made the request and returns a io.Reader that translates the data read
// from fcgi responder out of fcgi packet before returning it. // from fcgi responder out of fcgi packet before returning it.
func (c *FCGIClient) Do(p map[string]string, req io.Reader) (r io.Reader, err error) { func (c *FCGIClient) Do(p map[string]string, req io.Reader) (r io.Reader, err error) {
err = c.writeBeginRequest(uint16(Responder), 0) err = c.writeBeginRequest(uint16(Responder), FCGIKeepConn)
if err != nil { if err != nil {
return return
} }