Hi,
For a web site behind Nginx we use fastcgi_pass to pass the requests to a Go fgci.serve(…).
All is right but we often have error messages writing to a closed network connection :
"template: searchResults.html:1:1632: executing \"body\" at <</div><div id=\"csite...>: use of closed network connection"
In order to use a http.CloseNotifier, we need to use a http.serve instead of fcgi.serve and so we use Nginx proxy_pass instead of fastcgi_pass.
Our problem now is that "r.URL.Host", where "r" is an "http.Request" pointer, is always empty and so all the web page are 404 because the "gorilla mux" router does not match any routes.
We also have the error message "http: multiple response.WriteHeader calls" which does not appear with fcgi.
Here a simplified version of our Nginx configuration for development environment :
upstream http_upstream_dev {
server 127.0.0.1:9001;
keepalive 50;
}
server {
listen 8081;
server_name .*dev.csite;
client_max_body_size 5M;
add_header Access-Control-Allow-Origin "http://csite.cdn.local:8081";
charset utf-8;
access_log /var/log/nginx/csite_access.log;
error_log /var/log/nginx/csite_error.log warn;
location / {
proxy_redirect off;
proxy_buffering off;
proxy_pass_request_headers on;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_set_header Referer $http_referer;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Raw-Url $scheme://$http_host$request_uri;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Nginx-Proxy true;
proxy_pass http://http_upstream_dev;
}
}
The go server is loaded as this, in a goagain environment :
l, err = net.Listen("tcp", ":"+strconv.Itoa(theApp.Config.Const.PORT))
[…]
http.Serve(l, theApp)
where theApp is an instance of a App struct :
type App struct {
[…]
Router *mux.Router
[…]
}
func (app *App) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer func() {
if reco := recover(); reco != nil {
app.NewHttpError(w, r, "¡¡ PANIC RECOVERY !!\n", reco)
}
}()
fmt.Printf("Host=`%s`\n", r.URL.Host)
app.Router.ServeHTTP(w, r)
}
and "app.Router" is a "gorilla/mux.Router" pointer.
After reading tons of post about Go web app behind Nginx using proxy_pass, we can not solve the problem of empty host without adding the ugly code r.URL, err = r.URL.Parse(r.Header.Get("X-Raw-Url")) before "app.Router.ServeHTTP(w, r)" and we have no solution for the "multiple response.WriteHeader calls" error.
Can someone help us, please ?