enproxy

package module
v0.0.0-...-ad4ddfd Latest Latest
Warning

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

Go to latest
Published: Dec 4, 2014 License: Apache-2.0 Imports: 13 Imported by: 0

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

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 (
	BAD_GATEWAY = 502

	DEFAULT_BYTES_BEFORE_FLUSH = 1024768
	DEFAULT_READ_BUFFER_SIZE   = 65536
)

Variables

This section is empty.

Functions

This section is empty.

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

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

func (*Config) Intercept

func (c *Config) Intercept(resp http.ResponseWriter, req *http.Request)

Intercept intercepts a CONNECT request, hijacks the underlying client connetion and starts piping the data over a new enproxy.Conn configured using this Config.

type Conn

type Conn struct {
	// Addr: the host:port of the destination server that we're trying to reach
	Addr string

	// Config: configuration of this Conn
	Config *Config
	// contains filtered or unexported fields
}

Conn is a net.Conn that tunnels its data via an httpconn.Proxy using HTTP requests and responses. It assumes that streaming requests are not supported by the underlying servers/proxies, and so uses a polling technique similar to the one used by meek, but different in that data is not encoded as JSON. https://trac.torproject.org/projects/tor/wiki/doc/AChildsGardenOfPluggableTransports#Undertheencryption.

enproxy uses two parallel channels to send and receive data. One channel handles writing data out by making sequential POST requests to the server which encapsulate the outbound data in their request bodies, while the other channel handles reading data by making GET requests and grabbing the data encapsulated in the response bodies.

Write Channel:

  1. Accept writes, piping these to the proxy as the body of an http POST
  2. Continue to pipe the writes until the pause between consecutive writes exceeds the IdleInterval, at which point we finish the request body. We do this because it is assumed that intervening proxies (e.g. CloudFlare CDN) do not allow streaming requests, so it is necessary to finish the request for data to get flushed to the destination server.
  3. After receiving a response to the POST request, return to step 1

Read Channel:

  1. Accept reads, issuing a new GET request if one is not already ongoing
  2. Process read by grabbing data from the response to the GET request
  3. Continue to accept reads, grabbing these from the response of the existing GET request
  4. Once the response to the GET request reaches EOF, return to step 1. This will happen because the proxy periodically closes responses to make sure intervening proxies don't time out.
  5. If a response is received with a special header indicating a true EOF from the destination server, return EOF to the reader

func (*Conn) Close

func (c *Conn) Close() error

Close() implements the function from net.Conn

func (*Conn) Connect

func (c *Conn) Connect() error

Connect opens a connection to the proxy and starts processing writes and reads to this Conn.

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

LocalAddr() is not implemented

func (*Conn) Read

func (c *Conn) Read(b []byte) (n int, err error)

Read() implements the function from net.Conn

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

RemoteAddr() is not implemented

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline() is currently unimplemented.

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline() is currently unimplemented.

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

SetWriteDeadline() is currently unimplemented.

func (*Conn) Write

func (c *Conn) Write(b []byte) (n int, err error)

Write() implements the function from net.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: FQDN that is guaranteed to hit this particular proxy.  Required
	// if this server was originally reached by e.g. DNS round robin.
	Host 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
	// 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) 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