-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrequest.put.go
90 lines (78 loc) · 2.16 KB
/
request.put.go
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package braid
import (
"bufio"
"bytes"
"context"
"fmt"
"net/http"
"strconv"
"strings"
"github.com/pkg/errors"
)
type PutRequest struct {
ContentType string
Accept string
Version string
Parents []string
Patches []Patch
}
// Creates an *http.Request representing the given Tx that follows the Braid-HTTP
// specification for sending transactions/patches to peers.
func MakePutRequest(ctx context.Context, dialAddr string, opts PutRequest) (*http.Request, error) {
var patchBytes [][]byte
for _, patch := range opts.Patches {
bs, err := patch.MarshalRequest()
if err != nil {
return nil, err
}
patchBytes = append(patchBytes, bs)
}
body := bytes.NewBuffer(bytes.Join(patchBytes, []byte("\n\n")))
req, err := http.NewRequestWithContext(ctx, "PUT", dialAddr, body)
if err != nil {
return nil, errors.WithStack(err)
}
req.Header.Set("Version", opts.Version)
req.Header.Set("Content-Type", opts.ContentType)
req.Header.Set("Content-Length", fmt.Sprintf("%v", body.Len()))
if opts.Accept != "" {
req.Header.Set("Accept", opts.Accept)
}
req.Header.Set("Parents", strings.Join(opts.Parents, ","))
req.Header.Set("Patches", fmt.Sprintf("%v", len(opts.Patches)))
return req, nil
}
func ReadPutRequest(r *http.Request) (*PutRequest, error) {
contentType := r.Header.Get("Content-Type")
accept := r.Header.Get("Accept")
version := r.Header.Get("Version")
parents := strings.Split(r.Header.Get("Parents"), ",")
for i := range parents {
parents[i] = strings.TrimSpace(parents[i])
}
numPatchesStr := r.Header.Get("Patches")
if strings.TrimSpace(numPatchesStr) == "" {
return nil, errors.New("missing Patches header")
}
numPatches, err := strconv.ParseUint(numPatchesStr, 10, 64)
if err != nil {
return nil, errors.Wrap(err, "bad Patches header")
}
reader := bufio.NewReader(r.Body)
var patches []Patch
for i := uint64(0); i < numPatches; i++ {
var patch Patch
err := patch.UnmarshalRequest(reader)
if err != nil {
return nil, err
}
patches = append(patches, patch)
}
return &PutRequest{
ContentType: contentType,
Accept: accept,
Version: version,
Parents: parents,
Patches: patches,
}, nil
}