For incoming requests in an HTTP server, instead of cycling through the headers and body to get the information, we can use the DumpRequest util from the httputil standard library. Like so:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"

)

func main() {
	http.HandleFunc("/test", Handler)
	
	log.Println("Listening on 127.0.0.1:8080")
	log.Fatal(http.ListenAndServe("127.0.0.1:8080", nil))
}

func Handler(w http.ResponseWriter, r *http.Request) {
	log.Println("New request:")
	requestDump, _ := httputil.DumpRequest(r, true)
	fmt.Println(string(requestDump))
}

This will return something like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
2021/03/16 13:26:45 Listening on 127.0.0.1:8080
2021/03/16 13:26:49 New request:

POST /test HTTP/1.0
Host: newsletter-curator.segrob.local
Connection: close
Accept-Encoding: gzip, deflate, br
Connection: close
Content-Length: 84
Content-Type: application/json
Postman-Token: 7086c763-2aa0-43e2-80c6-ae663e399d61
User-Agent: PostmanRuntime/7.26.8
X-Forwarded-For: 127.0.0.1
X-Forwarded-Proto: http
X-Real-Ip: 127.0.0.1

{
    "action" : "block",
    "mailbox_id": "potato"
}

We can also get the raw info for external requests and their responses with DumpRequestOut and DumpResponse. Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main

import (
	"fmt"
	"log"
	"strings"
	"net/http"
	"net/http/httputil"
)

func main{
	outgoing_req, _ := http.NewRequest("POST", "/testing", strings.NewReader("test"))

	// dump request
	req_dump, _ := httputil.DumpRequestOut(outgoing_req, true)
	fmt.Println(string(req_dump))

	// execute request
	resp, err := http.DefaultClient.Do(outgoing_req)
	if err != nil {
		log.Println(err)
	}

	defer outgoing_req.Body.Close()

	// ...

	// dump response
	dump_resp, _ := httputil.DumpResponse(resp, true)
	fmt.Println(string(dump_resp))
}