spdy

package
v0.0.0-...-ad0d598 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2017 License: Apache-2.0, BSD-2-Clause Imports: 16 Imported by: 0

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

View Source
const DEFAULT_SPDY_VERSION = 3.1

SPDY version of this implementation.

Variables

This section is empty.

Functions

func AddSPDY

func AddSPDY(srv *http.Server)

AddSPDY adds SPDY support to srv, and must be called before srv begins serving.

func DisableSpdyVersion

func DisableSpdyVersion(v float64) error

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

func EnableSpdyVersion(v float64) error

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 NewClient

func NewClient(insecureSkipVerify bool) *http.Client

NewClient creates an http.Client that supports SPDY.

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 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

func PingServer(c http.Client, server string) (<-chan bool, error)

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 Push

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

func SetDebugLogger(l *logging.Logger)

SetDebugLogger sets the package's debug info logger.

func SetDebugOutput

func SetDebugOutput(w io.Writer)

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

func SetLogOutput(w io.Writer)

SetLogOutput sets the output for the package's error logger.

func SetLogger

func SetLogger(l *logging.Logger)

SetLogger sets 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

func SupportedVersion(v float64) bool

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

type Compressor interface {
	io.Closer
	Compress(http.Header) ([]byte, error)
}

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

type Decompressor interface {
	Decompress([]byte) (http.Header, error)
}

Decompressor is used to decompress the text header of a SPDY frame.

type Pinger

type Pinger interface {
	Ping() (<-chan bool, error)
}

Pinger represents something able to send and receive PING frames.

type PriorityStream

type PriorityStream interface {
	Stream

	// Priority returns the stream's
	// priority.
	Priority() common.Priority
}

PriorityStream represents a SPDY stream with a priority.

type Pusher

type Pusher interface {
	Push(url string, origin common.Stream) (common.PushStream, error)
}

Pusher represents something able to send server puhes.

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

func NewTransport(insecureSkipVerify bool) *Transport

NewTransport gives a simple initialised Transport.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip handles the actual request; ensuring a connection is made, determining which protocol to use, and performing the request.

Directories

Path Synopsis
Package common contains shared functionality for the spdy package.
Package common contains shared functionality for the spdy package.
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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL