Repository: go
Issue: net/http: go server behind nginx require read entire body before writing response
Labels: help wanted,NeedsInvestigation

### What version of Go are you using (`go version`)?
go version go1.9.1 windows/amd64

### Does this issue reproduce with the latest release?
YES

### What operating system and processor architecture are you using (`go env`)?
set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=E:\Documents\Develop\WorkSpace\Go
set GORACE=
set GOROOT=E:\Documents\Develop\RunTime\Go\x64
set GOTOOLDIR=E:\Documents\Develop\RunTime\Go\x64\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=D:\CommonSoft\MSYS2\tmp\go-build716063943=/tmp/go-build -gno-record-gcc-switches
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config


### What did you do?
1. Start Go Server
````
package main

import (
	"log"
	"net/http"
)

func main() {
	MockServer()
}

func MockServer() {
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		w.WriteHeader(400)
		w.Write([]byte("HELLO"))
	})
	log.Fatal(http.ListenAndServe(":8080", nil))
}
````
2. Start nginx
nginx.conf
````
upstream nodes {
        server 127.0.0.1:8080 max_fails=0;
}
server {
        listen 80;
        server_name ~.*;

        access_log logs/access.log main;
        error_log logs/error.log;

        client_max_body_size 1024m;
        client_body_buffer_size 512K;
        proxy_next_upstream error timeout non_idempotent;
        client_body_temp_path   client_body_temp_path 3 2;
        location / {
                proxy_http_version 1.1;
                proxy_pass http://nodes;
                break;
        }
}
````
3. Make A POST Request
````
package main

import (
	"bytes"
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"
)

func main() {
	resp, err := http.Post("http://127.0.0.1:80", "application/octet-stream", bytes.NewReader(make([]byte, 1024*1024)))
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	respBuf, err := httputil.DumpResponse(resp, true)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(respBuf))
}
````


### What did you expect to see?
Response:
````
HTTP/1.1 400 Bad Request
Content-Length: 5
Connection: keep-alive
Content-Type: text/plain; charset=utf-8
Date: Wed, 11 Oct 2017 04:16:07 GMT
Server: nginx/1.13.0

HELLO
````

### What did you see instead?
Resp:
````
HTTP/1.1 502 Bad Gateway
Content-Length: 173
Connection: keep-alive
Content-Type: text/html
Date: Wed, 11 Oct 2017 04:02:37 GMT
Server: nginx/1.13.0

<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.13.0</center>
</body>
````
Nginx Error:
````
2017/10/11 12:02:37 [error] 11956#2392: *49 WSASend() failed (10054: An existing connection was forcibly closed by the remote host) while sending request to upstream, client: 127.0.0.1, server: ~.*, request: "POST / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "127.0.0.1:80"
````

If i send request without body or the server side read all the body, response will be as expected.
It seems golang should ensure that a FIN packet is sent before any RST packet.
https://trac.nginx.org/nginx/ticket/1037