MCPcopy
hub / github.com/caddyserver/caddy / prepareRequest

Method prepareRequest

modules/caddyhttp/reverseproxy/reverseproxy.go:762–877  ·  modules/caddyhttp/reverseproxy/reverseproxy.go::Handler.prepareRequest

prepareRequest clones req so that it can be safely modified without changing the original request or introducing data races. It then modifies it so that it is ready to be proxied, except for directing to a specific upstream. This method adjusts headers and other relevant properties of the cloned req

(req *http.Request, repl *caddy.Replacer)

Source from the content-addressed store, hash-verified

760// proxying) regardless of proxy retries. This assumes that no mutations
761// of the cloned request are performed by h during or after proxying.
762func (h Handler) prepareRequest(req *http.Request, repl *caddy.Replacer) (*http.Request, error) {
763 req = cloneRequest(req)
764
765 // if enabled, perform rewrites on the cloned request; if
766 // the method is GET or HEAD, prevent the request body
767 // from being copied to the upstream
768 if h.Rewrite != nil {
769 changed := h.Rewrite.Rewrite(req, repl)
770 if changed && (h.Rewrite.Method == "GET" || h.Rewrite.Method == "HEAD") {
771 req.ContentLength = 0
772 req.Body = nil
773 }
774 }
775
776 // if enabled, buffer client request; this should only be
777 // enabled if the upstream requires it and does not work
778 // with "slow clients" (gunicorn, etc.) - this obviously
779 // has a perf overhead and makes the proxy at risk of
780 // exhausting memory and more susceptible to slowloris
781 // attacks, so it is strongly recommended to only use this
782 // feature if absolutely required, if read timeouts are
783 // set, and if body size is limited
784 if h.RequestBuffers != 0 && req.Body != nil {
785 var readBytes int64
786 req.Body, readBytes = h.bufferedBody(req.Body, h.RequestBuffers)
787 // set Content-Length when body is fully buffered
788 if b, ok := req.Body.(bodyReadCloser); ok && b.body == nil {
789 req.ContentLength = readBytes
790 req.Header.Set("Content-Length", strconv.FormatInt(req.ContentLength, 10))
791 }
792 }
793
794 if req.ContentLength == 0 {
795 req.Body = nil // Issue golang/go#16036: nil Body for http.Transport retries
796 }
797
798 req.Close = false
799
800 // if User-Agent is not set by client, then explicitly
801 // disable it so it's not set to default value by std lib
802 if _, ok := req.Header["User-Agent"]; !ok {
803 req.Header.Set("User-Agent", "")
804 }
805
806 // Indicate if request has been conveyed in early data.
807 // RFC 8470: "An intermediary that forwards a request prior to the
808 // completion of the TLS handshake with its client MUST send it with
809 // the Early-Data header field set to “1” (i.e., it adds it if not
810 // present in the request). An intermediary MUST use the Early-Data
811 // header field if the request might have been subject to a replay and
812 // might already have been forwarded by it or another instance
813 // (see Section 6.2)."
814 if req.TLS != nil && !req.TLS.HandshakeComplete {
815 req.Header.Set("Early-Data", "1")
816 }
817
818 reqUpgradeType := upgradeType(req.Header)
819 removeConnectionHeaders(req.Header)

Callers 1

ServeHTTPMethod · 0.95

Calls 13

bufferedBodyMethod · 0.95
addForwardedHeadersMethod · 0.95
GetVarFunction · 0.92
SetVarFunction · 0.92
cloneRequestFunction · 0.85
upgradeTypeFunction · 0.85
removeConnectionHeadersFunction · 0.85
isWebsocketFunction · 0.85
RewriteMethod · 0.80
DelMethod · 0.80
SetMethod · 0.45

Tested by

no test coverage detected