Skip to content

Body length 0 error with basic example #28

@eest

Description

@eest

Hello,

Trying out the library I looked at the example in the README and came up with this as a basic example for using a POST request:

package main

import (
	"bytes"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/httptest"

	"github.com/jbowes/httpsig"
)

func main() {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Printf("%#v\n", r.Header)
		body, _ := io.ReadAll(r.Body)
		fmt.Fprintf(w, "Hello, client: %s", body)
	}))
	defer ts.Close()

	privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		log.Fatal(err)
	}

	//client := http.Client{}
	client := http.Client{
		// Wrap the transport:
		Transport: httpsig.NewSignTransport(http.DefaultTransport,
			httpsig.WithSignEcdsaP256Sha256("key1", privKey)),
	}

	data := map[string]string{
		"hello": "world",
	}

	b, err := json.Marshal(data)
	if err != nil {
		log.Fatal(err)
	}

	buf := bytes.NewReader(b)

	resp, err := client.Post(ts.URL, "application/json", buf)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

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

	fmt.Println(string(body))
}

Trying to run this results in the following output:

go run .
2023/10/23 23:21:20 Post "http://127.0.0.1:55020": http: ContentLength=17 with Body length 0
exit status 1

I think the problem is that

r.Body = io.NopCloser(bytes.NewReader(b.Bytes()))
... should be setting nr.Body, not r.Body. I think the reason for this is the function returns transport.RoundTrip(nr) which at that point holds a reference to the original (and at that point consumed) r.Body.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions