Beispiel #1
0
Datei: conn.go Projekt: erkl/wire
func newConn(raw net.Conn, t *Transport, tls bool, addr string) *conn {
	buf := buffers.Get().([]byte)

	return &conn{
		Reader: xo.NewReader(raw, buf[:bufferSize]),
		Writer: xo.NewWriter(raw, buf[bufferSize:]),
		raw:    raw,
		buf:    buf,
		t:      t,
		tls:    tls,
		addr:   addr,
	}
}
Beispiel #2
0
func (p *Proxy) serveHTTPS(conn net.Conn, addr string) error {
	rw := xo.NewReadWriter(
		xo.NewReader(conn, make([]byte, 4096)),
		xo.NewWriter(conn, make([]byte, 4096)),
	)

	for {
		req, body, err := readRequest(rw)
		if err != nil {
			switch err {
			case heat.ErrRequestHeader:
				resp := statusResponse(404, "Malformed HTTP request header.")
				return writeResponse(rw, resp, req.Method)

			case heat.ErrRequestVersion:
				resp := statusResponse(505, "Unsupported HTTP version number.")
				return writeResponse(rw, resp, req.Method)

			// If the connection terminated cleanly, stop.
			case io.EOF:
				return nil

			// Any other error would be from the underlying connection, and
			// should be propagated.
			default:
				return err
			}
		}

		// Populate the scheme and remote address.
		req.Scheme = "https"
		req.Remote = addr

		// Will the client close this connection after receiving a response?
		closing := heat.Closing(req.Major, req.Minor, req.Fields)

		// Forward the request to the upstream server.
		resp, err := p.forward(req)
		if err != nil {
			resp = statusResponse(500, "Round-trip to upstream failed: %s.", err)
		}

		// Are we closing the connection after sending the response?
		if !closing && (body == nil || body.LastError() == io.EOF) {
			resp.Fields.Set("Connection", "keep-alive")
		} else {
			resp.Fields.Set("Connection", "close")
			closing = true
		}

		// Write the response.
		err = writeResponse(rw, resp, req.Method)
		if err != nil {
			return err
		}

		// Stop if the connection isn't keep-alive.
		if closing {
			return nil
		}
	}
}
Beispiel #3
0
func (p *Proxy) serveHTTP(conn net.Conn) error {
	rw := xo.NewReadWriter(
		xo.NewReader(conn, make([]byte, 4096)),
		xo.NewWriter(conn, make([]byte, 4096)),
	)

	for {
		// Read the next request.
		req, body, err := readRequest(rw)
		if err != nil {
			switch err {
			case heat.ErrRequestHeader:
				resp := statusResponse(404, "Malformed HTTP request header.")
				return writeResponse(rw, resp, req.Method)

			case heat.ErrRequestVersion:
				resp := statusResponse(505, "Unsupported HTTP version number.")
				return writeResponse(rw, resp, req.Method)

			// If the connection terminated cleanly, stop.
			case io.EOF:
				return nil

			// Any other error would be from the underlying connection, and
			// should be propagated.
			default:
				return err
			}
		}

		// Support CONNECT tunneling.
		if req.Method == "CONNECT" {
			return p.connect(conn, rw, req)
		}

		// Will the client close this connection after receiving a response?
		closing := heat.Closing(req.Major, req.Minor, req.Fields)

		// Fetch the actual response from the upstream server.
		resp, err := p.proxy(req)
		if err != nil {
			resp := statusResponse(500, "Unknown error: %s.", err)
			return writeResponse(rw, resp, req.Method)
		}

		// Are we closing the connection after sending the response?
		if !closing && (body == nil || body.LastError() == io.EOF) {
			resp.Fields.Set("Connection", "keep-alive")
		} else {
			resp.Fields.Set("Connection", "close")
			closing = true
		}

		// Write the response.
		err = writeResponse(rw, resp, req.Method)
		if err != nil {
			return err
		}

		// Stop if the connection isn't keep-alive.
		if closing {
			return nil
		}
	}
}