feat(14-01): fetchguard client covers PUT, multipart, bearer and a trusted mode
- TrustedMode (declared after PublicOnlyMode) lifts the scheme, host and dial checks for Client only - PutJSON, PostMultipart with FormField/FormFile, Bearer - tests for modes, redirects, multipart order, body cap and the scheme guard - README, root modules row and outbound HTTP docs describe the client and its test seam
This commit is contained in:
@@ -4,6 +4,9 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/fetchguard"
|
||||
@@ -50,3 +53,44 @@ func ExampleFetch() {
|
||||
// invalid_url https://%zz
|
||||
// 10485760 10s
|
||||
}
|
||||
|
||||
// stubVendor stands in for a vendor API in the example; tests use the tide
|
||||
// upstream fake the same way.
|
||||
type stubVendor struct{}
|
||||
|
||||
func (stubVendor) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
body := `{"id":42}`
|
||||
if r.Header.Get("Authorization") != "Bearer example-token" {
|
||||
body = `{"error":"unauthorized"}`
|
||||
}
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusCreated,
|
||||
Header: http.Header{"Content-Type": {"application/json"}},
|
||||
Body: io.NopCloser(strings.NewReader(body)),
|
||||
Request: r,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ExampleClient_PostJSON() {
|
||||
client, err := fetchguard.NewClient(fetchguard.Policy{
|
||||
Mode: fetchguard.AllowHostsMode,
|
||||
AllowHosts: []string{"api.example.com"},
|
||||
Timeout: 10 * time.Second,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
header := http.Header{}
|
||||
header.Set("Authorization", fetchguard.Bearer("example-token"))
|
||||
|
||||
// Production code passes its own context; the example routes the call to
|
||||
// a stub instead of the network.
|
||||
ctx := fetchguard.WithTransport(context.Background(), stubVendor{})
|
||||
res, err := client.PostJSON(ctx, "https://api.example.com/v1/items", header, map[string]string{"name": "widget"})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(res.StatusCode, string(res.Body))
|
||||
// Output:
|
||||
// 201 {"id":42}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user