Skip to content

Commit 90dbfe5

Browse files
committed
feat: SCA-151 add support for gzipped HTTP requests and MaxSbomVersion handling
- Introduced `gzipped_body` for gzipped request body support. - Added `MaxSbomVersion` to `ScanTask` and related models. - Implemented conditional behavior in SBOM commit based on `MaxSbomVersion`.
1 parent 248433d commit 90dbfe5

6 files changed

Lines changed: 91 additions & 4 deletions

File tree

api/client.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ package api
33
import (
44
"context"
55
"encoding/json"
6-
"github.com/murphysecurity/murphysec/utils/must"
7-
"github.com/murphysecurity/murphysec/version"
8-
"go.uber.org/zap"
96
"io"
107
"net/http"
118
"net/url"
129
"path"
1310
"reflect"
1411
"strings"
12+
13+
"github.com/murphysecurity/murphysec/utils/must"
14+
"github.com/murphysecurity/murphysec/version"
15+
"go.uber.org/zap"
1516
)
1617

1718
var _DefaultClient *Client
@@ -113,6 +114,14 @@ func (c *Client) POST(url *url.URL, body io.Reader) *http.Request {
113114
return must.A(http.NewRequest(http.MethodPost, url.String(), body))
114115
}
115116

117+
func (c *Client) PostSpecialJson(url *url.URL, data any) *http.Request {
118+
var body = NewGzippedBody(NewJsonRequestBody(data))
119+
u := c.POST(url, body)
120+
u.GetBody = body.GetBody
121+
u.Header.Set("Content-Type", "application/vnd.murphysec.sbom.v1")
122+
return u
123+
}
124+
116125
func (c *Client) PostJson(url *url.URL, data any) *http.Request {
117126
var body = NewJsonRequestBody(data)
118127
u := c.POST(url, body)

api/create_sub_task.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ type CreateSubTaskResponse struct {
4343
SubtaskID string `json:"subtask_id"` // 子任务ID
4444
TaskName string `json:"task_name"` // 任务名称
4545
AlertMessage string `json:"alert_message"`
46+
47+
MaxSbomVersion string `json:"max_sbom_version"`
4648
}
4749

4850
func CreateSubTask(client *Client, request *CreateSubTaskRequest) (*CreateSubTaskResponse, error) {

api/gzipped_body.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package api
2+
3+
import (
4+
"bytes"
5+
"compress/gzip"
6+
"io"
7+
)
8+
9+
func NewGzippedBody(body interface {
10+
GetBody() (io.ReadCloser, error)
11+
io.ReadCloser
12+
}) interface {
13+
GetBody() (io.ReadCloser, error)
14+
io.ReadCloser
15+
} {
16+
return &gzippedBody{body: body, reader: body}
17+
}
18+
19+
type gzippedBody struct {
20+
buf bytes.Buffer
21+
end bool
22+
gzipWriter *gzip.Writer
23+
body interface {
24+
GetBody() (io.ReadCloser, error)
25+
io.ReadCloser
26+
}
27+
reader io.ReadCloser
28+
}
29+
30+
func (g *gzippedBody) GetBody() (io.ReadCloser, error) {
31+
reader, e := g.body.GetBody()
32+
if e != nil {
33+
return nil, e
34+
}
35+
return &gzippedBody{body: g.body, reader: reader}, nil
36+
}
37+
38+
func (g *gzippedBody) Read(p []byte) (n int, err error) {
39+
if g.gzipWriter == nil {
40+
g.gzipWriter = gzip.NewWriter(&g.buf)
41+
}
42+
for g.buf.Available() == 0 {
43+
if g.end {
44+
return 0, io.EOF
45+
}
46+
_, e := io.CopyN(g.gzipWriter, g.reader, 16*1024)
47+
if e == io.EOF {
48+
g.end = true
49+
e = g.gzipWriter.Close()
50+
if e != nil {
51+
return 0, e
52+
}
53+
}
54+
if e != nil {
55+
return 0, e
56+
}
57+
}
58+
59+
return g.reader.Read(p)
60+
}
61+
62+
func (g *gzippedBody) Close() error {
63+
return g.reader.Close()
64+
}

api/sbom_commit.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bufio"
55
"context"
66
"encoding/json"
7+
"net/http"
78
"os"
89

910
"github.com/murphysecurity/murphysec/env"
@@ -40,5 +41,11 @@ func SubmitSBOM(ctx context.Context, client *Client) error {
4041
must.M(bf.Flush())
4142
must.M(f.Close())
4243
}
43-
return client.DoJson(client.PostJson(joinURL(client.baseUrl, "/platform3/v3/client/upload_data"), req), nil)
44+
var body *http.Request
45+
if task.MaxSbomVersion == "v1" {
46+
body = client.PostSpecialJson(joinURL(client.baseUrl, "/platform3/v3/client/upload_data"), req)
47+
} else {
48+
body = client.PostJson(joinURL(client.baseUrl, "/platform3/v3/client/upload_data"), req)
49+
}
50+
return client.DoJson(body, nil)
4451
}

cmd/murphy/internal/scan/scan.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ func envScan(ctx context.Context) (task *model.ScanTask, e error) {
7979
TaskId: createTaskResp.TaskID,
8080
SubtaskId: createTaskResp.SubtaskID,
8181
SubtaskName: createSubtask.ProjectName,
82+
83+
MaxSbomVersion: createTaskResp.MaxSbomVersion,
8284
}
8385
ctx = model.WithScanTask(ctx, task)
8486
e = envinspection.InspectEnv(ctx, scanProcess)
@@ -217,6 +219,7 @@ func scan(ctx context.Context, dir string, accessType model.AccessType, mode mod
217219
IsNoBuild: noBuild,
218220
IsAutonomous: scanCodeHash,
219221
MavenModuleName: mavenModuleName,
222+
MaxSbomVersion: createTaskResp.MaxSbomVersion,
220223
}
221224
if gitSummary != nil {
222225
task.GitUrl = gitSummary.RemoteAddr

model/scantask.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ type ScanTask struct {
2828
AutoBuildFailedCount int
2929

3030
ProjectLicense ProjectLicense
31+
32+
MaxSbomVersion string
3133
}
3234

3335
func (s *ScanTask) BuildInspectionTask(dir string) *InspectionTask {

0 commit comments

Comments
 (0)