aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-05-16 13:42:56 +0700
committerShulhan <ms@kilabit.info>2023-05-16 13:42:56 +0700
commit147fd4eb7a76d387a4c23bcac399971b8b099232 (patch)
tree5d8a25ccaa42a8041647eb99737bae97d4968fab
parent361358eec4853cb75600b11a99ad0894dd8e83b0 (diff)
downloadgorankusu-147fd4eb7a76d387a4c23bcac399971b8b099232.tar.xz
all: implement HTTP API to run and cancel attack on HTTP target
This endpoints similar that we have in the WebSocket. The idea is to replace the WebSocket endpoints with this one.
-rw-r--r--http_server.go115
-rw-r--r--trunks.go4
-rw-r--r--websocket_server.go6
3 files changed, 118 insertions, 7 deletions
diff --git a/http_server.go b/http_server.go
index 43d166d..d737352 100644
--- a/http_server.go
+++ b/http_server.go
@@ -21,15 +21,28 @@ var (
ResponseType: libhttp.ResponseTypeJSON,
}
+ apiAttackHttp = libhttp.Endpoint{
+ Method: libhttp.RequestMethodPost,
+ Path: `/_trunks/api/attack/http`,
+ RequestType: libhttp.RequestTypeJSON,
+ ResponseType: libhttp.ResponseTypeJSON,
+ }
+ apiAttackHttpCancel = libhttp.Endpoint{
+ Method: libhttp.RequestMethodDelete,
+ Path: `/_trunks/api/attack/http`,
+ RequestType: libhttp.RequestTypeJSON,
+ ResponseType: libhttp.ResponseTypeJSON,
+ }
+
apiAttackResultDelete = &libhttp.Endpoint{
Method: libhttp.RequestMethodDelete,
- Path: apiAttackResult,
+ Path: pathApiAttackResult,
RequestType: libhttp.RequestTypeJSON,
ResponseType: libhttp.ResponseTypeJSON,
}
apiAttackResultGet = &libhttp.Endpoint{
Method: libhttp.RequestMethodGet,
- Path: apiAttackResult,
+ Path: pathApiAttackResult,
RequestType: libhttp.RequestTypeQuery,
ResponseType: libhttp.ResponseTypeJSON,
}
@@ -97,6 +110,18 @@ func (trunks *Trunks) initHttpServer(isDevelopment bool) (err error) {
return fmt.Errorf("%s: %w", logp, err)
}
+ apiAttackHttp.Call = trunks.apiAttackHttp
+ err = trunks.Httpd.RegisterEndpoint(&apiAttackHttp)
+ if err != nil {
+ return fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ apiAttackHttpCancel.Call = trunks.apiAttackHttpCancel
+ err = trunks.Httpd.RegisterEndpoint(&apiAttackHttpCancel)
+ if err != nil {
+ return fmt.Errorf(`%s: %w`, logp, err)
+ }
+
apiAttackResultDelete.Call = trunks.apiAttackResultDelete
err = trunks.Httpd.RegisterEndpoint(apiAttackResultDelete)
if err != nil {
@@ -142,6 +167,92 @@ func (trunks *Trunks) apiEnvironmentGet(epr *libhttp.EndpointRequest) (resbody [
return json.Marshal(&res)
}
+// apiAttackHttp request to attack HTTP target.
+//
+// Request format,
+//
+// POST /_trunks/api/attack/http
+// Content-Type: application/json
+//
+// <RunRequest>
+//
+// Response format,
+//
+// Content-Type: application/json
+//
+// {"data":<RunRequest>}
+//
+// Response codes,
+// - 200 OK: success.
+// - 500 ERR_INTERNAL: internal server error.
+func (trunks *Trunks) apiAttackHttp(epr *libhttp.EndpointRequest) (resbody []byte, err error) {
+ var (
+ logp = `apiAttackHttp`
+ runRequest = &RunRequest{}
+ )
+
+ err = json.Unmarshal(epr.RequestBody, runRequest)
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ err = trunks.AttackHttp(runRequest)
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ var res = &libhttp.EndpointResponse{}
+ res.Code = http.StatusOK
+ res.Name = `OK_ATTACK_HTTP`
+ res.Data = runRequest
+
+ resbody, err = json.Marshal(res)
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+ return resbody, nil
+}
+
+// apiAttackHttpCancel request to cancel the running attack on HTTP target.
+//
+// Request format,
+//
+// DELETE /_trunks/api/attack/http
+//
+// Response format,
+//
+// Content-Type: application/json
+//
+// {"data":<RunRequest>}
+//
+// Response codes,
+// - 200 OK: success, return the RunRequest object that has been cancelled.
+// - 500 ERR_INTERNAL: internal server error.
+func (trunks *Trunks) apiAttackHttpCancel(epr *libhttp.EndpointRequest) (resbody []byte, err error) {
+ var (
+ logp = `apiAttackHttpCancel`
+ runRequest *RunRequest
+ )
+
+ runRequest, err = trunks.AttackHttpCancel()
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ var res = &libhttp.EndpointResponse{}
+ res.Code = http.StatusOK
+ res.Name = `OK_ATTACK_HTTP_CANCEL`
+ res.Message = fmt.Sprintf(`Attack on target "%s/%s" has been canceled`,
+ runRequest.Target.Name, runRequest.HttpTarget.Name)
+ res.Data = runRequest
+
+ resbody, err = json.Marshal(res)
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+ return resbody, nil
+}
+
func (trunks *Trunks) apiAttackResultDelete(epr *libhttp.EndpointRequest) (resbody []byte, err error) {
name := epr.HttpRequest.Form.Get(paramNameName)
if len(name) == 0 {
diff --git a/trunks.go b/trunks.go
index 6037f4f..b3b161f 100644
--- a/trunks.go
+++ b/trunks.go
@@ -38,8 +38,8 @@ const (
paramNameName = "name"
// List of HTTP APIs and/or WebSocket broadcast messages.
- apiAttackHttp = "/_trunks/api/attack/http"
- apiAttackResult = "/_trunks/api/attack/result"
+ pathApiAttackHttp = "/_trunks/api/attack/http"
+ pathApiAttackResult = "/_trunks/api/attack/result"
)
// Trunks is the HTTP server with web user interface and APIs for running and
diff --git a/websocket_server.go b/websocket_server.go
index 5928c73..9cff066 100644
--- a/websocket_server.go
+++ b/websocket_server.go
@@ -30,7 +30,7 @@ func (trunks *Trunks) wsBroadcastAttackFinish(result *AttackResult) {
}
packet, err := websocket.NewBroadcast(
- apiAttackResult,
+ pathApiAttackResult,
base64.StdEncoding.EncodeToString(jsonb),
)
if err != nil {
@@ -55,7 +55,7 @@ func (trunks *Trunks) initWebSocketServer() (err error) {
err = trunks.Wsd.RegisterTextHandler(
"POST",
- apiAttackHttp,
+ pathApiAttackHttp,
trunks.handleWsAttackHttp,
)
if err != nil {
@@ -64,7 +64,7 @@ func (trunks *Trunks) initWebSocketServer() (err error) {
err = trunks.Wsd.RegisterTextHandler(
"DELETE",
- apiAttackHttp,
+ pathApiAttackHttp,
trunks.handleWsAttackHttpCancel,
)
if err != nil {