httputil

Imports

Imports #

"bufio"
"bytes"
"errors"
"fmt"
"io"
"net"
"net/http"
"net/url"
"strings"
"time"
"io"
"net/http/internal"
"bufio"
"errors"
"io"
"net"
"net/http"
"net/textproto"
"sync"
"context"
"errors"
"fmt"
"io"
"log"
"mime"
"net"
"net/http"
"net/http/httptrace"
"net/http/internal/ascii"
"net/textproto"
"net/url"
"strings"
"sync"
"time"
"golang.org/x/net/http/httpguts"

Constants & Variables

ErrClosed var #

Deprecated: No longer used.

var ErrClosed = *ast.UnaryExpr

ErrLineTooLong var #

ErrLineTooLong is returned when reading malformed chunked data with lines that are too long.

var ErrLineTooLong = internal.ErrLineTooLong

ErrPersistEOF var #

Deprecated: No longer used.

var ErrPersistEOF = *ast.UnaryExpr

ErrPipeline var #

Deprecated: No longer used.

var ErrPipeline = *ast.UnaryExpr

emptyBody var #

emptyBody is an instance of empty reader.

var emptyBody = *ast.CallExpr

errClosed var #

This is an API usage error - the local side is closed. ErrPersistEOF (above) reports that the remote side is closed.

var errClosed = *ast.CallExpr

errNoBody var #

errNoBody is a sentinel error value used by failureToReadBody so we can detect that the lack of body was intentional.

var errNoBody = *ast.CallExpr

hopHeaders var #

Hop-by-hop headers. These are removed when sent to the backend. As of RFC 7230, hop-by-hop headers are required to appear in the Connection header field. These are the headers defined by the obsoleted RFC 2616 (section 13.5.1) and are used for backward compatibility.

var hopHeaders = []string{...}

inOurTests var #

var inOurTests bool

reqWriteExcludeHeaderDump var #

var reqWriteExcludeHeaderDump = map[string]bool{...}

Type Aliases

neverEnding type #

type neverEnding byte

Interfaces

BufferPool interface #

A BufferPool is an interface for getting and returning temporary byte slices for use by [io.CopyBuffer].

type BufferPool interface {
Get() []byte
Put([]byte)
}

Structs

ClientConn struct #

ClientConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use Client or Transport in package [net/http] instead.

type ClientConn struct {
mu sync.Mutex
c net.Conn
r *bufio.Reader
re error
we error
lastbody io.ReadCloser
nread int
nwritten int
pipereq map[*http.Request]uint
pipe textproto.Pipeline
writeReq func(*http.Request, io.Writer) error
}

ProxyRequest struct #

A ProxyRequest contains a request to be rewritten by a [ReverseProxy].

type ProxyRequest struct {
In *http.Request
Out *http.Request
}

ReverseProxy struct #

ReverseProxy is an HTTP Handler that takes an incoming request and sends it to another server, proxying the response back to the client. 1xx responses are forwarded to the client if the underlying transport supports ClientTrace.Got1xxResponse.

type ReverseProxy struct {
Rewrite func(*ProxyRequest)
Director func(*http.Request)
Transport http.RoundTripper
FlushInterval time.Duration
ErrorLog *log.Logger
BufferPool BufferPool
ModifyResponse func(*http.Response) error
ErrorHandler func(http.ResponseWriter, *http.Request, error)
}

ServerConn struct #

ServerConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use the Server in package [net/http] instead.

type ServerConn struct {
mu sync.Mutex
c net.Conn
r *bufio.Reader
re error
we error
lastbody io.ReadCloser
nread int
nwritten int
pipereq map[*http.Request]uint
pipe textproto.Pipeline
}

delegateReader struct #

delegateReader is a reader that delegates to another reader, once it arrives on a channel.

type delegateReader struct {
c chan io.Reader
err error
r io.Reader
}

dumpConn struct #

dumpConn is a net.Conn which writes to Writer and reads from Reader

