func (c *conn) serveSmart() { defer func() { if err := recover(); err != nil { const size = 4096 buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] log.Printf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf) } if !c.hijacked() { c.close() } }() if tlsConn, ok := c.rwc.(*tls.Conn); ok { if d := c.server.ReadTimeout; d != 0 { c.rwc.SetReadDeadline(time.Now().Add(d)) } if d := c.server.WriteTimeout; d != 0 { c.rwc.SetWriteDeadline(time.Now().Add(d)) } if err := tlsConn.Handshake(); err != nil { return } c.tlsState = new(tls.ConnectionState) *c.tlsState = tlsConn.ConnectionState() if proto := c.tlsState.NegotiatedProtocol; validNPN(proto) { if fn := c.server.TLSNextProto[proto]; fn != nil { h := initNPNRequest{tlsConn, serverHandler{c.server}} fn(c.server, tlsConn, h) } return } } initial_bytes := make([]byte, start_bytes) // add smart detection n, err := c.rwc.Read(initial_bytes) if err != nil || n != start_bytes { return } if checkspdy(initial_bytes) { s := c.server z := new(http.Server) z.Addr = s.Addr z.Handler = s.inner_h z.ReadTimeout = s.ReadTimeout z.WriteTimeout = s.WriteTimeout z.MaxHeaderBytes = s.MaxHeaderBytes server_session := spdy.NewServerSession(NewSmartConn(c.rwc, initial_bytes), z) server_session.Serve() return } c2, err := c.server.newConn(NewSmartConn(c.rwc, initial_bytes)) if err != nil { return } c2.serve() }
func main() { root := flag.String("r", "./testdata", "root of the directory to serve") spdy_debug := flag.Bool("s", false, "enable SPDY debug output") flag.Parse() if *spdy_debug { // enable spdy debug messages spdy.EnableDebug() } for { const SLEEP_RETRY = 5 var conn *tls.Conn var err error for i := 0; i < 10; i++ { // connect to P. conn, err = tls.Dial("tcp", HOST_PORT, &tls.Config{InsecureSkipVerify: true}) if err != nil { time.Sleep(100 * time.Millisecond) } else { break } } if conn == nil { log.Println("Failed to connect. Waiting", SLEEP_RETRY, "seconds.") time.Sleep(SLEEP_RETRY * time.Second) continue } // build the request buf := new(bytes.Buffer) _, err = buf.WriteString("Hello from C") handle(err) req, err := http.NewRequest("PUT", "https://"+HOST_PORT, buf) handle(err) // make the client connection client := httputil.NewClientConn(conn, nil) res, err := client.Do(req) if err != nil { log.Println("Error: Failed to make connection to P:", err) continue } buf.Reset() _, err = io.Copy(buf, res.Body) handle(err) fmt.Printf("%q from P: %q.\n", res.Status, buf.String()) c, _ := client.Hijack() conn = c.(*tls.Conn) server := new(http.Server) server.Handler = &handler{data: nil, rt: *root} //http.FileServer(http.Dir(*root)) session := spdy.NewServerSession(conn, server) session.Serve() } }
func nextproto3(s *Server, c *tls.Conn, h Handler) { z := new(http.Server) z.Addr = s.Addr z.Handler = s.inner_h z.ReadTimeout = s.ReadTimeout z.WriteTimeout = s.WriteTimeout z.MaxHeaderBytes = s.MaxHeaderBytes if z.Handler == nil { z.Handler = http.DefaultServeMux } server_session := spdy.NewServerSession(c, z) server_session.Serve() }