summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gorankusu.go76
-rw-r--r--http_run_handler.go86
-rw-r--r--http_target.go13
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 {