type dumpConn struct {
io.Writer
io.Reader
}

failureToReadBody struct #

failureToReadBody is an io.ReadCloser that just returns errNoBody on Read. It's swapped in when we don't actually want to consume the body, but need a non-nil one, and want to distinguish the error from reading the dummy body.

type failureToReadBody struct {

}

maxLatencyWriter struct #

type maxLatencyWriter struct {
dst io.Writer
flush func() error
latency time.Duration
mu sync.Mutex
t *time.Timer
flushPending bool
}

switchProtocolCopier struct #

switchProtocolCopier exists so goroutines proxying data back and forth have nice names in stacks.

type switchProtocolCopier struct {
user io.ReadWriter
backend io.ReadWriter
}

Functions

Close method #

Close calls [ClientConn.Hijack] and then also closes the underlying connection.

func (cc *ClientConn) Close() error

Close method #

func (c *dumpConn) Close() error

Close method #

func (failureToReadBody) Close() error

Close method #

Close calls [ServerConn.Hijack] and then also closes the underlying connection.

func (sc *ServerConn) Close() error

Do method #

Do is convenience method that writes a request and reads a response.

func (cc *ClientConn) Do(req *http.Request) (*http.Response, error)

DumpRequest function #

DumpRequest returns the given request in its HTTP/1.x wire representation. It should only be used by servers to debug client requests. The returned representation is an approximation only; some details of the initial request are lost while parsing it into an [http.Request]. In particular, the order and case of header field names are lost. The order of values in multi-valued headers is kept intact. HTTP/2 requests are dumped in HTTP/1.x form, not in their original binary representations. If body is true, DumpRequest also returns the body. To do so, it consumes req.Body and then replaces it with a new [io.ReadCloser] that yields the same bytes. If DumpRequest returns an error, the state of req is undefined. The documentation for [http.Request.Write] details which fields of req are included in the dump.

func DumpRequest(req *http.Request, body bool) ([]byte, error)

DumpRequestOut function #

DumpRequestOut is like [DumpRequest] but for outgoing client requests. It includes any headers that the standard [http.Transport] adds, such as User-Agent.

func DumpRequestOut(req *http.Request, body bool) ([]byte, error)

DumpResponse function #

DumpResponse is like DumpRequest but dumps a response.

func DumpResponse(resp *http.Response, body bool) ([]byte, error)

Hijack method #

Hijack detaches the [ClientConn] and returns the underlying connection as well as the read-side bufio which may have some left over data. Hijack may be called before the user or Read have signaled the end of the keep-alive logic. The user should not call Hijack while [ClientConn.Read] or ClientConn.Write is in progress.

func (cc *ClientConn) Hijack() (c net.Conn, r *bufio.Reader)

Hijack method #

Hijack detaches the [ServerConn] and returns the underlying connection as well as the read-side bufio which may have some left over data. Hijack may be called before Read has signaled the end of the keep-alive logic. The user should not call Hijack while [ServerConn.Read] or [ServerConn.Write] is in progress.

func (sc *ServerConn) Hijack() (net.Conn, *bufio.Reader)

LocalAddr method #

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

NewChunkedReader function #

NewChunkedReader returns a new chunkedReader that translates the data read from r out of HTTP "chunked" format before returning it. The chunkedReader returns [io.EOF] when the final 0-length chunk is read. NewChunkedReader is not needed by normal applications. The http package automatically decodes chunking when reading response bodies.

func NewChunkedReader(r io.Reader) io.Reader

NewChunkedWriter function #

NewChunkedWriter returns a new chunkedWriter that translates writes into HTTP "chunked" format before writing them to w. Closing the returned chunkedWriter sends the final 0-length chunk that marks the end of the stream but does not send the final CRLF that appears after trailers; trailers and the last CRLF must be written separately. NewChunkedWriter is not needed by normal applications. The http package adds chunking automatically if handlers don't set a Content-Length header. Using NewChunkedWriter inside a handler would result in double chunking or chunking with a Content-Length length, both of which are wrong.

