add a SetQuicHeaders function to h2quic.Server

fixes #156
This commit is contained in:
Lucas Clemente
2016-05-31 15:38:21 +02:00
parent ae778fc042
commit a7afffe700
4 changed files with 86 additions and 0 deletions

View File

@@ -3,6 +3,7 @@ package h2quic
import (
"crypto/tls"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
@@ -26,6 +27,8 @@ type Server struct {
// Private flag for demo, do not use
CloseAfterFirstRequest bool
port int
}
// ListenAndServe listens on the UDP address s.Addr and calls s.Handler to handle HTTP/2 requests on incoming connections.
@@ -142,11 +145,36 @@ func (s *Server) handleRequest(session streamCreator, headerStream utils.Stream,
return nil
}
// Close the server
func (s *Server) Close() error {
// TODO: implement
return nil
}
// SetQuicHeaders can be used to set the proper headers that announce that this server supports QUIC.
// The values that are set depend on the port information from s.Server.Addr, and currently look like this (if Addr has port 443):
// Alternate-Protocol: 443:quic
// Alt-Svc: quic=":443"; ma=2592000; v="33,32,31,30"
func (s *Server) SetQuicHeaders(hdr http.Header) error {
if s.port == 0 {
// Extract port from s.Server.Addr
_, portStr, err := net.SplitHostPort(s.Server.Addr)
if err != nil {
return err
}
port, err := net.LookupPort("tcp", portStr)
if err != nil {
return err
}
s.port = port
}
hdr.Add("Alternate-Protocol", fmt.Sprintf("%d:quic", s.port))
hdr.Add("Alt-Svc", fmt.Sprintf(`quic=":%d"; ma=2592000; v="%s"`, s.port, protocol.SupportedVersionsAsString))
return nil
}
// ListenAndServeQUIC listens on the UDP network address addr and calls the
// handler for HTTP/2 requests on incoming conections. http.DefaultServeMux is
// used when handler is nil.

View File

@@ -157,4 +157,47 @@ var _ = Describe("H2 server", func() {
Server{}.Serve(nil)
}).To(Panic())
})
Context("setting http headers", func() {
expected := http.Header{
"Alt-Svc": {`quic=":443"; ma=2592000; v="33,32,31,30"`},
"Alternate-Protocol": {`443:quic`},
}
It("sets proper headers with numeric port", func() {
s.Server.Addr = ":443"
hdr := http.Header{}
err := s.SetQuicHeaders(hdr)
Expect(err).NotTo(HaveOccurred())
Expect(hdr).To(Equal(expected))
})
It("sets proper headers with full addr", func() {
s.Server.Addr = "127.0.0.1:443"
hdr := http.Header{}
err := s.SetQuicHeaders(hdr)
Expect(err).NotTo(HaveOccurred())
Expect(hdr).To(Equal(expected))
})
It("sets proper headers with string port", func() {
s.Server.Addr = ":https"
hdr := http.Header{}
err := s.SetQuicHeaders(hdr)
Expect(err).NotTo(HaveOccurred())
Expect(hdr).To(Equal(expected))
})
It("works multiple times", func() {
s.Server.Addr = ":https"
hdr := http.Header{}
err := s.SetQuicHeaders(hdr)
Expect(err).NotTo(HaveOccurred())
Expect(hdr).To(Equal(expected))
hdr = http.Header{}
err = s.SetQuicHeaders(hdr)
Expect(err).NotTo(HaveOccurred())
Expect(hdr).To(Equal(expected))
})
})
})

View File

@@ -3,6 +3,7 @@ package protocol
import (
"bytes"
"encoding/binary"
"strconv"
)
// VersionNumber is a version number as int
@@ -16,6 +17,9 @@ var SupportedVersions = []VersionNumber{
// SupportedVersionsAsTags is needed for the SHLO crypto message
var SupportedVersionsAsTags []byte
// SupportedVersionsAsString is needed for the Alt-Scv HTTP header
var SupportedVersionsAsString string
// VersionNumberToTag maps version numbers ('32') to tags ('Q032')
func VersionNumberToTag(vn VersionNumber) uint32 {
v := uint32(vn)
@@ -45,4 +49,11 @@ func init() {
b.Write(s)
}
SupportedVersionsAsTags = b.Bytes()
for i := len(SupportedVersions) - 1; i >= 0; i-- {
SupportedVersionsAsString += strconv.Itoa(int(SupportedVersions[i]))
if i != 0 {
SupportedVersionsAsString += ","
}
}
}

View File

@@ -22,6 +22,10 @@ var _ = Describe("Version", func() {
Expect(protocol.SupportedVersionsAsTags).To(Equal([]byte("Q030Q031Q032Q033")))
})
It("has proper version list", func() {
Expect(protocol.SupportedVersionsAsString).To(Equal("33,32,31,30"))
})
It("recognizes supported versions", func() {
Expect(protocol.IsSupportedVersion(0)).To(BeFalse())
Expect(protocol.IsSupportedVersion(protocol.SupportedVersions[0])).To(BeTrue())