httputil

package
v0.0.0-...-64a4400 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2021 License: Apache-2.0, ISC Imports: 19 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// Deprecated: No longer used.
	ErrPersistEOF = &http.ProtocolError{ErrorString: "persistent connection closed"}

	// Deprecated: No longer used.
	ErrClosed = &http.ProtocolError{ErrorString: "connection closed by user"}

	// Deprecated: No longer used.
	ErrPipeline = &http.ProtocolError{ErrorString: "pipeline error"}
)

Functions

func DumpRequest

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

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.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"strings"

	"github.com/boosted-bounty/zgrab2/lib/http"
	"github.com/boosted-bounty/zgrab2/lib/http/httptest"
	"github.com/boosted-bounty/zgrab2/lib/http/httputil"
)

func main() {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		dump, err := httputil.DumpRequest(r, true)
		if err != nil {
			http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
			return
		}

		fmt.Fprintf(w, "%q", dump)
	}))
	defer ts.Close()

	const body = "Go is a general-purpose language designed with systems programming in mind."
	req, err := http.NewRequest("POST", ts.URL, strings.NewReader(body))
	if err != nil {
		log.Fatal(err)
	}
	req.Host = "www.example.org"
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s", b)

}
Output:

"POST / HTTP/1.1\r\nHost: www.example.org\r\nAccept-Encoding: gzip\r\nContent-Length: 75\r\nUser-Agent: Mozilla/5.0 zgrab/0.x\r\n\r\nGo is a general-purpose language designed with systems programming in mind."

func DumpRequestOut

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

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

Example
package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/boosted-bounty/zgrab2/lib/http"
	"github.com/boosted-bounty/zgrab2/lib/http/httputil"
)

func main() {
	const body = "Go is a general-purpose language designed with systems programming in mind."
	req, err := http.NewRequest("PUT", "http://www.example.org", strings.NewReader(body))
	if err != nil {
		log.Fatal(err)
	}

	dump, err := httputil.DumpRequestOut(req, true)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%q", dump)

}
Output:

"PUT / HTTP/1.1\r\nHost: www.example.org\r\nUser-Agent: Mozilla/5.0 zgrab/0.x\r\nContent-Length: 75\r\nAccept-Encoding: gzip\r\n\r\nGo is a general-purpose language designed with systems programming in mind."

func DumpResponse

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

DumpResponse is like DumpRequest but dumps a response.

Example
package main

import (
	"fmt"
	"log"

	"github.com/boosted-bounty/zgrab2/lib/http"
	"github.com/boosted-bounty/zgrab2/lib/http/httptest"
	"github.com/boosted-bounty/zgrab2/lib/http/httputil"
)

func main() {
	const body = "Go is a general-purpose language designed with systems programming in mind."
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Date", "Wed, 19 Jul 1972 19:00:00 GMT")
		fmt.Fprintln(w, body)
	}))
	defer ts.Close()

	resp, err := http.Get(ts.URL)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	dump, err := httputil.DumpResponse(resp, true)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%q", dump)

}
Output:

"HTTP/1.1 200 OK\r\nContent-Length: 76\r\nContent-Length: 76\r\nContent-Type: text/plain; charset=utf-8\r\nDate: Wed, 19 Jul 1972 19:00:00 GMT\r\n\r\nGo is a general-purpose language designed with systems programming in mind.\n"

func TestNilBody

func TestNilBody(t *testing.T)

Issue 12344

func TestReverseProxy

func TestReverseProxy(t *testing.T)

func TestReverseProxyCancelation

func TestReverseProxyCancelation(t *testing.T)

func TestReverseProxyFlushInterval

func TestReverseProxyFlushInterval(t *testing.T)

func TestReverseProxyGetPutBuffer

func TestReverseProxyGetPutBuffer(t *testing.T)

func TestReverseProxyModifyResponse

func TestReverseProxyModifyResponse(t *testing.T)

Issue 14237. Test ModifyResponse and that an error from it causes the proxy to return StatusBadGateway, or StatusOK otherwise.

func TestReverseProxyQuery

func TestReverseProxyQuery(t *testing.T)

func TestReverseProxyStripHeadersPresentInConnection

func TestReverseProxyStripHeadersPresentInConnection(t *testing.T)

Issue 16875: remove any proxied headers mentioned in the "Connection" header value.

