Hello golang-nuts!

I have some code that creates a short-lived HTTP server, and I'm trying to 
write tests for it.  I'm hitting a case where HTTP handlers seem to stick 
around even though I'm creating a brand new `http.ServeMux`, `http.Server`, 
and `net.Listener` objects.  How do I get rid of old handlers?

Here's a semi-simple reproducible case:

package main

import (
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"strconv"
"time"
)

// Some state so we can show the old handler is in effect...
type Foo struct {
SomeVar int
}

func (f *Foo) Serve(addr string) (net.Listener, error) {
l, err := net.Listen("tcp", addr)
if err != nil {
return nil, err
}
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("In handler wrapper, f = %p\n", f)
w.Write([]byte(strconv.Itoa(f.SomeVar)))
})
srv := &http.Server{
Handler: mux,
}

go srv.Serve(l)
return l, nil
}

func main() {
f1 := &Foo{SomeVar: 1}
f2 := &Foo{SomeVar: 2}

l, err := f1.Serve("0.0.0.0:8090")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(doRequest())
l.Close()
// Ok it didn't actually close, wait a bit or it'll show the address as
// already in use...
time.Sleep(1 * time.Second)

l, err = f2.Serve("0.0.0.0:8090")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(doRequest())
l.Close()
}

func doRequest() string {
client := &http.Client{}
req, _ := http.NewRequest("GET", "http://0.0.0.0:8090";, nil)
resp, _ := client.Do(req)
bytes, _ := ioutil.ReadAll(resp.Body)
return string(bytes)
}

Output:

$ go run main.go
In handler wrapper, f = 0xc42000d200
1
In handler wrapper, f = 0xc42000d200
1

Note the pointer to the method receiver is the same in both cases, 
indicating the old ServeMux is still handling the new request... (boy did 
it take me a long time to figure out what was going on in a non-trivial 
codebase...)

What's happening here?  Is the old http.Server still "attached" to the 
tcp.Listener?  What can I do to fix this?

Thanks so much!

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to