SlyMarbo / spdy

[deprecated] A full-featured SPDY library for the Go language.
BSD 2-Clause "Simplified" License
116 stars 13 forks source link

Tying spdy to httptest #49

Closed rnapier closed 10 years ago

rnapier commented 10 years ago

I've been trying to create some unit tests so I can more easily reproduce the race conditions. I'm having a bit of trouble getting spdy to use SPDY when in an httptest server.

This test case works, but it runs over HTTPS. I haven't been able to convince it to run under SPDY (so I'm not testing the code I want to test).

I tried adding NextProtos: []string{"spdy/3.1"} to the tls.Config, which seems part of the answer, but I then get "spdy3_conn.go:1018: Error: Encountered error: "Error: Field \"flags\" recieved invalid data 47, expecting 1." (*spdy.invalidField)". Adding the same thing to server doesn't improve things.

It's failing at transport.go:227:

        if !state.NegotiatedProtocolIsMutual {

At this point, state.NegotiatedProtocol is spdy/3.1, but NegotiatedProtocolIsMutual is false.

Given spdy's design, this feels like it should be pretty straightforward, so I'm not sure if I'm missing something simple or there's a bug.

I based all of this on the http package's tests.

package spdy_test

import (
    "crypto/tls"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/http/httptest"
    "strings"
    "testing"

    "github.com/SlyMarbo/spdy"
)

func init() {
    spdy.EnableDebugOutput()
}

func TestClient(t *testing.T) {
    ts := httptest.NewUnstartedServer(robotsTxtHandler)
    defer ts.Close()

    srv := &http.Server{
        Handler: robotsTxtHandler,
        TLSConfig: &tls.Config{
            NextProtos: []string{"spdy/3.1"},
        },
    }
    ts.Config = srv
    spdy.AddSPDY(srv)
    ts.StartTLS()

    tr := spdy.Transport{
        TLSClientConfig: &tls.Config{
            InsecureSkipVerify: true,
    }
    client := http.Client{Transport: &tr}

    r, err := client.Get(ts.URL)
    var b []byte
    if err == nil {
        b, err = ioutil.ReadAll(r.Body)
        r.Body.Close()
    }
    if err != nil {
        t.Error(err)
    } else if s := string(b); !strings.HasPrefix(s, "User-agent:") {
        t.Errorf("Incorrect page body (did not begin with User-agent): %q", s)
    }
}

var robotsTxtHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Last-Modified", "sometime")
    fmt.Fprintf(w, "User-agent: go\nDisallow: /something/")
})
SlyMarbo commented 10 years ago

I'm afraid I'm very busy at the moment and won't be free to do any development for several days. I'll get on this as soon as I can, though.

rnapier commented 10 years ago

Thanks. I'm currently pursuing other approaches that don't require httptest.

On Wed, May 28, 2014 at 12:23 PM, Jamie Hall notifications@github.comwrote:

I'm afraid I'm very busy at the moment and won't be free to do any development for several days. I'll get on this as soon as I can, though.

— Reply to this email directly or view it on GitHubhttps://github.com/SlyMarbo/spdy/issues/49#issuecomment-44430675 .

Rob Napier -- Software and Security Consulting Cocoaphony blog -- http://robnapier.net/blog iOS Programming Pushing the Limits -- http://robnapier.net/book