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

Function AdminAPIRequest

cmd/commandfuncs.go:774–854  ·  view source on GitHub ↗

AdminAPIRequest makes an API request according to the CLI flags given, with the given HTTP method and request URI. If body is non-nil, it will be assumed to be Content-Type application/json. The caller should close the response body. Should only be used by Caddy CLI commands which need to interact w

(adminAddr, method, uri string, headers http.Header, body io.Reader)

Source from the content-addressed store, hash-verified

772// the response body. Should only be used by Caddy CLI commands which
773// need to interact with a running instance of Caddy via the admin API.
774func AdminAPIRequest(adminAddr, method, uri string, headers http.Header, body io.Reader) (*http.Response, error) {
775 parsedAddr, err := caddy.ParseNetworkAddress(adminAddr)
776 if err != nil || parsedAddr.PortRangeSize() > 1 {
777 return nil, fmt.Errorf("invalid admin address %s: %v", adminAddr, err)
778 }
779 origin := "http://" + parsedAddr.JoinHostPort(0)
780 if parsedAddr.IsUnixNetwork() {
781 origin = "http://127.0.0.1" // bogus host is a hack so that http.NewRequest() is happy
782
783 // the unix address at this point might still contain the optional
784 // unix socket permissions, which are part of the address/host.
785 // those need to be removed first, as they aren't part of the
786 // resulting unix file path
787 addr, _, err := internal.SplitUnixSocketPermissionsBits(parsedAddr.Host)
788 if err != nil {
789 return nil, err
790 }
791 parsedAddr.Host = addr
792 } else if parsedAddr.IsFdNetwork() {
793 origin = "http://127.0.0.1"
794 }
795
796 // form the request
797 req, err := http.NewRequest(method, origin+uri, body)
798 if err != nil {
799 return nil, fmt.Errorf("making request: %v", err)
800 }
801 if parsedAddr.IsUnixNetwork() || parsedAddr.IsFdNetwork() {
802 // We used to conform to RFC 2616 Section 14.26 which requires
803 // an empty host header when there is no host, as is the case
804 // with unix sockets and socket fds. However, Go required a
805 // Host value so we used a hack of a space character as the host
806 // (it would see the Host was non-empty, then trim the space later).
807 // As of Go 1.20.6 (July 2023), this hack no longer works. See:
808 // https://github.com/golang/go/issues/60374
809 // See also the discussion here:
810 // https://github.com/golang/go/issues/61431
811 //
812 // After that, we now require a Host value of either 127.0.0.1
813 // or ::1 if one is set. Above I choose to use 127.0.0.1. Even
814 // though the value should be completely irrelevant (it could be
815 // "srldkjfsd"), if for some reason the Host *is* used, at least
816 // we can have some reasonable assurance it will stay on the local
817 // machine and that browsers, if they ever allow access to unix
818 // sockets, can still enforce CORS, ensuring it is still coming
819 // from the local machine.
820 } else {
821 req.Header.Set("Origin", origin)
822 }
823 if body != nil {
824 req.Header.Set("Content-Type", "application/json")
825 }
826 maps.Copy(req.Header, headers)
827
828 // make an HTTP client that dials our network type, since admin
829 // endpoints aren't always TCP, which is what the default transport
830 // expects; reuse is not of particular concern here
831 client := http.Client{

Callers 2

cmdStopFunction · 0.85
cmdReloadFunction · 0.85

Calls 7

PortRangeSizeMethod · 0.80
JoinHostPortMethod · 0.80
IsUnixNetworkMethod · 0.80
IsFdNetworkMethod · 0.80
DoMethod · 0.80
SetMethod · 0.45

Tested by

no test coverage detected