mirror of
https://github.com/buger/goreplay.git
synced 2024-04-21 12:32:02 +00:00
Handle proxy request format and HTTP 1.0 requests
This commit is contained in:
+15
-9
@@ -21,7 +21,9 @@ type HTTPClientConfig struct {
|
||||
}
|
||||
|
||||
type HTTPClient struct {
|
||||
baseURL *url.URL
|
||||
baseURL string
|
||||
scheme string
|
||||
host string
|
||||
conn net.Conn
|
||||
respBuf []byte
|
||||
config *HTTPClientConfig
|
||||
@@ -33,24 +35,28 @@ func NewHTTPClient(baseURL string, config *HTTPClientConfig) *HTTPClient {
|
||||
baseURL = "http://" + baseURL
|
||||
}
|
||||
|
||||
u, _ := url.Parse(baseURL)
|
||||
if !strings.Contains(u.Host, ":") {
|
||||
u.Host += ":" + defaultPorts[u.Scheme]
|
||||
}
|
||||
|
||||
|
||||
client := new(HTTPClient)
|
||||
client.baseURL, _ = url.Parse(baseURL)
|
||||
client.baseURL = u.String()
|
||||
client.host = u.Host
|
||||
client.scheme = u.Scheme
|
||||
client.respBuf = make([]byte, 4096*10)
|
||||
client.config = config
|
||||
|
||||
if !strings.Contains(client.baseURL.Host, ":") {
|
||||
client.baseURL.Host += ":" + defaultPorts[client.baseURL.Scheme]
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
func (c *HTTPClient) Connect() (err error) {
|
||||
c.Disconnect()
|
||||
|
||||
c.conn, err = net.Dial("tcp", c.baseURL.Host)
|
||||
c.conn, err = net.Dial("tcp", c.host)
|
||||
|
||||
if c.baseURL.Scheme == "https" {
|
||||
if c.scheme == "https" {
|
||||
tlsConn := tls.Client(c.conn, &tls.Config{InsecureSkipVerify: true})
|
||||
|
||||
if err = tlsConn.Handshake(); err != nil {
|
||||
@@ -93,7 +99,7 @@ func (c *HTTPClient) Send(data []byte) (response []byte, err error) {
|
||||
|
||||
c.conn.SetWriteDeadline(timeout)
|
||||
|
||||
data = proto.SetHeader(data, []byte("Host"), []byte(c.baseURL.Host))
|
||||
data = proto.SetHost(data, []byte(c.baseURL), []byte(c.host))
|
||||
|
||||
if c.config.Debug {
|
||||
Debug("Sending:", string(data))
|
||||
|
||||
+31
-9
@@ -13,23 +13,23 @@ import (
|
||||
|
||||
func TestHTTPClientURLPort(t *testing.T) {
|
||||
c1 := NewHTTPClient("http://example.com", &HTTPClientConfig{})
|
||||
if c1.baseURL.String() != "http://example.com:80" {
|
||||
t.Error("Sould add 80 port for http:", c1.baseURL.String())
|
||||
if c1.baseURL != "http://example.com:80" {
|
||||
t.Error("Sould add 80 port for http:", c1.baseURL)
|
||||
}
|
||||
|
||||
c2 := NewHTTPClient("https://example.com", &HTTPClientConfig{})
|
||||
if c2.baseURL.String() != "https://example.com:443" {
|
||||
t.Error("Sould add 443 port for https:", c2.baseURL.String())
|
||||
if c2.baseURL != "https://example.com:443" {
|
||||
t.Error("Sould add 443 port for https:", c2.baseURL)
|
||||
}
|
||||
|
||||
c3 := NewHTTPClient("https://example.com:1", &HTTPClientConfig{})
|
||||
if c3.baseURL.String() != "https://example.com:1" {
|
||||
t.Error("Sould use specified port:", c3.baseURL.String())
|
||||
if c3.baseURL != "https://example.com:1" {
|
||||
t.Error("Sould use specified port:", c3.baseURL)
|
||||
}
|
||||
|
||||
c4 := NewHTTPClient("example.com", &HTTPClientConfig{})
|
||||
if c4.baseURL.String() != "http://example.com:80" {
|
||||
t.Error("Sould add default protocol:", c4.baseURL.String())
|
||||
if c4.baseURL != "http://example.com:80" {
|
||||
t.Error("Sould add default protocol:", c4.baseURL)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ func TestHTTPClientSend(t *testing.T) {
|
||||
wg.Done()
|
||||
}))
|
||||
|
||||
client := NewHTTPClient(server.URL, &HTTPClientConfig{Debug: false})
|
||||
client := NewHTTPClient(server.URL, &HTTPClientConfig{Debug: true})
|
||||
|
||||
wg.Add(4)
|
||||
client.Send(payload("POST"))
|
||||
@@ -245,3 +245,25 @@ func TestHTTPClientRedirectLimit(t *testing.T) {
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestHTTPClientHandleHTTP10(t *testing.T) {
|
||||
wg := new(sync.WaitGroup)
|
||||
|
||||
GET_payload := []byte("GET http://foobar.com/path HTTP/1.0\r\n\r\n")
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if r.URL.Path != "/path" {
|
||||
t.Error("Path not match:", r.URL.Path)
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
}))
|
||||
|
||||
client := NewHTTPClient(server.URL, &HTTPClientConfig{Debug: true})
|
||||
|
||||
wg.Add(1)
|
||||
client.Send(GET_payload)
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
@@ -86,6 +86,24 @@ func SetPath(payload, path []byte) []byte {
|
||||
return byteutils.Replace(payload, start, start+end, path)
|
||||
}
|
||||
|
||||
func SetHost(payload, url, host []byte) []byte {
|
||||
// If this is HTTP 1.0 traffic or proxy traffic it may include host right into path variable, so instead of setting Host header we rewrite Path
|
||||
// Fix for https://github.com/buger/gor/issues/156
|
||||
if path := Path(payload); bytes.HasPrefix(path, []byte("http")) {
|
||||
hostStart := bytes.IndexByte(path, ':') // : position "https?:"
|
||||
hostStart += 3 // Skip 1 ':' and 2 '\'
|
||||
hostEnd := hostStart + bytes.IndexByte(path[hostStart:], '/')
|
||||
|
||||
newPath := make([]byte, len(path))
|
||||
copy(newPath, path)
|
||||
newPath = byteutils.Replace(newPath, 0, hostEnd, url)
|
||||
|
||||
return SetPath(payload, newPath)
|
||||
} else {
|
||||
return SetHeader(payload, []byte("Host"), host)
|
||||
}
|
||||
}
|
||||
|
||||
func Method(payload []byte) []byte {
|
||||
end := bytes.IndexByte(payload, ' ')
|
||||
|
||||
|
||||
@@ -87,4 +87,15 @@ func TestSetPath(t *testing.T) {
|
||||
if payload = SetPath(payload, []byte("/new_path")); !bytes.Equal(payload, payload_after) {
|
||||
t.Error("Should replace path", string(payload))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetHostHTTP10(t *testing.T) {
|
||||
var payload, payload_after []byte
|
||||
|
||||
payload = []byte("POST http://example.com/post HTTP/1.0\r\nContent-Length: 7\r\nHost: www.w3.org\r\n\r\na=1&b=2")
|
||||
payload_after = []byte("POST http://new.com/post HTTP/1.0\r\nContent-Length: 7\r\nHost: www.w3.org\r\n\r\na=1&b=2")
|
||||
|
||||
if payload = SetHost(payload, []byte("http://new.com"), []byte("new.com")); !bytes.Equal(payload, payload_after) {
|
||||
t.Error("Should replace host", string(payload))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user