Created a HTTP/2 client and server program using net/http Go library for streaming client and server request response. Taken the reference from code here #13444 (comment) .
Server code
func handle_stream_request(w http.ResponseWriter, r *http.Request) {
buf := make([]byte, 1024)
i := 0
for {
i = i + 1
if(i == 10){
break
}
len, _ := r.Body.Read(buf)
response_str := "Server ACK for: " + string(buf[:len])
w.Write([]byte(response_str))
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
}
}
Client Code
func send_stream_request(client *http.Client){
pr, pw := io.Pipe()
req, _ := http.NewRequest("PUT", "https://localhost:8000/", ioutil.NopCloser(pr))
var res *http.Response
go func() {
for {
time.Sleep(2 * time.Second)
s := "Client ping@" + get_time()
pw.Write([]byte(s))
if res != nil {
buf := make([]byte, 1024)
len, _ := res.Body.Read(buf)
log.Printf("Response is: %s", string(buf[:len]))
}
}
}()
go func() {
response, _ := client.Do(req)
res = response
log.Printf("\n Got: %#v", res)
}()
select {}
}
What did you expect to see?
After 10 requests from client the client program should exit successfully.
What did you see instead?
The client program blocks at writing at pipe “pw.Write([]byte(s))” after server has finished the handle function because there is no reader to read the data on pipe.
I am not able to understand how can I stop such client program from hanging. What signal does server send to client that request stream has been closed and it shouldn’t try to write more stuff on pipe.