About HTTP and the importance of Close()

Go, the so called system language from Google (I have checked the performances against C++, go loses.), has some very comfortable features dealing with http. When a strong type language is required, which now is more often then not, I found myself drawn to it. It is simple, compile very fast (one of the points where it beats C++ with ease). Go has both simple http client and server. They both have the same comfort level that Node js has, with far better performances, data sharing, and actual multithreading (Go uses frames, but this goes beyond the scope of this post).

To open a simple get connection to a server, we can just do this:

resp, err := http.Get(address)

where resp is the response object. We can get the status code, and also the body of the request, by using

resp.Body

Server side

Server side is not much harder.

first we need a function (or more) to server content to the client:

func handler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/text; charset=UTF-8")
  fmt.Fprintf(w, "Hello world!")
}

Then we just start the server with that function:

listening_port:=3000
http.HandleFunc("/", handler)
http.ListenAndServe(fmt.Sprintf(":%d", listening_port), nil)

In both cases, client and server, there is a serious bug: the body is not being closed.

Now this code will work, the only question is, how long. Sooner or later, a socket limit error is going to show it's face, and the program will crash. This error happens quite a bit. The usual suggestion is to increase the file limit (Linux), which will solve it, for a little while, till the new limit is met.

So what the body has to do with that? well, the body is a stream object, io.ReadCloser to be exact, and it will not pull all the content for you and just store it in a buffer. There might be a lot of it, and you might don't want to do that. Therefore, once a body was received, it must be closed.

defer to the help

Luckily enough, go has a defer keyword, which will execute a command for you upon function exit, thus relieves you from figuring out exactly where to close the Body.

here is the correct function version:

func handler(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "text/text; charset=UTF-8") 
 fmt.Fprintf(w, "Hello world!") 
 r.Body.Close()
}

note that here, defer was not needed. you should also call body.Close on the client side as well.

resp, err := http.Get(address)
	if err != nil {
}else{        
	defer resp.Body.Close()
}

 

Installing light ide for go

The new google go language has a nice IDE to program with, light IDE.

The download link is here: http://sourceforge.net/projects/liteide/

Once untared, you might go in to an issue where the program seems to start and immediately dies (in Linux). That qt's doing. remove any library (lib folder) that has qt in it's name, and you should be done.