func NewChunkedWriter(w io.Writer) io.WriteCloser

NewClientConn function #

NewClientConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use the Client or Transport in package [net/http] instead.

func NewClientConn(c net.Conn, r *bufio.Reader) *ClientConn

NewProxyClientConn function #

NewProxyClientConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use the Client or Transport in package [net/http] instead.

func NewProxyClientConn(c net.Conn, r *bufio.Reader) *ClientConn

NewServerConn function #

NewServerConn is an artifact of Go's early HTTP implementation. It is low-level, old, and unused by Go's current HTTP stack. We should have deleted it before Go 1. Deprecated: Use the Server in package [net/http] instead.

func NewServerConn(c net.Conn, r *bufio.Reader) *ServerConn

NewSingleHostReverseProxy function #

NewSingleHostReverseProxy returns a new [ReverseProxy] that routes URLs to the scheme, host, and base path provided in target. If the target's path is "/base" and the incoming request was for "/dir", the target request will be for /base/dir. NewSingleHostReverseProxy does not rewrite the Host header. To customize the ReverseProxy behavior beyond what NewSingleHostReverseProxy provides, use ReverseProxy directly with a Rewrite function. The ProxyRequest SetURL method may be used to route the outbound request. (Note that SetURL, unlike NewSingleHostReverseProxy, rewrites the Host header of the outbound request by default.) proxy := &ReverseProxy{ Rewrite: func(r *ProxyRequest) { r.SetURL(target) r.Out.Host = r.In.Host // if desired }, }

func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy

Pending method #

Pending returns the number of unanswered requests that have been sent on the connection.

func (cc *ClientConn) Pending() int

Pending method #

Pending returns the number of unanswered requests that have been received on the connection.

func (sc *ServerConn) Pending() int

Read method #

Read reads the next response from the wire. A valid response might be returned together with an [ErrPersistEOF], which means that the remote requested that this be the last request serviced. Read can be called concurrently with [ClientConn.Write], but not with another Read.

func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error)

Read method #

Read returns the next request on the wire. An [ErrPersistEOF] is returned if it is gracefully determined that there are no more requests (e.g. after the first request on an HTTP/1.0 connection, or after a Connection:close on a HTTP/1.1 connection).

func (sc *ServerConn) Read() (*http.Request, error)

Read method #

func (b neverEnding) Read(p []byte) (n int, err error)

Read method #

func (r *delegateReader) Read(p []byte) (int, error)

Read method #

func (failureToReadBody) Read([]byte) (int, error)

RemoteAddr method #

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

ServeHTTP method #

func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request)

SetDeadline method #

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

SetReadDeadline method #

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

SetURL method #

SetURL routes the outbound request to the scheme, host, and base path provided in target. If the target's path is "/base" and the incoming request was for "/dir", the target request will be for "/base/dir". SetURL rewrites the outbound Host header to match the target's host. To preserve the inbound request's Host header (the default behavior of [NewSingleHostReverseProxy]): rewriteFunc := func(r *httputil.ProxyRequest) { r.SetURL(url) r.Out.Host = r.In.Host }

func (r *ProxyRequest) SetURL(target *url.URL)

SetWriteDeadline method #

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

SetXForwarded method #

SetXForwarded sets the X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto headers of the outbound request. - The X-Forwarded-For header is set to the client IP address. - The X-Forwarded-Host header is set to the host name requested by the client. - The X-Forwarded-Proto header is set to "http" or "https", depending on whether the inbound request was made on a TLS-enabled connection. If the outbound request contains an existing X-Forwarded-For header, SetXForwarded appends the client IP address to it. To append to the inbound request's X-Forwarded-For header (the default behavior of [ReverseProxy] when using a Director function), copy the header from the inbound request before calling SetXForwarded: rewriteFunc := func(r *httputil.ProxyRequest) { r.Out.Header["X-Forwarded-For"] = r.In.Header["X-Forwarded-For"] r.SetXForwarded() }

