diff --git a/pkg/protocols/http/request.go b/pkg/protocols/http/request.go index 7b6c6cee24..90743b6c0e 100644 --- a/pkg/protocols/http/request.go +++ b/pkg/protocols/http/request.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "net/http" + "net/url" "strconv" "strings" "sync" @@ -856,14 +857,38 @@ func (request *Request) executeRequest(input *contextargs.Context, generatedRequ } return err } - var curlCommand string - if !request.Unsafe && resp != nil && generatedRequest.request != nil && resp.Request != nil && !request.Race { - bodyBytes, _ := generatedRequest.request.BodyBytes() - resp.Request.Body = io.NopCloser(bytes.NewReader(bodyBytes)) - command, err := http2curl.GetCurlCommand(generatedRequest.request.Request) - if err == nil && command != nil { - curlCommand = command.String() + if resp != nil && !request.Race { + if !request.Unsafe && generatedRequest.request != nil && resp.Request != nil { + bodyBytes, _ := generatedRequest.request.BodyBytes() + resp.Request.Body = io.NopCloser(bytes.NewReader(bodyBytes)) + command, err := http2curl.GetCurlCommand(generatedRequest.request.Request) + if err == nil && command != nil { + curlCommand = command.String() + } + } else if generatedRequest.rawRequest != nil { + unsafeRawBytes := generatedRequest.rawRequest.UnsafeRawBytes + ncat := "printf " + new_line := []byte{'\r', '\n'} + for _, line := range bytes.Split(unsafeRawBytes, new_line) { + ncat += bashEscape(append(line[:], new_line[:]...)) + ncat += "\\\r\n" + } + ncat += "|" + ncat_cmd := []string{"ncat"} + rawurl, err := url.Parse(formedURL) + if err != nil { + ncat_cmd = append(ncat_cmd, "127.0.0.1") + ncat_cmd = append(ncat_cmd, "80") + } else { + if rawurl.Scheme == "https" { + ncat_cmd = append(ncat_cmd, "--ssl") + } + ncat_cmd = append(ncat_cmd, rawurl.Hostname()) + ncat_cmd = append(ncat_cmd, rawurl.Port()) + } + ncat += strings.Join(ncat_cmd, " ") + curlCommand = ncat } } @@ -1152,3 +1177,18 @@ func (request *Request) isUnresponsiveAddress(input *contextargs.Context) bool { } return false } +func bashEscape(b []byte) string { + str := "" + for i := 0; i < len(b); i++ { + if b[i] < 32 || b[i] > 126 { + s := strconv.QuoteToASCII(string(b[i])) + s = strings.TrimPrefix(s, "\"") + s = strings.TrimSuffix(s, "\"") + str += s + } else { + str += string(b[i]) + } + } + str = "'" + strings.ReplaceAll(str, "\"", "\\\"") + "'" + return str +}