sending server response to a client by w responseWriter

368 views
Skip to first unread message

RS

unread,
Oct 7, 2021, 7:12:31 AM10/7/21
to golang-nuts
Best practice in following scenario:

In my func for an endpoint (handler) with  func hello(w http.ResponseWriter, req *http.Request) 
I call another server get the resp.Body (Body io.ReadCloser) and want to write this Body  in w (ResponseWriter ).
What is best practice?
I have already copied directly Body to w via io.Copy. 
I want but make sure that the whole body is sent to client. 
With io.Copy I am not sure if this is guaranteed. 
And I would like to set status to 500 in case io.Copy returns err. 

Could you please help me on this?


Axel Wagner

unread,
Oct 7, 2021, 7:29:46 AM10/7/21
to RS, golang-nuts
As I said in your last thread:
What you want is impossible, based on how HTTP works. The status of a request must be determined *before* any of the body is written. So, if writing the body fails, there is nothing more you can do - you can only ignore that. And it's not an abnormal condition for the writing of a body to fail, as clients may disconnect at any time.

The best you can do is
a) write the body to an in-memory buffer, to make sure all bytes that need to be written are correctly determined,
b) then set tany headers (e.g. content-type) and status as appropriate and
c) write out the body, ignoring any errors - or at best, increment a metric or logging it.

That is, IMO, the best you can do with HTTP. There is no guarantee the body can be written, before you try do it and you can't set the status after you start writing the body. But if the actual *Write* fails (as opposed to the Read part of an io.Copy) you can at least be reasonably sure that the problem is some network issue or client disconnect you can't do anything about, so it's fine to ignore (from an application perspective).

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/5f0e7131-2625-452d-9861-51f5e42345d8n%40googlegroups.com.

RiSi

unread,
Oct 7, 2021, 7:42:33 AM10/7/21
to Axel Wagner, golang-nuts
w.Header().Set("Content-Type", "application/xml")
_, err:=io.Copy(w,src) 
if err!=nil{
re := &res{ Message: "Error happened",}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(599) //sample status code
err = json.NewEncoder(w).Encode(re)

}//if

the part after err!=nil should be removed?

RiSi

unread,
Oct 7, 2021, 7:43:54 AM10/7/21
to Axel Wagner, golang-nuts
if error happens by io.Copy, can I set the status Code of w after io.Copy?

Axel Wagner

unread,
Oct 7, 2021, 8:07:19 AM10/7/21
to RiSi, golang-nuts
 On Thu, Oct 7, 2021 at 1:43 PM RiSi <a0r...@gmail.com> wrote:
if error happens by io.Copy, can I set the status Code of w after io.Copy?

No. io.Copy might have already written parts of the body. You can't set the status after parts of the body have been written.
Reply all
Reply to author
Forward
0 new messages