func TestReverseProxy_CopyBuffer

func TestReverseProxy_CopyBuffer(t *testing.T)

Issue 16659: log errors from short read

func TestReverseProxy_NilBody

func TestReverseProxy_NilBody(t *testing.T)

Issue 16036: send a Request with a nil Body when possible

func TestReverseProxy_Post

func TestReverseProxy_Post(t *testing.T)

func TestUserAgentHeader

func TestUserAgentHeader(t *testing.T)

Issue 15524

func TestXForwardedFor

func TestXForwardedFor(t *testing.T)

Types

type BufferPool

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

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

type ClientConn deprecated

type ClientConn struct {
	// contains filtered or unexported fields
}

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.

func NewClientConn deprecated

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

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 NewProxyClientConn deprecated

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

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 (*ClientConn) Close

func (cc *ClientConn) Close() error

Close calls Hijack and then also closes the underlying connection.

func (*ClientConn) Do

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

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

func (*ClientConn) Hijack

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

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 Read or Write is in progress.

func (*ClientConn) Pending

func (cc *ClientConn) Pending() int

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

func (*ClientConn) Read

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

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 Write, but not with another Read.

func (*ClientConn) Write

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

Write writes a request. An ErrPersistEOF error is returned if the connection has been closed in an HTTP keepalive sense. If req.Close equals true, the keepalive 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.

type ReverseProxy

type ReverseProxy struct {
	// Director must be a function which modifies
	// the request into a new request to be sent
	// using Transport. Its response is then copied
	// back to the original client unmodified.
	// Director must not access the provided Request
	// after returning.
	Director func(*http.Request)

	// The transport used to perform proxy requests.
	// If nil, http.DefaultTransport is used.
	Transport http.RoundTripper

	// FlushInterval specifies the flush interval
	// to flush to the client while copying the
	// response body.
	// If zero, no periodic flushing is done.
	FlushInterval time.Duration

	// ErrorLog specifies an optional logger for errors
	// that occur when attempting to proxy the request.
	// If nil, logging goes to os.Stderr via the log package's
	// standard logger.
	ErrorLog *log.Logger

	// BufferPool optionally specifies a buffer pool to
	// get byte slices for use by io.CopyBuffer when
	// copying HTTP response bodies.
	BufferPool BufferPool

	// ModifyResponse is an optional function that
	// modifies the Response from the backend.
	// If it returns an error, the proxy returns a StatusBadGateway error.
	ModifyResponse func(*http.Response) error
}

ReverseProxy is an HTTP Handler that takes an incoming request and sends it to another server, proxying the response back to the client.

Example
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/url"

	"github.com/boosted-bounty/zgrab2/lib/http"
	"github.com/boosted-bounty/zgrab2/lib/http/httptest"
	"github.com/boosted-bounty/zgrab2/lib/http/httputil"
)

func main() {
	backendServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "this call was relayed by the reverse proxy")
	}))
	defer backendServer.Close()

	rpURL, err := url.Parse(backendServer.URL)
	if err != nil {
		log.Fatal(err)
	}
	frontendProxy := httptest.NewServer(httputil.NewSingleHostReverseProxy(rpURL))
	defer frontendProxy.Close()

	resp, err := http.Get(frontendProxy.URL)
	if err != nil {
		log.Fatal(err)
	}

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s", b)

}
Output:

this call was relayed by the reverse proxy

func NewSingleHostReverseProxy

func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy

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 rewrite Host headers, use ReverseProxy directly with a custom Director policy.

func (*ReverseProxy) ServeHTTP

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

type RoundTripperFunc

type RoundTripperFunc func(*http.Request) (*http.Response, error)

func (RoundTripperFunc) RoundTrip

func (fn RoundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error)

type ServerConn deprecated

type ServerConn struct {
	// contains filtered or unexported fields
}

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.

func NewServerConn deprecated

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

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 (*ServerConn) Close

func (sc *ServerConn) Close() error

Close calls Hijack and then also closes the underlying connection.

func (*ServerConn) Hijack

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

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 Read or Write is in progress.

func (*ServerConn) Pending

func (sc *ServerConn) Pending() int

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

func (*ServerConn) Read

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

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 (*ServerConn) Write

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

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 Read side.

Jump to

Keyboard shortcuts

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