localserver

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: May 24, 2018 License: MIT Imports: 21 Imported by: 0

README

localserver

Helpers for creating test HTTPS servers and clients on localhost.

Use case

If you're writing a proxy or some sort of routing component, you'll need to spin up some test servers. In the real world we only speak TLS, never plaintext. It follows that we'd like to use TLS in our integration tests, since using an encrypted transport gives us a more realistic setup.

However, dealing with X.509 certificates and keys is kind of a pain. On top of that, configuring TLS for Go's standard http.Server requires some boilerplate. This project tries to alleviate a little bit of that. We provide functions and configurable types that reside in memory, speaking HTTP1 and HTTP2 over TLS.

Example

Create a CA that can sign certs for a host called server1.

ca, err := NewCA(WithDNSNames([]string{"server1"}))

Create a signed cert for server1 with the CA object.

cert, err := ca.CreateSignedCert("server1")

Create a localhost HTTP2 server on a random high port. We provide a handler that echoes back our HTTP headers as a map. We provide the CA and the cert created earlier.

fn := func(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(200)
    // Header is an alias: type Header map[string][]string
    data, _ := json.Marshal(r.Header)
    w.Write(data)
}
svr := NewLocalServer(fn, cert, ca)
svr.StartHTTP2() // doesn't block
defer svr.Stop()

Now that svr is listening on localhost, we can talk to it over HTTPS with a client that trusts the same CA. Note that since we've spun up our test sever on a random port, we must use the AddrPort method to get the actual port.

client := NewHTTP2Client(ca)
url := fmt.Sprintf("https://server1:%s/", svr.AddrPort())
resp, err := client.Get(url)

Importantly, we have to set server1 as an alias to localhost in /etc/hosts, or otherwise ensure that the name server1 resolves to localhost.

Documentation

Overview

Package localserver is a generated protocol buffer package.

Web exposes a backend server over gRPC.

It is generated from these files:

grpc.proto

It has these top-level messages:

Key
Value
KV
OpResult

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewHTTP1Client

func NewHTTP1Client(ca *CA) *http.Client

NewHTTP1Client creates an http1 client that trusts our CA.

func NewHTTP2Client

func NewHTTP2Client(ca *CA) *http.Client

NewHTTP2Client creates an http2 client that trusts our CA.

func NewTLSConfig

func NewTLSConfig(ca *CA, certs ...*SignedCert) *tls.Config

NewTLSConfig builds a *tls.Config from a CA and one or more signed certs.

func NewTestHandler

func NewTestHandler(respCode int) http.HandlerFunc

NewTestHandler creates a handler that only writes a response code to test requests.

func RegisterGRPCServer added in v1.0.1

func RegisterGRPCServer(s *grpc.Server, srv GRPCServer)

Types

type CA

type CA struct {
	Cert       []byte
	PrivateKey []byte
	// contains filtered or unexported fields
}

CA is a temporary certificate authority suitable for LocalServers.

func NewCA

func NewCA(opts ...CAOption) (*CA, error)

NewCA returns CA

func (*CA) CreateSignedCert

func (ca *CA) CreateSignedCert(name string) (*SignedCert, error)

CreateSignedCert creates a signed certifictate.

type CAOption

type CAOption func(*caConfig)

CAOption are options for a Certificate Authority.

func WithCommonName

func WithCommonName(cn string) CAOption

WithCommonName sets a common name on a CA.

func WithDNSNames

func WithDNSNames(names []string) CAOption

WithDNSNames sets one or more supported DNS names on a CA. If you want to issue certs for a specfic DNS/SAN/host name, you must set them with this option.

func WithOrganization

func WithOrganization(orgs []string) CAOption

WithOrganization sets one or more organization names on a CA.

type GRPCClient added in v1.0.1

type GRPCClient interface {
	Get(ctx context.Context, in *Key, opts ...grpc.CallOption) (*Value, error)
	PutKVStream(ctx context.Context, opts ...grpc.CallOption) (GRPC_PutKVStreamClient, error)
	GetKVStream(ctx context.Context, in *Key, opts ...grpc.CallOption) (GRPC_GetKVStreamClient, error)
}

func NewGRPCClient added in v1.0.1

func NewGRPCClient(cc *grpc.ClientConn) GRPCClient

func NewGRPCClientForServer added in v1.0.1

func NewGRPCClientForServer(ca *CA, addr string) (GRPCClient, error)

NewGRPCClientForServer ...

type GRPCServer added in v1.0.1

type GRPCServer interface {
	Get(context.Context, *Key) (*Value, error)
	PutKVStream(GRPC_PutKVStreamServer) error
	GetKVStream(*Key, GRPC_GetKVStreamServer) error
}

type GRPCServerImpl added in v1.0.1

type GRPCServerImpl struct {
	Lis net.Listener
	Srv *grpc.Server
}

GRPCServerImpl ...

func NewGRPCServer added in v1.0.1

func NewGRPCServer(ca *CA, cert *SignedCert, authority string) (*GRPCServerImpl, error)

NewGRPCServer spins up a server pair on a random port. Inspect the Addr field on the returned server to see the port selected for the server. The authority parameter is the server hostname.

func (*GRPCServerImpl) Addr added in v1.0.1

func (i *GRPCServerImpl) Addr() string

Addr returns the full network address of the LocalServer's net.Listener.

func (*GRPCServerImpl) AddrPort added in v1.0.1

func (i *GRPCServerImpl) AddrPort() string

AddrPort returns the network port of the LocalServer's net.Listener.

