diff --git a/proto/proto.go b/proto/proto.go index 9bc13ac93..c949309bf 100644 --- a/proto/proto.go +++ b/proto/proto.go @@ -323,21 +323,23 @@ func SetPath(payload, path []byte) []byte { func PathParam(payload, name []byte) (value []byte, valueStart, valueEnd int) { path := Path(payload) - if paramStart := bytes.Index(path, append(name, '=')); paramStart != -1 { - valueStart := paramStart + len(name) + 1 - paramEnd := bytes.IndexByte(path[valueStart:], '&') - - // Param can end with '&' (another param), or end of line - if paramEnd == -1 { // It is final param - paramEnd = len(path) - } else { - paramEnd += valueStart + paramStart := -1 + if paramStart = bytes.Index(path, append([]byte{'&'}, append(name, '=')...)); paramStart == -1 { + if paramStart = bytes.Index(path, append([]byte{'?'}, append(name, '=')...)); paramStart == -1 { + return []byte(""), -1, -1 } - - return path[valueStart:paramEnd], valueStart, paramEnd } - return []byte(""), -1, -1 + valueStart = paramStart + len(name) + 2 + paramEnd := bytes.IndexByte(path[valueStart:], '&') + + // Param can end with '&' (another param), or end of line + if paramEnd == -1 { // It is final param + paramEnd = len(path) + } else { + paramEnd += valueStart + } + return path[valueStart:paramEnd], valueStart, paramEnd } // SetPathParam takes payload and updates path Query attribute diff --git a/proto/proto_test.go b/proto/proto_test.go index 210a9c181..fc46e52ed 100644 --- a/proto/proto_test.go +++ b/proto/proto_test.go @@ -271,7 +271,7 @@ func TestSetPath(t *testing.T) { func TestPathParam(t *testing.T) { var payload []byte - payload = []byte("POST /post?param=test&user_id=1 HTTP/1.1\r\nContent-Length: 7\r\nHost: www.w3.org\r\n\r\na=1&b=2") + payload = []byte("POST /post?param=test&user_id=1&d_type=1&type=2&d_type=3 HTTP/1.1\r\nContent-Length: 7\r\nHost: www.w3.org\r\n\r\na=1&b=2") if val, _, _ := PathParam(payload, []byte("param")); !bytes.Equal(val, []byte("test")) { t.Error("Should detect attribute", string(val)) @@ -280,6 +280,15 @@ func TestPathParam(t *testing.T) { if val, _, _ := PathParam(payload, []byte("user_id")); !bytes.Equal(val, []byte("1")) { t.Error("Should detect attribute", string(val)) } + + if val, _, _ := PathParam(payload, []byte("type")); !bytes.Equal(val, []byte("2")) { + t.Error("Should detect attribute", string(val)) + } + + if val, _, _ := PathParam(payload, []byte("d_type")); !bytes.Equal(val, []byte("1")) { + // this function is not designed for cases with duplicate param keys + t.Error("Should detect attribute", string(val)) + } } func TestSetPathParam(t *testing.T) { diff --git a/settings.go b/settings.go index c027e28bb..ffc4b2fee 100644 --- a/settings.go +++ b/settings.go @@ -151,7 +151,7 @@ func init() { flag.StringVar(&Settings.OutputFileConfig.BufferPath, "output-file-buffer", "/tmp", "The path for temporary storing current buffer: \n\tgor --input-raw :80 --output-file s3://mybucket/logs/%Y-%m-%d.gz --output-file-buffer /mnt/logs") - flag.BoolVar(&Settings.PrettifyHTTP, "prettify-http", false, "If enabled, will automatically decode requests and responses with: Content-Encodning: gzip and Transfer-Encoding: chunked. Useful for debugging, in conjuction with --output-stdout") + flag.BoolVar(&Settings.PrettifyHTTP, "prettify-http", false, "If enabled, will automatically decode requests and responses with: Content-Encoding: gzip and Transfer-Encoding: chunked. Useful for debugging, in conjuction with --output-stdout") flag.Var(&Settings.InputRAW, "input-raw", "Capture traffic from given port (use RAW sockets and require *sudo* access):\n\t# Capture traffic from 8080 port\n\tgor --input-raw :8080 --output-http staging.com")