diff options
| -rw-r--r-- | gorankusu.go | 76 | ||||
| -rw-r--r-- | http_run_handler.go | 86 | ||||
| -rw-r--r-- | http_target.go | 13 |
3 files changed, 96 insertions, 79 deletions
diff --git a/gorankusu.go b/gorankusu.go index 2d49e1d..3d5975a 100644 --- a/gorankusu.go +++ b/gorankusu.go @@ -4,9 +4,7 @@ package gorankusu import ( - "bytes" "fmt" - "io" "net/http" "os" "strings" @@ -185,17 +183,9 @@ func (gorankusu *Gorankusu) RunHTTP(req *RunRequest) (res *RunResponse, err erro return nil, errInvalidHTTPTarget(req.HTTPTarget.ID) } - if origHTTPTarget.Run == nil { - req.Target.BaseURL = origTarget.BaseURL - req.Target.Name = origTarget.Name - - req.HTTPTarget.refCopy(origHTTPTarget) + req = generateRunRequest(gorankusu.Env, req, origTarget, origHTTPTarget) - res, err = gorankusu.runHTTPTarget(req) - } else { - req = generateRunRequest(gorankusu.Env, req, origTarget, origHTTPTarget) - res, err = req.HTTPTarget.Run(req) - } + res, err = req.HTTPTarget.Run(req) if err != nil { return nil, err } @@ -325,68 +315,6 @@ func (gorankusu *Gorankusu) getTargetByResultFilename(name string) (t *Target, h return t, ht } -// runHTTPTarget default [HTTPTarget.Run] handler that generate HTTP request -// and send it to the target. -func (gorankusu *Gorankusu) runHTTPTarget(rr *RunRequest) (res *RunResponse, err error) { - var ( - logp = `runHTTPTarget` - headers = rr.HTTPTarget.Headers.ToHTTPHeader() - ) - - httpcOpts := &libhttp.ClientOptions{ - ServerUrl: rr.Target.BaseURL, - AllowInsecure: true, - } - - httpc := libhttp.NewClient(httpcOpts) - - var params any - - if !rr.HTTPTarget.WithRawBody { - rr.HTTPTarget.paramsToPath() - - params, err = rr.HTTPTarget.ParamsConverter(&rr.HTTPTarget) - if err != nil { - return nil, fmt.Errorf(`%s: %w`, logp, err) - } - } - - res = &RunResponse{} - - httpRequest, err := httpc.GenerateHttpRequest( - rr.HTTPTarget.Method, - rr.HTTPTarget.Path, - rr.HTTPTarget.RequestType, - headers, - params, - ) - if err != nil { - return nil, fmt.Errorf("%s: %w", logp, err) - } - - if rr.HTTPTarget.WithRawBody { - httpRequest.Body = io.NopCloser(bytes.NewReader(rr.HTTPTarget.RawBody)) - httpRequest.ContentLength = int64(len(rr.HTTPTarget.RawBody)) - } - - err = res.SetHTTPRequest(rr.HTTPTarget.RequestDumper, httpRequest) - if err != nil { - return nil, fmt.Errorf("%s: %w", logp, err) - } - - httpResponse, _, err := httpc.Do(httpRequest) - if err != nil { - return nil, fmt.Errorf("%s: %w", logp, err) - } - - err = res.SetHTTPResponse(rr.HTTPTarget.ResponseDumper, httpResponse) - if err != nil { - return nil, fmt.Errorf("%s: %w", logp, err) - } - - return res, nil -} - // scanResultsDir scan the environment's ResultsDir for the past attack // results and add it to each target based on ID on file name. // diff --git a/http_run_handler.go b/http_run_handler.go new file mode 100644 index 0000000..00212ec --- /dev/null +++ b/http_run_handler.go @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2024 M. Shulhan <ms@kilabit.info> +// SPDX-License-Identifier: GPL-3.0-or-later + +package gorankusu + +import ( + "bytes" + "fmt" + "io" + "net/http" + + libhttp "github.com/shuLhan/share/lib/http" +) + +// HTTPRunHandler define the function type that will be called when client +// send request to run the HTTP target. +type HTTPRunHandler func(rr *RunRequest) (runres *RunResponse, err error) + +// DefaultHTTPRun default [HTTPTarget.Run] handler that generate +// [http.Request], send it to the target, and store and dump them into +// [RunResponse]. +func DefaultHTTPRun() HTTPRunHandler { + return func(rr *RunRequest) (res *RunResponse, err error) { + var ( + logp = `DefaultHTTPRun` + httpcOpts = &libhttp.ClientOptions{ + ServerUrl: rr.Target.BaseURL, + AllowInsecure: true, + } + httpc = libhttp.NewClient(httpcOpts) + params any + ) + + if !rr.HTTPTarget.WithRawBody { + rr.HTTPTarget.paramsToPath() + + params, err = rr.HTTPTarget.ParamsConverter(&rr.HTTPTarget) + if err != nil { + return nil, fmt.Errorf(`%s: %w`, logp, err) + } + } + + var ( + headers = rr.HTTPTarget.Headers.ToHTTPHeader() + + httpRequest *http.Request + ) + + httpRequest, err = httpc.GenerateHttpRequest( + rr.HTTPTarget.Method, + rr.HTTPTarget.Path, + rr.HTTPTarget.RequestType, + headers, + params, + ) + if err != nil { + return nil, fmt.Errorf(`%s: %w`, logp, err) + } + + if rr.HTTPTarget.WithRawBody { + httpRequest.Body = io.NopCloser(bytes.NewReader(rr.HTTPTarget.RawBody)) + httpRequest.ContentLength = int64(len(rr.HTTPTarget.RawBody)) + } + + res = &RunResponse{} + + err = res.SetHTTPRequest(rr.HTTPTarget.RequestDumper, httpRequest) + if err != nil { + return nil, fmt.Errorf(`%s: %w`, logp, err) + } + + var httpResponse *http.Response + + httpResponse, _, err = httpc.Do(httpRequest) + if err != nil { + return nil, fmt.Errorf(`%s: %w`, logp, err) + } + + err = res.SetHTTPResponse(rr.HTTPTarget.ResponseDumper, httpResponse) + if err != nil { + return nil, fmt.Errorf(`%s: %w`, logp, err) + } + + return res, nil + } +} diff --git a/http_target.go b/http_target.go index 6eee3aa..444f3a9 100644 --- a/http_target.go +++ b/http_target.go @@ -17,10 +17,6 @@ import ( libpath "github.com/shuLhan/share/lib/path" ) -// HTTPRunHandler define the function type that will be called when client -// send request to run the HTTP target. -type HTTPRunHandler func(rr *RunRequest) (runres *RunResponse, err error) - // HTTPPreAttackHandler define the function type that will be called before // the actual Attack being called. type HTTPPreAttackHandler func(rr *RunRequest) @@ -36,7 +32,11 @@ type HTTPTarget struct { Headers KeyFormInput - Run HTTPRunHandler `json:"-"` + // Run define the handler that will be called when request to run + // HTTPTarget received from client (web user-interface). + // This field is optional, default to [DefaultHTTPRun]. + Run HTTPRunHandler `json:"-"` + PreAttack HTTPPreAttackHandler `json:"-"` // Attack define custom handler to generate [vegeta.Attacker]. @@ -118,6 +118,9 @@ func (ht *HTTPTarget) init() (err error) { if ht.Headers == nil { ht.Headers = KeyFormInput{} } + if ht.Run == nil { + ht.Run = DefaultHTTPRun() + } if ht.Params == nil { ht.Params = KeyFormInput{} } else { |