func (*GRPCServerImpl) Get added in v1.0.1

func (i *GRPCServerImpl) Get(ctx context.Context, key *Key) (*Value, error)

Get is our test method for simple unary request-response.

func (*GRPCServerImpl) GetKVStream added in v1.0.1

func (i *GRPCServerImpl) GetKVStream(key *Key, stream GRPC_GetKVStreamServer) error

GetKVStream is our test method to stream from server to client.

func (*GRPCServerImpl) PutKVStream added in v1.0.1

func (i *GRPCServerImpl) PutKVStream(stream GRPC_PutKVStreamServer) error

PutKVStream is our test method to stream from client to server.

func (*GRPCServerImpl) ServeGRPC added in v1.0.1

func (i *GRPCServerImpl) ServeGRPC()

ServeGRPC starts a grpc server asyncronously.

func (*GRPCServerImpl) Stop added in v1.0.1

func (i *GRPCServerImpl) Stop()

Stop stops our grpc server.

type GRPC_GetKVStreamClient added in v1.0.1

type GRPC_GetKVStreamClient interface {
	Recv() (*KV, error)
	grpc.ClientStream
}

type GRPC_GetKVStreamServer added in v1.0.1

type GRPC_GetKVStreamServer interface {
	Send(*KV) error
	grpc.ServerStream
}

type GRPC_PutKVStreamClient added in v1.0.1

type GRPC_PutKVStreamClient interface {
	Send(*KV) error
	CloseAndRecv() (*OpResult, error)
	grpc.ClientStream
}

type GRPC_PutKVStreamServer added in v1.0.1

type GRPC_PutKVStreamServer interface {
	SendAndClose(*OpResult) error
	Recv() (*KV, error)
	grpc.ServerStream
}

type KV added in v1.0.1

type KV struct {
	Key   string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"`
	Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
}

func (*KV) Descriptor added in v1.0.1

func (*KV) Descriptor() ([]byte, []int)

func (*KV) GetKey added in v1.0.1

func (m *KV) GetKey() string

func (*KV) GetValue added in v1.0.1

func (m *KV) GetValue() string

func (*KV) ProtoMessage added in v1.0.1

func (*KV) ProtoMessage()

func (*KV) Reset added in v1.0.1

func (m *KV) Reset()

func (*KV) String added in v1.0.1

func (m *KV) String() string

type Key added in v1.0.1

type Key struct {
	Key string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"`
}

func (*Key) Descriptor added in v1.0.1

func (*Key) Descriptor() ([]byte, []int)

func (*Key) GetKey added in v1.0.1

func (m *Key) GetKey() string

func (*Key) ProtoMessage added in v1.0.1

func (*Key) ProtoMessage()

func (*Key) Reset added in v1.0.1

func (m *Key) Reset()

func (*Key) String added in v1.0.1

func (m *Key) String() string

type LocalServer

type LocalServer struct {
	TLS *tls.Config
	Srv *http.Server
	Lis net.Listener
	// contains filtered or unexported fields
}

LocalServer is a server that can be configured to respond with a configurable handler. This is useful for testing.

func NewLocalServer

func NewLocalServer(h http.HandlerFunc, cert *SignedCert, ca *CA, opts ...Option) *LocalServer

NewLocalServer builds a LocalServer.

func (*LocalServer) AddrPort

func (ls *LocalServer) AddrPort() string

AddrPort returns the network address of the LocalServer's net.Listener.

func (*LocalServer) Debug

func (ls *LocalServer) Debug() string

func (*LocalServer) StartHTTP1

func (ls *LocalServer) StartHTTP1()

StartHTTP1 starts a LocalServer as an HTTP1 server.

func (*LocalServer) StartHTTP2

func (ls *LocalServer) StartHTTP2()

StartHTTP2 starts a LocalServer as an HTTP2 server. We rely on Go's net/http package using HTTP2 by default, as long as the server uses TLS with the right protocol suite.

func (*LocalServer) Stop

func (ls *LocalServer) Stop()

Stop stops our HTTP server.

type OpResult added in v1.0.1

type OpResult struct {
	ErrCode int64 `protobuf:"varint,1,opt,name=err_code,json=errCode" json:"err_code,omitempty"`
}

func (*OpResult) Descriptor added in v1.0.1

func (*OpResult) Descriptor() ([]byte, []int)

func (*OpResult) GetErrCode added in v1.0.1

func (m *OpResult) GetErrCode() int64

func (*OpResult) ProtoMessage added in v1.0.1

func (*OpResult) ProtoMessage()

func (*OpResult) Reset added in v1.0.1

func (m *OpResult) Reset()

func (*OpResult) String added in v1.0.1

func (m *OpResult) String() string

type Option

type Option func(*LocalServer)

func WithDebugBuffer

func WithDebugBuffer() Option

type SignedCert

type SignedCert struct {
	Cert       []byte
	PrivateKey []byte
}

A SignedCert can be created by a CA.

type Value added in v1.0.1

type Value struct {
	Value string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
}

func (*Value) Descriptor added in v1.0.1

func (*Value) Descriptor() ([]byte, []int)

func (*Value) GetValue added in v1.0.1

func (m *Value) GetValue() string

func (*Value) ProtoMessage added in v1.0.1

func (*Value) ProtoMessage()

func (*Value) Reset added in v1.0.1

func (m *Value) Reset()

func (*Value) String added in v1.0.1

func (m *Value) String() string

Jump to

Keyboard shortcuts

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