aboutsummaryrefslogtreecommitdiffstats
path: root/syz-cluster/pkg/api/http.go
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-04-10 15:09:06 +0200
committerAleksandr Nogikh <nogikh@google.com>2025-04-11 10:07:50 +0000
commit4d9e57eb150fee8d24ff32fb4a8a414c77d246e6 (patch)
tree9214e0b17c3aa833b9f812b52c5ecf7b28b4d741 /syz-cluster/pkg/api/http.go
parentdfb5be349af98db984a0944f49896f454e4bc8a6 (diff)
syz-cluster: provide API for uploading artifacts archive
The archive would be a useful source of debugging information. Provide an HTTP endpoint that accepts a multipart form request with the archived data. Provide an *api.Client method to encapsulate the encoding of the data. Add a test.
Diffstat (limited to 'syz-cluster/pkg/api/http.go')
-rw-r--r--syz-cluster/pkg/api/http.go24
1 files changed, 24 insertions, 0 deletions
diff --git a/syz-cluster/pkg/api/http.go b/syz-cluster/pkg/api/http.go
index 420b787a7..4523b5374 100644
--- a/syz-cluster/pkg/api/http.go
+++ b/syz-cluster/pkg/api/http.go
@@ -7,7 +7,9 @@ import (
"bytes"
"context"
"encoding/json"
+ "fmt"
"io"
+ "mime/multipart"
"net/http"
)
@@ -32,6 +34,28 @@ func postJSON[Req any, Resp any](ctx context.Context, url string, req *Req) (*Re
return finishRequest[Resp](httpReq)
}
+func postMultiPartFile[Resp any](ctx context.Context, url string, reader io.Reader) (*Resp, error) {
+ // TODO: this will work well only up to some size of the file. We need a pipe and a goroutine.
+ body := &bytes.Buffer{}
+ writer := multipart.NewWriter(body)
+ part, err := writer.CreateFormFile("content", "content")
+ if err != nil {
+ return nil, fmt.Errorf("failed to create a form file part: %w", err)
+ }
+ if _, err := io.Copy(part, reader); err != nil {
+ return nil, err
+ }
+ if err := writer.Close(); err != nil {
+ return nil, err
+ }
+ httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, body)
+ if err != nil {
+ return nil, err
+ }
+ httpReq.Header.Set("Content-Type", writer.FormDataContentType())
+ return finishRequest[Resp](httpReq)
+}
+
func ReplyJSON[T any](w http.ResponseWriter, resp T) {
w.Header().Set("Content-Type", "application/json")
err := json.NewEncoder(w).Encode(resp)