func (r *ProxyRequest) SetXForwarded()

Write method #

func (m *maxLatencyWriter) Write(p []byte) (n int, err error)

Write method #

Write writes a request. An [ErrPersistEOF] error is returned if the connection has been closed in an HTTP keep-alive sense. If req.Close equals true, the keep-alive connection is logically closed after this request and the opposing server is informed. An ErrUnexpectedEOF indicates the remote closed the underlying TCP connection, which is usually considered as graceful close.

func (cc *ClientConn) Write(req *http.Request) error

Write method #

Write writes resp in response to req. To close the connection gracefully, set the Response.Close field to true. Write should be considered operational until it returns an error, regardless of any errors returned on the [ServerConn.Read] side.

func (sc *ServerConn) Write(req *http.Request, resp *http.Response) error

cleanQueryParams function #

func cleanQueryParams(s string) string

copyBuffer method #

copyBuffer returns any write errors or non-EOF read errors, and the amount of bytes written.

func (p *ReverseProxy) copyBuffer(dst io.Writer, src io.Reader, buf []byte) (int64, error)

copyFromBackend method #

func (c switchProtocolCopier) copyFromBackend(errc chan<- error)

copyHeader function #

func copyHeader(dst http.Header, src http.Header)

copyResponse method #

func (p *ReverseProxy) copyResponse(dst http.ResponseWriter, src io.Reader, flushInterval time.Duration) error

copyToBackend method #

func (c switchProtocolCopier) copyToBackend(errc chan<- error)

defaultErrorHandler method #

func (p *ReverseProxy) defaultErrorHandler(rw http.ResponseWriter, req *http.Request, err error)

delayedFlush method #

func (m *maxLatencyWriter) delayedFlush()

drainBody function #

drainBody reads all of b to memory and then returns two equivalent ReadClosers yielding the same bytes. It returns an error if the initial slurp of all bytes fails. It does not attempt to make the returned ReadClosers have identical error-matching behavior.

func drainBody(b io.ReadCloser) (r1 io.ReadCloser, r2 io.ReadCloser, err error)

flushInterval method #

flushInterval returns the p.FlushInterval value, conditionally overriding its value for a specific request/response.

func (p *ReverseProxy) flushInterval(res *http.Response) time.Duration

getErrorHandler method #

func (p *ReverseProxy) getErrorHandler() (func(http.ResponseWriter, *http.Request, error))

handleUpgradeResponse method #

func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response)

ishex function #

func ishex(c byte) bool

joinURLPath function #

func joinURLPath(a *url.URL, b *url.URL) (path string, rawpath string)

logf method #

func (p *ReverseProxy) logf(format string, args ...any)

modifyResponse method #

modifyResponse conditionally runs the optional ModifyResponse hook and reports whether the request should proceed.

func (p *ReverseProxy) modifyResponse(rw http.ResponseWriter, res *http.Response, req *http.Request) bool

outgoingLength function #

outgoingLength is a copy of the unexported (*http.Request).outgoingLength method.

func outgoingLength(req *http.Request) int64

removeHopByHopHeaders function #

removeHopByHopHeaders removes hop-by-hop headers.

func removeHopByHopHeaders(h http.Header)

rewriteRequestURL function #

func rewriteRequestURL(req *http.Request, target *url.URL)

shouldPanicOnCopyError function #

shouldPanicOnCopyError reports whether the reverse proxy should panic with http.ErrAbortHandler. This is the right thing to do by default, but Go 1.10 and earlier did not, so existing unit tests weren't expecting panics. Only panic in our own tests, or when running under the HTTP server.

func shouldPanicOnCopyError(req *http.Request) bool

singleJoiningSlash function #

func singleJoiningSlash(a string, b string) string

stop method #

func (m *maxLatencyWriter) stop()

upgradeType function #

func upgradeType(h http.Header) string

valueOrDefault function #

Return value if nonempty, def otherwise.

func valueOrDefault(value string, def string) string

Generated with Arrow