Documentation ¶
Overview ¶
Package spdy is a full-featured SPDY library for the Go language (still under very active development).
Note that this implementation currently supports SPDY drafts 2 and 3, and support for SPDY/4, and HTTP/2.0 is upcoming.
See examples for various simple examples that use the package.
-------------------------------
Note that using this package with Martini (https://github.com/go-martini/martini) is likely to result in strange and hard-to-diagnose bugs. For more information, read http://stephensearles.com/?p=254. As a result, issues that arise when combining the two should be directed at the Martini developers.
-------------------------------
Servers
The following examples use features specific to SPDY.
Just the handler is shown.
Use SPDY's pinging features to test the connection:
package main import ( "net/http" "time" "github.com/SlyMarbo/spdy" ) func Serve(w http.ResponseWriter, r *http.Request) { // Ping returns a channel which will send a bool. if ping, err := spdy.PingClient(w); err == nil { select { case _, ok := <- ping: if ok { // Connection is fine. } else { // Something went wrong. } case <-time.After(timeout): // Ping took too long. } } else { // Not SPDY. } // ... }
Sending a server push:
package main import ( "net/http" "github.com/SlyMarbo/spdy" ) func Serve(w http.ResponseWriter, r *http.Request) { // Push returns a separate http.ResponseWriter and an error. path := r.URL.Scheme + "://" + r.URL.Host + "/example.js" push, err := spdy.Push(path) if err != nil { // Not using SPDY. } http.ServeFile(push, r, "./content/example.js") // Note that a PushStream must be finished manually once // all writing has finished. push.Finish() // ... }
Index ¶
- Constants
- func AddSPDY(srv *http.Server)
- func ConnectAndServe(addr string, config *tls.Config, srv *http.Server) error
- func DisableSpdyVersion(v float64) error
- func EnableDebugOutput()
- func EnableSpdyVersion(v float64) error
- func GetPriority(w http.ResponseWriter) (int, error)
- func ListenAndServeSPDYNoNPN(addr string, certFile string, keyFile string, handler http.Handler, ...) error
- func ListenAndServeSpdyOnly(addr string, certFile string, keyFile string, handler http.Handler) error
- func ListenAndServeTLS(addr string, certFile string, keyFile string, handler http.Handler) error
- func NewClient(insecureSkipVerify bool) *http.Client
- func NewClientConn(conn net.Conn, push common.Receiver, version, subversion int) (common.Conn, error)
- func NewServerConn(conn net.Conn, server *http.Server, version, subversion int) (common.Conn, error)
- func PingClient(w http.ResponseWriter) (<-chan bool, error)
- func PingServer(c http.Client, server string) (<-chan bool, error)
- func ProxyConnections(handler ProxyConnHandler) http.Handler
- func Push(w http.ResponseWriter, url string) (common.PushStream, error)
- func SPDYversion(w http.ResponseWriter) float64
- func SetDebugLogger(l *logging.Logger)
- func SetDebugOutput(w io.Writer)
- func SetFlowControl(w http.ResponseWriter, f common.FlowControl) error
- func SetLogOutput(w io.Writer)
- func SetLogger(l *logging.Logger)
- func SetMaxBenignErrors(n int)
- func SupportedVersion(v float64) bool
- func SupportedVersions() []float64
- func UsingSPDY(w http.ResponseWriter) bool
- type Compressor
- type Conn
- type Decompressor
- type Pinger
- type PriorityStream
- type ProxyConnHandler
- type ProxyConnHandlerFunc
- type Pusher
- type SetFlowController
- type Stream
- type Transport
Constants ¶
const DEFAULT_SPDY_VERSION = 3.1
SPDY version of this implementation.
Variables ¶
This section is empty.
Functions ¶
func ConnectAndServe ¶
ConnectAndServe is used to perform connection reversal. (See Connect() for more details.)
This works very similarly to ListenAndServeTLS, except that addr and config are used to connect to the client. If srv is nil, a new http.Server is used, with http.DefaultServeMux as the handler.
func DisableSpdyVersion ¶
DisableSpdyVersion can be used to disable support for the given SPDY version. This process can be undone by using EnableSpdyVersion.
func EnableDebugOutput ¶
func EnableDebugOutput()
EnableDebugOutput sets the output for the package's debug info logger to os.Stdout.
func EnableSpdyVersion ¶
EnableSpdyVersion can re-enable support for versions of SPDY that have been disabled by DisableSpdyVersion.
func GetPriority ¶
func GetPriority(w http.ResponseWriter) (int, error)
GetPriority is used to identify the request priority of the given stream. This can be used to manually enforce stream priority, although this is already performed by the library. If the underlying connection is using HTTP, and not SPDY, GetPriority will return the ErrNotSPDY error.
A simple example of finding a stream's priority is:
import ( "github.com/SlyMarbo/spdy" "log" "net/http" ) func httpHandler(w http.ResponseWriter, r *http.Request) { priority, err := spdy.GetPriority(w) if err != nil { // Non-SPDY connection. } else { log.Println(priority) } } func main() { http.HandleFunc("/", httpHandler) log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/") err := spdy.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil) if err != nil { log.Fatal(err) } }
func ListenAndServeSPDYNoNPN ¶
func ListenAndServeSPDYNoNPN(addr string, certFile string, keyFile string, handler http.Handler, version, subversion int) error
ListenAndServeSPDYNoNPN creates a server that listens exclusively for SPDY and (unlike the rest of the package) will not support HTTPS.
func ListenAndServeSpdyOnly ¶
func ListenAndServeSpdyOnly(addr string, certFile string, keyFile string, handler http.Handler) error
ListenAndServeSpdyOnly listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections. Handler is typically nil, in which case the DefaultServeMux is used. Additionally, files containing a certificate and matching private key for the server must be provided. If the certificate is signed by a certificate authority, the certFile should be the concatenation of the server's certificate followed by the CA's certificate.
IMPORTANT NOTE: Unlike spdy.ListenAndServeTLS, this function will ONLY serve SPDY. HTTPS requests are refused.
See examples/spdy_only_server/server.go for a simple example server.
func ListenAndServeTLS ¶
ListenAndServeTLS listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections. Handler is typically nil, in which case the DefaultServeMux is used. Additionally, files containing a certificate and matching private key for the server must be provided. If the certificate is signed by a certificate authority, the certFile should be the concatenation of the server's certificate followed by the CA's certificate.
See examples/server/server.go for a simple example server.
func NewClientConn ¶
func NewClientConn(conn net.Conn, push common.Receiver, version, subversion int) (common.Conn, error)
NewClientConn is used to create a SPDY connection, using the given net.Conn for the underlying connection, and the given Receiver to receive server pushes.
func NewServerConn ¶
func NewServerConn(conn net.Conn, server *http.Server, version, subversion int) (common.Conn, error)
NewServerConn is used to create a SPDY connection, using the given net.Conn for the underlying connection, and the given http.Server to configure the request serving.
func PingClient ¶
func PingClient(w http.ResponseWriter) (<-chan bool, error)
PingClient is used to send PINGs with SPDY servers. PingClient takes a ResponseWriter and returns a channel on which a spdy.Ping will be sent when the PING response is received. If the channel is closed before a spdy.Ping has been sent, this indicates that the PING was unsuccessful.
If the underlying connection is using HTTP, and not SPDY, PingClient will return the ErrNotSPDY error.
A simple example of sending a ping is:
import ( "github.com/SlyMarbo/spdy" "log" "net/http" ) func httpHandler(w http.ResponseWriter, req *http.Request) { ping, err := spdy.PingClient(w) if err != nil { // Non-SPDY connection. } else { resp, ok <- ping if ok { // Ping was successful. } } } func main() { http.HandleFunc("/", httpHandler) log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/") err := spdy.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil) if err != nil { log.Fatal(err) } }
func PingServer ¶
PingServer is used to send PINGs with http.Clients using. SPDY. PingServer takes a ResponseWriter and returns a channel onwhich a spdy.Ping will be sent when the PING response is received. If the channel is closed before a spdy.Ping has been sent, this indicates that the PING was unsuccessful.
If the underlying connection is using HTTP, and not SPDY, PingServer will return the ErrNotSPDY error.
If an underlying connection has not been made to the given server, PingServer will return the ErrNotConnected error.
A simple example of sending a ping is:
import ( "github.com/SlyMarbo/spdy" "net/http" ) func main() { resp, err := http.Get("https://example.com/") // ... ping, err := spdy.PingServer(http.DefaultClient, "https://example.com") if err != nil { // No SPDY connection. } else { resp, ok <- ping if ok { // Ping was successful. } } }
func ProxyConnections ¶
func ProxyConnections(handler ProxyConnHandler) http.Handler
ProxyConnections is used with ConnectAndServe in connection- reversing proxies. This returns an http.Handler which will call handler each time a client connects. The call is treated as an event loop and the connection may be terminated if the call returns. The returned Handler should then be used in a normal HTTP server, like the following:
package main import ( "net/http" "github.com/SlyMarbo/spdy" ) func handleProxy(conn spdy.Conn) { // make requests... } func main() { handler := spdy.ProxyConnHandlerFunc(handleProxy) http.Handle("/", spdy.ProxyConnections(handler)) http.ListenAndServeTLS(":80", "cert.pem", "key.pem", nil) }
Use Conn.Request to make requests to the client and Conn.Conn to access the underlying connection for further details like the client's address.
func Push ¶
func Push(w http.ResponseWriter, url string) (common.PushStream, error)
Push is used to send server pushes with SPDY servers. Push takes a ResponseWriter and the url of the resource being pushed, and returns a ResponseWriter to which the push should be written.
If the underlying connection is using HTTP, and not SPDY, Push will return the ErrNotSPDY error.
A simple example of pushing a file is:
import ( "github.com/SlyMarbo/spdy" "log" "net/http" ) func httpHandler(w http.ResponseWriter, r *http.Request) { path := r.URL.Scheme + "://" + r.URL.Host + "/javascript.js" push, err := spdy.Push(w, path) if err != nil { // Non-SPDY connection. } else { http.ServeFile(push, r, "./javascript.js") // Push the given file. push.Finish() // Finish the stream once used. } } func main() { http.HandleFunc("/", httpHandler) log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/") err := spdy.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil) if err != nil { log.Fatal(err) } }
func SPDYversion ¶
func SPDYversion(w http.ResponseWriter) float64
SPDYversion returns the SPDY version being used in the underlying connection used by the given http.ResponseWriter. This is 0 for connections not using SPDY.
func SetDebugLogger ¶
SetDebugLogger sets the package's debug info logger.
func SetDebugOutput ¶
SetDebugOutput sets the output for the package's debug info logger.
func SetFlowControl ¶
func SetFlowControl(w http.ResponseWriter, f common.FlowControl) error
SetFlowControl can be used to set the flow control mechanism on the underlying SPDY connection.
func SetLogOutput ¶
SetLogOutput sets the output for the package's error logger.
func SetMaxBenignErrors ¶
func SetMaxBenignErrors(n int)
SetMaxBenignErrors is used to modify the maximum number of minor errors each connection will allow without ending the session.
By default, the value is set to 0, disabling checks and allowing minor errors to go unchecked, although they will still be reported to the debug logger. If it is important that no errors go unchecked, such as when testing another implementation, SetMaxBenignErrors with 1 or higher.
func SupportedVersion ¶
SupportedVersion determines if the provided SPDY version is supported by this instance of the library. This can be modified with EnableSpdyVersion and DisableSpdyVersion.
func SupportedVersions ¶
func SupportedVersions() []float64
SupportedVersions will return a slice of supported SPDY versions. The returned versions are sorted into order of most recent first.
func UsingSPDY ¶
func UsingSPDY(w http.ResponseWriter) bool
UsingSPDY indicates whether a given ResponseWriter is using SPDY.
Types ¶
type Compressor ¶
Compressor is used to compress the text header of a SPDY frame.
type Conn ¶
type Conn interface { http.CloseNotifier Close() error Conn() net.Conn Request(request *http.Request, receiver common.Receiver, priority common.Priority) (common.Stream, error) RequestResponse(request *http.Request, receiver common.Receiver, priority common.Priority) (*http.Response, error) Run() error }
Connection represents a SPDY connection. The connection should be started with a call to Run, which will return once the connection has been terminated. The connection can be ended early by using Close.
type Decompressor ¶
Decompressor is used to decompress the text header of a SPDY frame.
type PriorityStream ¶
type PriorityStream interface { Stream // Priority returns the stream's // priority. Priority() common.Priority }
PriorityStream represents a SPDY stream with a priority.
type ProxyConnHandler ¶
type ProxyConnHandler interface {
ProxyConnHandle(Conn)
}
type ProxyConnHandlerFunc ¶
type ProxyConnHandlerFunc func(Conn)
func (ProxyConnHandlerFunc) ProxyConnHandle ¶
func (p ProxyConnHandlerFunc) ProxyConnHandle(c Conn)
type SetFlowController ¶
type SetFlowController interface {
SetFlowControl(common.FlowControl)
}
SetFlowController represents a connection which can have its flow control mechanism customised.
type Stream ¶
type Stream interface { http.CloseNotifier http.ResponseWriter Close() error Conn() common.Conn ReceiveFrame(common.Frame) error Run() error State() *common.StreamState StreamID() common.StreamID }
Stream contains a single SPDY stream.
type Transport ¶
type Transport struct { // Proxy specifies a function to return a proxy for a given // Request. If the function returns a non-nil error, the // request is aborted with the provided error. // If Proxy is nil or returns a nil *URL, no proxy is used. Proxy func(*http.Request) (*url.URL, error) // Dial specifies the dial function for creating TCP // connections. // If Dial is nil, net.Dial is used. Dial func(network, addr string) (net.Conn, error) // TODO: use // TLSClientConfig specifies the TLS configuration to use with // tls.Client. If nil, the default configuration is used. TLSClientConfig *tls.Config // DisableKeepAlives, if true, prevents re-use of TCP connections // between different HTTP requests. DisableKeepAlives bool // DisableCompression, if true, prevents the Transport from // requesting compression with an "Accept-Encoding: gzip" // request header when the Request contains no existing // Accept-Encoding value. If the Transport requests gzip on // its own and gets a gzipped response, it's transparently // decoded in the Response.Body. However, if the user // explicitly requested gzip it is not automatically // uncompressed. DisableCompression bool // MaxIdleConnsPerHost, if non-zero, controls the maximum idle // (keep-alive) to keep per-host. If zero, // DefaultMaxIdleConnsPerHost is used. MaxIdleConnsPerHost int // ResponseHeaderTimeout, if non-zero, specifies the amount of // time to wait for a server's response headers after fully // writing the request (including its body, if any). This // time does not include the time to read the response body. ResponseHeaderTimeout time.Duration // Priority is used to determine the request priority of SPDY // requests. If nil, spdy.DefaultPriority is used. Priority func(*url.URL) common.Priority // Receiver is used to receive the server's response. If left // nil, the default Receiver will parse and create a normal // Response. Receiver common.Receiver // PushReceiver is used to receive server pushes. If left nil, // pushes will be refused. The provided Request will be that // sent with the server push. See Receiver for more detail on // its methods. PushReceiver common.Receiver // contains filtered or unexported fields }
A Transport is an HTTP/SPDY http.RoundTripper.
func NewTransport ¶
NewTransport gives a simple initialised Transport.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package common contains shared functionality for the spdy package.
|
Package common contains shared functionality for the spdy package. |
examples
|
|
Package spdy2 contains functionality for SPDY/2.
|
Package spdy2 contains functionality for SPDY/2. |
frames
Package frames contains an implementation of the SPDY/2 frames.
|
Package frames contains an implementation of the SPDY/2 frames. |
Package spdy3 contains functionality for SPDY/3.
|
Package spdy3 contains functionality for SPDY/3. |
frames
Package frames contains an implementation of the SPDY/3 frames.
|
Package frames contains an implementation of the SPDY/3 frames. |