enproxy

package module
v0.0.0-...-002212d Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2018 License: Apache-2.0 Imports: 17 Imported by: 25

README

enproxy Travis CI Status Coverage Status GoDoc

enproxy provides an implementation of net.Conn that sends and receives data to/ from a proxy using HTTP request/response pairs that encapsulate the data. This is useful when you need to tunnel arbitrary protocols over an HTTP proxy that doesn't support HTTP CONNECT. Content distribution networks are one example of such a proxy.

To open such a connection:

conn := &enproxy.Conn{
  Addr:   addr,
  Config: &enproxy.Config{
    DialProxy: func(addr string) (net.Conn, error) {
      // This opens a TCP connection to the proxy
      return net.Dial("tcp", proxyAddress)
    },
    NewRequest: func(method string, body io.Reader) (req *http.Request, err error) {
      // This is called for every request from enproxy.Conn to the proxy
      return http.NewRequest(method, "http://"+proxyAddress+"/", body)
    },
  },
}
err := conn.Connect()
if err == nil {
  // start using conn as any other net.Conn
}

To start the corresponding proxy server:

proxy := &enproxy.Proxy{}
err := proxy.ListenAndServe(proxyAddress)
if err != nil {
  log.Fatalf("Unable to listen and serve: %s", err)
}

Debugging

enproxy allows tracing various global metrics about connections, which can be useful when debugging issues like file descriptor leaks. To enable this tracing, just set the environment variable TRACE_CONN_STATE=true. This will cause the program to output information like the below every 5 seconds:

---- Enproxy Connections----
Open:                        34
Closing:                      0
Blocked on Closing:           0
Blocked on Read:             33
Reading:                     33
Reading Finishing:            0
Blocked on Write:             0
Writing:                     33
  Selecting:                 33
  Writing:                    0
    Write Pipe Open:          0
    Request Pending:          0
      Submitting Req.:        0
      Processing Req.:        1
        Posting Req. Fin:     0
        Posting Resp:         0       
        Dialing First:        0
        Redialing:            0
    Doing Write:              0
  Posting Response:           0
  Writing Empty:              0
  Finishing Body:             0
  Finishing:                  0
Requesting:                  33
Requesting Finishing:         0

Documentation

Index

Constants

View Source
const (
	X_ENPROXY_ID         = "X-Enproxy-Id"
	X_ENPROXY_DEST_ADDR  = "X-Enproxy-Dest-Addr"
	X_ENPROXY_EOF        = "X-Enproxy-EOF"
	X_ENPROXY_PROXY_HOST = "X-Enproxy-Proxy-Host"
	X_ENPROXY_OP         = "X-Enproxy-Op"

	OP_WRITE = "write"
	OP_READ  = "read"
)
View Source
const (
	DEFAULT_BYTES_BEFORE_FLUSH = 1024768
	DEFAULT_READ_BUFFER_SIZE   = 65536
)

Variables

This section is empty.

Functions

func Dial

func Dial(addr string, config *Config) (net.Conn, error)

Dial creates a Conn, opens a connection to the proxy and starts processing writes and reads on the Conn.

addr: the host:port of the destination server that we're trying to reach

config: configuration for this Conn

func DumpConnTrace

func DumpConnTrace()

DumpConnTrace dumps connection tracing information to the debug log.

Types

type Config

type Config struct {
	// DialProxy: function to open a connection to the proxy
	DialProxy dialFunc

	// NewRequest: function to create a new request to the proxy
	NewRequest newRequestFunc

	// OnFirstResponse: optional callback that gets called on the first response
	// from the proxy.
	OnFirstResponse func(resp *http.Response)

	// FlushTimeout: how long to let writes idle before writing out a
	// request to the proxy.  Defaults to 15 milliseconds.
	FlushTimeout time.Duration

	// IdleTimeout: how long to wait before closing an idle connection, defaults
	// to 30 seconds on the client and 70 seconds on the server proxy.
	//
	// For clients, the value should be set lower than the proxy's idle timeout
	// so that enproxy redials before the active connection is closed. The value
	// should be set higher than the maximum possible time between the proxy
	// receiving the last data from a request and the proxy returning the first
	// data of the response, otherwise the connection will be closed in the
	// middle of processing a request.
	IdleTimeout time.Duration

	// BufferRequests: if true, requests to the proxy will be buffered and sent
	// with identity encoding.  If false, they'll be streamed with chunked
	// encoding.
	BufferRequests bool
}

Config configures a Conn

type Proxy

type Proxy struct {
	// Dial: function used to dial the destination server.  If nil, a default
	// TCP dialer is used.
	Dial dialFunc

	// Host: (Deprecated; use HostFn instead) FQDN of this particular proxy.
	// Either this or HostFn is required if this server was originally reached
	// by DNS round robin.
	Host string

	// HostFn: given a http.Request, return the FQDN of this particular proxy,
	// hopefully through the same front.  This is used to support multiple
	// domain fronts.  Either this or Host is required if this server was
	// originally reached by DNS round robin.
	HostFn func(*http.Request) string

	// FlushTimeout: how long to let reads idle before writing out a
	// response to the client.  Defaults to 35 milliseconds.
	FlushTimeout time.Duration

	// BytesBeforeFlush: how many bytes to read before flushing response to
	// client.  Periodically flushing the response keeps the response buffer
	// from getting too big when processing big downloads.
	BytesBeforeFlush int

	// IdleTimeout: how long to wait before closing an idle connection, defaults
	// to 70 seconds
	IdleTimeout time.Duration

	// ReadBufferSize: size of read buffer in bytes
	ReadBufferSize int

	// OnBytesReceived is an optional callback for learning about bytes received
	// from a client
	OnBytesReceived statCallback

	// OnBytesSent is an optional callback for learning about bytes sent to a
	// client
	OnBytesSent statCallback

	// Allow: Optional function that checks whether the given request to the
	// given destAddr is allowed.  If it is not allowed, this function should
	// return the HTTP error code and an error.
	Allow func(req *http.Request, destAddr string) (int, error)
	// contains filtered or unexported fields
}

Proxy is the server side to an enproxy.Client. Proxy implements the http.Handler interface for plugging into an HTTP server, and it also provides a convenience ListenAndServe() function for quickly starting up a dedicated HTTP server using this Proxy as its handler.

func (*Proxy) ListenAndServe

func (p *Proxy) ListenAndServe(addr string) error

ListenAndServe: convenience function for quickly starting up a dedicated HTTP server using this Proxy as its handler

func (*Proxy) Serve

func (p *Proxy) Serve(l net.Listener) error

Serve: convenience function for quickly starting up a dedicated HTTP server using this Proxy as its handler

func (*Proxy) ServeHTTP

func (p *Proxy) ServeHTTP(resp http.ResponseWriter, req *http.Request)

ServeHTTP: implements the http.Handler interface

func (*Proxy) Start

func (p *Proxy) Start()

Start() starts this proxy

Directories

Path Synopsis
test

Jump to

Keyboard shortcuts

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