aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-04-24 15:09:33 +0700
committerShulhan <ms@kilabit.info>2024-04-24 15:09:33 +0700
commitf5aa31cc48e78816d6eec75a03be4abdd7cb6649 (patch)
tree8692e5e0b186407ec779b137397aa21fa81e790d
parent9e7d6accdee5e0620bd9605d0cb225444671e1ce (diff)
downloadgorankusu-f5aa31cc48e78816d6eec75a03be4abdd7cb6649.tar.xz
all: refactoring form input for multipart form-data
This changes replace handling type for storing multipart form-data from "map[string][]byte" to [*multipart.Form] based on changes on module "pakakeh.go".
-rw-r--r--example.go14
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--http_attack_handler.go13
-rw-r--r--http_params_converter.go4
-rw-r--r--key_form_input.go80
-rw-r--r--testdata/target_http_run_formkindfile_test.txt40
7 files changed, 89 insertions, 68 deletions
diff --git a/example.go b/example.go
index c17aab9..00ec3a9 100644
--- a/example.go
+++ b/example.go
@@ -554,19 +554,7 @@ func (ex *Example) pathExampleRawbodyJSON(epr *libhttp.EndpointRequest) (resbody
}
func (ex *Example) pathExampleUpload(epr *libhttp.EndpointRequest) (resb []byte, err error) {
- var logp = `pathExampleUpload`
-
- var res = libhttp.EndpointResponse{}
-
- res.Code = http.StatusOK
- res.Data = epr.HTTPRequest.MultipartForm.Value
-
- resb, err = json.MarshalIndent(res, ``, ` `)
- if err != nil {
- return nil, fmt.Errorf(`%s: %w`, logp, err)
- }
-
- return resb, nil
+ return epr.RequestBody, nil
}
func (ex *Example) handleWSExampleGet(_ context.Context, req *websocket.Request) (res websocket.Response) {
diff --git a/go.mod b/go.mod
index 68ac808..5752026 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@ go 1.21
require (
git.sr.ht/~shulhan/ciigo v0.12.0
- git.sr.ht/~shulhan/pakakeh.go v0.54.0
+ git.sr.ht/~shulhan/pakakeh.go v0.54.1-0.20240424075702-072a5866613a
github.com/tsenart/vegeta/v12 v12.11.1
golang.org/x/tools v0.20.0
)
diff --git a/go.sum b/go.sum
index 7b48edb..6536a6d 100644
--- a/go.sum
+++ b/go.sum
@@ -2,8 +2,8 @@ git.sr.ht/~shulhan/asciidoctor-go v0.5.2 h1:tjG/NQJ1om2F70L7DwOvmr+n1kfgk9xhIBX+
git.sr.ht/~shulhan/asciidoctor-go v0.5.2/go.mod h1:fHXUiw7IbOOMyoHHvnd351Jini/MNZgutiFTtsCQ+Yk=
git.sr.ht/~shulhan/ciigo v0.12.0 h1:LSjFcA4nwJvPU2Xn/Mlz9520XSSvt6oyUtN1ARu0m6o=
git.sr.ht/~shulhan/ciigo v0.12.0/go.mod h1:v5xCYhQK4JRJ7ZuW2J7lUknDLwzaNknZCw3jqaMDSYA=
-git.sr.ht/~shulhan/pakakeh.go v0.54.0 h1:pwTQiJSyE5xTaWNR0FnWsszJ+0Z5hB2ufNLXcy8z0y8=
-git.sr.ht/~shulhan/pakakeh.go v0.54.0/go.mod h1:ys7WNtXm03x0M59oqrqBjXnc+wRCX8JBXyE/W8+KVbw=
+git.sr.ht/~shulhan/pakakeh.go v0.54.1-0.20240424075702-072a5866613a h1:0UUJkeUzFGYdnoIpGi4n+ZGZG4MnQfg8YBZ1jQuhBDY=
+git.sr.ht/~shulhan/pakakeh.go v0.54.1-0.20240424075702-072a5866613a/go.mod h1:hJHTZtPS9bOKMNtLljEdJZKHj3eOAXe7fuHcfI6vceY=
github.com/bmizerany/perks v0.0.0-20230307044200-03f9df79da1e h1:mWOqoK5jV13ChKf/aF3plwQ96laasTJgZi4f1aSOu+M=
github.com/bmizerany/perks v0.0.0-20230307044200-03f9df79da1e/go.mod h1:ac9efd0D1fsDb3EJvhqgXRbFx7bs2wqZ10HQPeU8U/Q=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
diff --git a/http_attack_handler.go b/http_attack_handler.go
index fc5656b..c39e242 100644
--- a/http_attack_handler.go
+++ b/http_attack_handler.go
@@ -6,6 +6,7 @@ package gorankusu
import (
"encoding/json"
"fmt"
+ "mime/multipart"
libhttp "git.sr.ht/~shulhan/pakakeh.go/lib/http"
vegeta "github.com/tsenart/vegeta/v12/lib"
@@ -58,15 +59,17 @@ func DefaultHTTPAttack() HTTPAttackHandler {
case libhttp.RequestTypeMultipartForm:
var (
- params map[string][]byte
+ params *multipart.Form
body string
)
- params = rr.HTTPTarget.Params.ToMultipartFormData()
- contentType, body, err = libhttp.GenerateFormData(params)
+ params, err = rr.HTTPTarget.Params.ToMultipartFormData()
if err == nil {
- vegetaTarget.Body = []byte(body)
- vegetaTarget.Header.Set(libhttp.HeaderContentType, contentType)
+ contentType, body, err = libhttp.GenerateFormData(params)
+ if err == nil {
+ vegetaTarget.Body = []byte(body)
+ vegetaTarget.Header.Set(libhttp.HeaderContentType, contentType)
+ }
}
}
}
diff --git a/http_params_converter.go b/http_params_converter.go
index 9a4ef91..b885f64 100644
--- a/http_params_converter.go
+++ b/http_params_converter.go
@@ -18,10 +18,10 @@ func DefaultParamsConverter() HTTPParamsConverter {
case libhttp.RequestTypeJSON:
params = target.Params.ToJSONObject()
case libhttp.RequestTypeMultipartForm:
- params = target.Params.ToMultipartFormData()
+ params, err = target.Params.ToMultipartFormData()
default:
params = target.Params.ToURLValues()
}
- return params, nil
+ return params, err
}
}
diff --git a/key_form_input.go b/key_form_input.go
index 61cbe41..7a0c571 100644
--- a/key_form_input.go
+++ b/key_form_input.go
@@ -4,11 +4,14 @@
package gorankusu
import (
+ "fmt"
+ "mime/multipart"
"net/http"
"net/url"
"strconv"
"strings"
+ libhttp "git.sr.ht/~shulhan/pakakeh.go/lib/http"
"git.sr.ht/~shulhan/pakakeh.go/lib/math/big"
)
@@ -69,38 +72,67 @@ func (kfi KeyFormInput) ToJSONObject() (data map[string]interface{}) {
return data
}
-// ToMultipartFormData convert the KeyFormInput into map of string and raw
-// bytes.
-func (kfi KeyFormInput) ToMultipartFormData() (data map[string][]byte) {
- data = make(map[string][]byte, len(kfi))
+// ToMultipartFormData convert the KeyFormInput into [*multipart.Form].
+func (kfi KeyFormInput) ToMultipartFormData() (data *multipart.Form, err error) {
+ var logp = `ToMultipartFormData`
+
+ data = &multipart.Form{
+ Value: map[string][]string{},
+ File: map[string][]*multipart.FileHeader{},
+ }
if len(kfi) == 0 {
- return data
+ return data, nil
}
- for k, fi := range kfi {
- if fi.Kind == FormInputKindFile {
- var name string
- if len(fi.Filename) != 0 {
- name = fi.FormDataName(FormDataFilename)
- data[name] = []byte(fi.Filename)
- }
- if len(fi.Filetype) != 0 {
- name = fi.FormDataName(FormDataFiletype)
- data[name] = []byte(fi.Filetype)
- }
- name = fi.FormDataName(FormDataFilesize)
- data[name] = []byte(strconv.FormatInt(fi.Filesize, 10))
+ var (
+ k string
+ fi FormInput
+ listValue []string
+ )
+ for k, fi = range kfi {
+ if fi.Kind != FormInputKindFile {
+ listValue = data.Value[k]
+ listValue = append(listValue, fi.Value)
+ data.Value[k] = listValue
+ continue
+ }
+
+ // Process form with type File.
- name = fi.FormDataName(FormDataFilemodms)
- data[name] = []byte(strconv.FormatInt(fi.Filemodms, 10))
+ var (
+ filename string
+ fieldname string
+ )
- name = fi.FormDataName(FormDataFilecontent)
- data[name] = []byte(fi.Value)
+ if len(fi.Filename) != 0 {
+ filename = fi.Filename
} else {
- data[k] = []byte(fi.Value)
+ filename = k
}
+
+ if len(fi.Filetype) != 0 {
+ fieldname = fi.FormDataName(FormDataFiletype)
+ data.Value[fieldname] = []string{fi.Filetype}
+ }
+
+ fieldname = fi.FormDataName(FormDataFilesize)
+ data.Value[fieldname] = []string{strconv.FormatInt(fi.Filesize, 10)}
+
+ fieldname = fi.FormDataName(FormDataFilemodms)
+ data.Value[fieldname] = []string{strconv.FormatInt(fi.Filemodms, 10)}
+
+ var fh *multipart.FileHeader
+
+ fh, err = libhttp.CreateMultipartFileHeader(filename, []byte(fi.Value))
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ var listFH = data.File[k]
+ listFH = append(listFH, fh)
+ data.File[k] = listFH
}
- return data
+ return data, nil
}
// ToURLValues convert the KeyFormInput to the standard url.Values.
diff --git a/testdata/target_http_run_formkindfile_test.txt b/testdata/target_http_run_formkindfile_test.txt
index 9dbf1ba..8932b1c 100644
--- a/testdata/target_http_run_formkindfile_test.txt
+++ b/testdata/target_http_run_formkindfile_test.txt
@@ -24,26 +24,24 @@ Test data for testing running HTTP with form kind is file (uploading file).
<<< valid:RunResponse.DumpResponse
HTTP/1.1 200 OK
-Content-Length: 256
+Content-Length: 637
Content-Type: application/json
-{
- "data": {
- "filecontent": [
- "Q29udGVudCBvZiBmaWxlIHVwbG9hZA=="
- ],
- "filemodms": [
- "0"
- ],
- "filesize": [
- "22"
- ],
- "filetype": [
- "text/plain"
- ],
- "name": [
- "test.txt"
- ]
- },
- "code": 200
-}
+--6f72616e6b7573756f72616e6b7573756f72616e6b7573756f72616e6b75
+Content-Disposition: form-data; name="file"; filename="test.txt"
+Content-Type: application/octet-stream
+
+Q29udGVudCBvZiBmaWxlIHVwbG9hZA==
+--6f72616e6b7573756f72616e6b7573756f72616e6b7573756f72616e6b75
+Content-Disposition: form-data; name="filemodms"
+
+0
+--6f72616e6b7573756f72616e6b7573756f72616e6b7573756f72616e6b75
+Content-Disposition: form-data; name="filesize"
+
+22
+--6f72616e6b7573756f72616e6b7573756f72616e6b7573756f72616e6b75
+Content-Disposition: form-data; name="filetype"
+
+text/plain
+--6f72616e6b7573756f72616e6b7573756f72616e6b7573756f72616e6b75--