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.
-------------------------------
Servers
Adding SPDY support to an existing Go server requires minimal work.
Modifying a simple example server like the following:
package main
import (
"net/http"
)
func Serve(w http.ResponseWriter, r *http.Request) {
// Remember not to add any headers after calling
// w.WriteHeader().
w.Write([]byte("Hello, HTTP!"))
}
func main() {
// Register handler.
http.HandleFunc("/", Serve)
err := http.ListenAndServeTLS("localhost:443", "cert.pem", "key.pem", nil)
if err != nil {
// handle error.
}
}
Simply requires the following changes:
package main
import (
"github.com/SlyMarbo/spdy" // Import SPDY.
"net/http"
)
// This handler will now serve HTTP, HTTPS, and SPDY requests.
func Serve(w http.ResponseWriter, r *http.Request) {
// Remember not to add any headers after calling
// w.WriteHeader().
w.Write([]byte("Hello, HTTP!"))
}
func main() {
http.HandleFunc("/", Serve)
// Use spdy's ListenAndServe.
err := spdy.ListenAndServeTLS("localhost:443", "cert.pem", "key.pem", nil)
if err != nil {
// handle error.
}
}
A very simple file server for both SPDY and HTTPS:
package main
import (
"github.com/SlyMarbo/spdy"
"net/http"
)
func Serve(w http.ResponseWriter, r *http.Request) {
if spdy.UsingSPDY(w) {
// Using SPDY.
} else {
// Using HTTP(S).
}
http.ServeFile(w, r, "." + r.RequestURI)
}
func main() {
// Register handler.
http.HandleFunc("/", Serve)
err := spdy.ListenAndServeTLS("localhost:443", "cert.pem", "key.pem", nil)
if err != nil {
// handle error.
}
}
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 (
"github.com/SlyMarbo/spdy"
"net/http"
"time"
)
func Serve(w http.ResponseWriter, r *http.Request) {
// Ping returns a channel which will send a bool.
ping, err := spdy.PingClient(w)
if err != nil {
// Not using SPDY.
}
select {
case _, ok := <- ping:
if ok {
// Connection is fine.
} else {
// Something went wrong.
}
case <-time.After(timeout):
// Ping took too long.
}
// ...
}
Sending a server push:
package main
import (
"github.com/SlyMarbo/spdy"
"net/http"
)
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()
// ...
}
-------------------------------
Clients
The client API is even easier to use. Simply import the spdy package to add SPDY support. Here's a simple example that will fetch the requested page over HTTP, HTTPS, or SPDY, as necessary.
package main
import (
"fmt"
_ "github.com/SlyMarbo/spdy" // Simply import SPDY.
"io/ioutil"
"net/http"
)
func main() {
res, err := http.Get("https://example.com/") // http.Get (and .Post etc) can now use SPDY.
if err != nil {
// handle the error.
}
bytes, err := ioutil.ReadAll(res.Body)
if err != nil {
// handle the error.
}
res.Body.Close()
fmt.Printf("Received: %s\n", bytes)
}
To add SPDY support to your own client, just use the spdy package's Transport.
package main
import (
"github.com/SlyMarbo/spdy" // Import SPDY.
"net/http"
)
func main() {
client := new(http.Client)
client.Transport = new(spdy.Transport) // This client now supports HTTP, HTTPS, and SPDY.
// ...
}
Index ¶
- Constants
- Variables
- 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 ListenAndServeSPDY(addr string, certFile string, keyFile string, handler http.Handler) error
- func ListenAndServeSPDYNoNPN(addr string, certFile string, keyFile string, handler http.Handler, ...) error
- func ListenAndServeTLS(addr string, certFile string, keyFile string, handler http.Handler) error
- func PingClient(w http.ResponseWriter) (<-chan Ping, error)
- func PingServer(c http.Client, server string) (<-chan Ping, error)
- func ProxyConnections(handler ProxyConnHandler) http.Handler
- func SPDYversion(w http.ResponseWriter) float64
- func SetDebugLogger(l *logging.Logger)
- func SetDebugOutput(w io.Writer)
- func SetFlowControl(w http.ResponseWriter, f FlowControl) error
- func SetLogOutput(w io.Writer)
- func SetLogger(l *logging.Logger)
- func SupportedVersion(v float64) bool
- func SupportedVersions() []float64
- func UsingSPDY(w http.ResponseWriter) bool
- type Compressor
- type Conn
- type Decompressor
- type DefaultFlowControl
- type Flags
- type FlowControl
- type Frame
- type Ping
- type Priority
- type ProxyConnHandler
- type ProxyConnHandlerFunc
- type PushStream
- type Receiver
- type Setting
- type Settings
- type StatusCode
- type Stream
- type StreamID
- type StreamState
- func (s *StreamState) Close()
- func (s *StreamState) CloseHere()
- func (s *StreamState) CloseThere()
- func (s *StreamState) Closed() bool
- func (s *StreamState) ClosedHere() bool
- func (s *StreamState) ClosedThere() bool
- func (s *StreamState) Open() bool
- func (s *StreamState) OpenHere() bool
- func (s *StreamState) OpenThere() bool
- func (s *StreamState) String() string
- type Transport
Constants ¶
const ( SYN_STREAMv2 = 1 SYN_REPLYv2 = 2 RST_STREAMv2 = 3 SETTINGSv2 = 4 NOOPv2 = 5 PINGv2 = 6 GOAWAYv2 = 7 HEADERSv2 = 8 WINDOW_UPDATEv2 = 9 CONTROL_FRAMEv2 = -1 DATA_FRAMEv2 = -2 )
Frame types in SPDY/2
const ( SYN_STREAMv3 = 1 SYN_REPLYv3 = 2 RST_STREAMv3 = 3 SETTINGSv3 = 4 PINGv3 = 6 GOAWAYv3 = 7 HEADERSv3 = 8 WINDOW_UPDATEv3 = 9 CREDENTIALv3 = 10 CONTROL_FRAMEv3 = -1 DATA_FRAMEv3 = -2 )
Frame types in SPDY/3
const ( DATAv4 = 0 HEADERS_PRIORITYv4 = 1 RST_STREAMv4 = 3 SETTINGSv4 = 4 PUSH_PROMISEv4 = 5 PINGv4 = 6 GOAWAYv4 = 7 HEADERSv4 = 8 WINDOW_UPDATEv4 = 9 CREDENTIALv4 = 10 )
Frame types in SPDY/4 / HTTP/2.0
const ( FLAG_FIN = 1 FLAG_UNIDIRECTIONAL = 2 FLAG_SETTINGS_CLEAR_SETTINGS = 1 FLAG_SETTINGS_PERSIST_VALUE = 1 FLAG_SETTINGS_PERSISTED = 2 )
Flags
const ( RST_STREAM_PROTOCOL_ERROR = 1 RST_STREAM_INVALID_STREAM = 2 RST_STREAM_REFUSED_STREAM = 3 RST_STREAM_UNSUPPORTED_VERSION = 4 RST_STREAM_CANCEL = 5 RST_STREAM_INTERNAL_ERROR = 6 RST_STREAM_FLOW_CONTROL_ERROR = 7 RST_STREAM_STREAM_IN_USE = 8 RST_STREAM_STREAM_ALREADY_CLOSED = 9 RST_STREAM_INVALID_CREDENTIALS = 10 RST_STREAM_FRAME_TOO_LARGE = 11 )
RST_STREAM status codes
const ( GOAWAY_OK = 0 GOAWAY_PROTOCOL_ERROR = 1 GOAWAY_INTERNAL_ERROR = 2 GOAWAY_FLOW_CONTROL_ERROR = 3 )
GOAWAY status codes
const ( SETTINGS_UPLOAD_BANDWIDTH = 1 SETTINGS_DOWNLOAD_BANDWIDTH = 2 SETTINGS_ROUND_TRIP_TIME = 3 SETTINGS_MAX_CONCURRENT_STREAMS = 4 SETTINGS_CURRENT_CWND = 5 SETTINGS_DOWNLOAD_RETRANS_RATE = 6 SETTINGS_INITIAL_WINDOW_SIZE = 7 SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE = 8 )
Settings IDs
const DEFAULT_INITIAL_CLIENT_WINDOW_SIZE = 10485760
The default initial transfer window sent by the client.
const DEFAULT_INITIAL_WINDOW_SIZE = 65535
The default initial transfer window size, as defined in the spec.
const DEFAULT_SPDY_VERSION = 3.1
SPDY version of this implementation.
const DEFAULT_STREAM_LIMIT = 1000
The default maximum number of concurrent streams.
const MAX_DATA_SIZE = 0xffffff
const MAX_DELTA_WINDOW_SIZE = 0x7fffffff
Maximum delta window size field for WINDOW_UPDATE.
const MAX_FRAME_SIZE = 0xffffff
Maximum frame size (2 ** 24 -1).
const MAX_STREAM_ID = 0x7fffffff
Maximum stream ID (2 ** 31 -1).
const MAX_TRANSFER_WINDOW_SIZE = 0x80000000
Maximum number of bytes in the transfer window.
const NO_STREAM_LIMIT = 0x80000000
NO_STREAM_LIMIT can be used to disable the stream limit.
const SPDY4_CLIENT_CONNECTION_HEADER = "FOO * HTTP/2.0\r\n\r\nBA\r\n\r\n"
Header sent by the client to initiate the connection.
Variables ¶
var ( ErrGoaway = errors.New("Error: GOAWAY received.") ErrConnNil = errors.New("Error: Connection is nil.") ErrNoFlowControl = errors.New("Error: This connection does not use flow control.") ErrConnectFail = errors.New("Error: Failed to connect.") ErrInvalidVersion = errors.New("Error: Invalid SPDY version.") )
Important errors.
var ErrNotConnected = errors.New("Error: Not connected to given server.")
ErrNotConnected indicates that a SPDY-specific feature was attempted with a Client not connected to the given server.
var ErrNotSPDY = errors.New("Error: Not a SPDY connection.")
ErrNotSPDY indicates that a SPDY-specific feature was attempted with a ResponseWriter using a non-SPDY connection.
var HeaderDictionaryV2 = []byte{}/* 907 elements not displayed */
Compression header for SPDY/2
var HeaderDictionaryV3 = []byte{}/* 1423 elements not displayed */
Compression header for SPDY/3
var MaxBenignErrors = 0
MaxBenignErrors is the maximum number of minor errors each connection will allow without ending the session.
By default, MaxBenignErrors 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, set MaxBenignErrors to 1 or higher.
var VerboseLogging = false
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 ListenAndServeSPDY ¶
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.
IMPORTANT NOTE: Unlike spdy.ListenAndServeTLS, this function will ONLY serve SPDY. HTTPS requests are refused.
A trivial example server is:
import (
"github.com/SlyMarbo/spdy"
"log"
"net/http"
)
func httpHandler(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("This is an example server.\n"))
}
func main() {
http.HandleFunc("/", httpHandler)
log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
err := spdy.ListenAndServeSPDY(":10443", "cert.pem", "key.pem", nil)
if err != nil {
log.Fatal(err)
}
}
One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
func ListenAndServeSPDYNoNPN ¶
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.
A trivial example server is:
import (
"github.com/SlyMarbo/spdy"
"log"
"net/http"
)
func httpHandler(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("This is an example server.\n"))
}
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)
}
}
One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
func PingClient ¶
func PingClient(w http.ResponseWriter) (<-chan Ping, 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 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 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 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.
func NewCompressor ¶
func NewCompressor(version uint16) Compressor
NewCompressor is used to create a new compressor. It takes the SPDY version to use.
type Conn ¶
type Conn interface {
http.CloseNotifier
io.Closer
Conn() net.Conn
InitialWindowSize() (uint32, error)
Ping() (<-chan Ping, error)
Push(url string, origin Stream) (PushStream, error)
Request(request *http.Request, receiver Receiver, priority Priority) (Stream, error)
RequestResponse(request *http.Request, receiver Receiver, priority Priority) (*http.Response, error)
Run() error
SetFlowControl(FlowControl) error
SetTimeout(time.Duration)
SetReadTimeout(time.Duration)
SetWriteTimeout(time.Duration)
}
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.
func Connect ¶
Connect is used to perform connection reversal where the client (who is normally behind a NAT of some kind) connects to a server on the internet. The connection is then reversed so that the 'server' sends requests to the 'client'. See ConnectAndServe() for a blocking version of this
func NewClientConn ¶
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.
type Decompressor ¶
Decompressor is used to decompress the text header of a SPDY frame.
func NewDecompressor ¶
func NewDecompressor(version uint16) Decompressor
NewDecompressor is used to create a new decompressor. It takes the SPDY version to use.
type DefaultFlowControl ¶
type DefaultFlowControl uint32
func (DefaultFlowControl) InitialWindowSize ¶
func (f DefaultFlowControl) InitialWindowSize() uint32
func (DefaultFlowControl) ReceiveData ¶
func (f DefaultFlowControl) ReceiveData(_ StreamID, initialWindowSize uint32, newWindowSize int64) uint32
type Flags ¶
type Flags byte
Flags represent a frame's Flags.
func (Flags) CLEAR_SETTINGS ¶
CLEAR_SETTINGS indicates whether the CLEAR_SETTINGS flag is set.
func (Flags) PERSIST_VALUE ¶
PERSIST_VALUE indicates whether the PERSIST_VALUE flag is set.
func (Flags) UNIDIRECTIONAL ¶
UNIDIRECTIONAL indicates whether the UNIDIRECTIONAL flag is set.
type FlowControl ¶
type FlowControl interface {
InitialWindowSize() uint32
ReceiveData(streamID StreamID, initialWindowSize uint32, newWindowSize int64) (deltaSize uint32)
}
Objects conforming to the FlowControl interface can be used to provide the flow control mechanism for a connection using SPDY version 3 and above.
InitialWindowSize is called whenever a new stream is created, and the returned value used as the initial flow control window size. Note that a values smaller than the default (65535) will likely result in poor network utilisation.
ReceiveData is called whenever a stream's window is consumed by inbound data. The stream's ID is provided, along with the stream's initial window size and the current window size after receiving the data that caused the call. If the window is to be regrown, ReceiveData should return the increase in size. A value of 0 does not change the window. Note that in SPDY/3.1 and later, the streamID may be 0 to represent the connection-level flow control window.
type Frame ¶
type Frame interface {
fmt.Stringer
io.ReaderFrom
io.WriterTo
Compress(Compressor) error
Decompress(Decompressor) error
Name() string
}
Frame represents a single SPDY frame.
type Priority ¶
type Priority byte
Priority represents a stream's priority.
func DefaultPriority ¶
DefaultPriority returns the default request priority for the given target path. This is currently in accordance with Google Chrome; giving 0 for pages, 1 for CSS, 2 for JS, 3 for images. Other types default to 2.
type ProxyConnHandler ¶
type ProxyConnHandler interface {
ProxyConnHandle(Conn)
}
type ProxyConnHandlerFunc ¶
type ProxyConnHandlerFunc func(Conn)
func (ProxyConnHandlerFunc) ProxyConnHandle ¶
func (p ProxyConnHandlerFunc) ProxyConnHandle(c Conn)
type PushStream ¶
type PushStream interface {
Stream
// Fin is used to close the
// push stream once writing
// has finished.
Finish()
}
PushStream contains a single SPDY push stream.
func Push ¶
func Push(w http.ResponseWriter, url string) (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)
}
}
type Receiver ¶
type Receiver interface {
ReceiveData(request *http.Request, data []byte, final bool)
ReceiveHeader(request *http.Request, header http.Header)
ReceiveRequest(request *http.Request) bool
}
Objects implementing the Receiver interface can be registered to receive requests on the Client.
ReceiveData is passed the original request, the data to receive and a bool indicating whether this is the final batch of data. If the bool is set to true, the data may be empty, but should not be nil.
ReceiveHeaders is passed the request and any sent text headers. This may be called multiple times. Note that these headers may contain the status code of the response, under the ":status" header. If the Receiver is being used to proxy a request, and the headers presented to ReceiveHeader are copied to another ResponseWriter, take care to call its WriteHeader method after copying all headers, since this may flush headers received so far.
ReceiveRequest is used when server pushes are sent. The returned bool should inticate whether to accept the push. The provided Request will be that sent by the server with the push.
type Settings ¶
Settings represents a series of settings, stored in a map by setting ID. This ensures that duplicate settings are not sent, since the new value will replace the old.
type StatusCode ¶
type StatusCode uint32
StatusCode represents a status code sent in certain SPDY frames, such as RST_STREAM and GOAWAY.
func (StatusCode) String ¶
func (r StatusCode) String() string
String gives the StatusCode in text form.
type Stream ¶
type Stream interface {
http.CloseNotifier
http.ResponseWriter
io.ReadCloser
Conn() Conn
ReceiveFrame(Frame) error
Run() error
State() *StreamState
StreamID() StreamID
}
Stream contains a single SPDY stream.
type StreamID ¶
type StreamID uint32
StreamID is the unique identifier for a single SPDY stream.
type StreamState ¶
StreamState is used to store and query the stream's state. The active methods do not directly affect the stream's state, but it will use that information to effect the changes.
func (*StreamState) CloseThere ¶
func (s *StreamState) CloseThere()
Half-close the stream at the other endpoint.
func (*StreamState) Closed ¶
func (s *StreamState) Closed() bool
Check whether the stream is closed.
func (*StreamState) ClosedHere ¶
func (s *StreamState) ClosedHere() bool
Check whether the stream is half-closed at the other endpoint.
func (*StreamState) ClosedThere ¶
func (s *StreamState) ClosedThere() bool
Check whether the stream is half-closed at the other endpoint.
func (*StreamState) OpenHere ¶
func (s *StreamState) OpenHere() bool
Check whether the stream is open locally.
func (*StreamState) OpenThere ¶
func (s *StreamState) OpenThere() bool
Check whether the stream is open at the other endpoint.
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) Priority
// Receiver is used to receive the server's response. If left
// nil, the default Receiver will parse and create a normal
// Response.
Receiver 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 Receiver
// contains filtered or unexported fields
}
A Transport is an HTTP/SPDY http.RoundTripper.