-2

I have this little server here. The intent is that if I visit localhost:8000/* it should increase counter by 1, and if I go to localhost:8000/count, it should show me the current number of counter.

A weird thing happening is that it seems like every time I visit localhost:8000, the counter goes up by 3. So I'd go to localhost:8000/count and the counter would be at 3, and then I visit localhost:8000, and then localhost:8000/count again, counter would now be at 6. Why does that happen? Is there something weird with net/http?

Also, why is it that when I refresh localhost:8000/count, the count goes up 1 by 1? The counter func doesn't increment count, yet count still goes up - why is that? Does handler get added to the localhost:8000/count route as well?

package main

import (
        "fmt"
        "log"
        "net/http"
        "sync"
)

var mu sync.Mutex
var count int

func main() {
        http.HandleFunc("/", handler)
        http.HandleFunc("/count", counter)
        log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

// handler echoes the Path component of the requested URL.
func handler(w http.ResponseWriter, r *http.Request) {
        mu.Lock()
        count++
        mu.Unlock()
        fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
}

// counter echoes the number of calls so far.
func counter(w http.ResponseWriter, r *http.Request) {
        mu.Lock()
        fmt.Fprintf(w, "Count %d\n", count)
        mu.Unlock()
}
Julien Chien
  • 2,052
  • 4
  • 16
  • 32

2 Answers2

3

The extra requests are your browser trying to access /favicon.ico

You can see this, for example, if you print the http.Request to stdout in your handler funcs.

LemurFromTheId
  • 4,061
  • 1
  • 15
  • 15
  • Ok. I'm logging it and this is what I found: each time my browser hits the url it also requests a favicon, like you @aedolon and @simo said. Also, it seems for `localhost:8000/count", `handler` and `counter` are both hit. Interesting stuff. – Julien Chien Mar 15 '16 at 08:15
  • Your browser likely (different browsers may behave differently) tries to grab favicon also when accessing /count, but favicon requests are all handled by `handler`, because "/" is the best and only match for "/favicon.ico". – LemurFromTheId Mar 15 '16 at 08:19
  • @LeibnizMan: again, check all the urls that are hit when you load the "/count" page. Maybe your browser sends extra requests. The amount and repetition of requests for favicon.ico depends on your browser and how it caches stuff : on my PC (firefox - linux), I only see the `+3` step on the first page load ; after that, the counter is incremented "as expected". – LeGEC Mar 15 '16 at 08:21
1

The issue is that your handler is serving extra static content like favicon and such. If you log the request, you'll see your browser is probably also requesting /favicon.ico, which is being passed to that same handler.

To serve static content one way is to create your own ServeMux:

package main

import (
    "fmt"
    "net/http"
    "strings"
)   

var chttp = http.NewServeMux()

func main() {

    chttp.Handle("/", http.FileServer(http.Dir("./")))

    http.HandleFunc("/", HomeHandler) // homepage
    http.ListenAndServe(":8080", nil)
}   

func HomeHandler(w http.ResponseWriter, r *http.Request) {

    if (strings.Contains(r.URL.Path, ".")) {
        chttp.ServeHTTP(w, r)
    } else {
        fmt.Fprintf(w, "HomeHandler")
    }   
} 

Serve homepage and static content from root

Community
  • 1
  • 1
Endre Simo
  • 11,330
  • 2
  • 40
  • 49
  • Thanks for the answer. I accepted @Aedolon's because he was the first - but you're equally right as far as I can tell :D – Julien Chien Mar 15 '16 at 08:15