It is because every incoming request is routed to your HelloWorld()
handler function, and the browser makes multiple calls under the hood, specifically to /favicon.ico
.
And since your web server does not send back a valid favicon, it will request it again when you refresh the page in the browser.
Try it with Chrome: open the Developer tools (CTRL+SHIFT+I), and choose the “Network” tab. Hit refresh, and you will see 2 new entries:
Name Status Type
--------------------------------------------------------
localhost 200 document
favicon.ico 200 text/plain
Since your counter starts with 0
(default value for type int
), you increment it once and you send back 1
. Then the request for favicon.ico
increments it again (2
), but the result is not displayed. Then if you refresh, it gets incremented again to 3
and you send that back, etc.
Also note that multiple goroutines can serve requests concurrently, so your solution has a race. You should synchronize access to the calls
variable, or use the sync/atomic
package to increment the counter safely, for example:
var calls int64
func HelloWorld(w http.ResponseWriter, r *http.Request) {
count := atomic.AddInt64(&calls, 1)
fmt.Fprintf(w, "You've called me %d times", count)
}
A simple “fix” to achieve what you want would be to check the request path, and if it is not the root "https://stackoverflow.com/"
, don’t increment, e.g.:
func HelloWorld(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "https://stackoverflow.com/" {
return
}
count := atomic.AddInt64(&calls, 1)
fmt.Fprintf(w, "You've called me %d times", count)
}
You may also choose to only exclude requests for favicon.ico
, e.g.:
if r.URL.Path == "/favicon.ico" {
return
}