Beispiel #1
0
func req(s string) *http.Request {
	req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(s)))
	if err != nil {
		panic(fmt.Sprintf("bad request in test: %q (error: %v)", req, err))
	}
	return req
}
Beispiel #2
0
func TestHybiServerHandshakeHybiBadVersion(t *testing.T) {
	config := new(Config)
	handshaker := &hybiServerHandshaker{Config: config}
	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 9

`))
	req, err := http.ReadRequest(br)
	if err != nil {
		t.Fatal("request", err)
	}
	code, err := handshaker.ReadHandshake(br, req)
	if err != ErrBadWebSocketVersion {
		t.Errorf("handshake expected err %q but got %q", ErrBadWebSocketVersion, err)
	}
	if code != http.StatusBadRequest {
		t.Errorf("status expected %q but got %q", http.StatusBadRequest, code)
	}
}
Beispiel #3
0
// Attempt to extract an HTTP request from the packet and serialise with the
// provided encoder.
func SerialisePacket(pkt *pcap.Packet, enc *json.Encoder) {
	// TODO: serialise packet details for non-HTTP packets

	// TODO: naively assumes requests are contained in a single packet and
	// HTTP verbs are not otherwise contained in a request

	// rfc 2616
	httpMethods := [...]string{"OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT"}

	// TODO: IPv6
	if hdr, ok := pkt.Headers[0].(*pcap.Iphdr); ok {
		if tcpHdr, ok := pkt.Headers[1].(*pcap.Tcphdr); ok {
			// TODO: Consider peeking at other ports
			if tcpHdr.DestPort == 80 {
				pktString := PacketAsString(pkt)
				for _, verb := range httpMethods {
					if strings.Contains(pktString, verb) {
						unparsedReqs := strings.Split(pktString, verb)
						for _, unparsed := range unparsedReqs {
							req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(verb + unparsed)))
							// TODO: serialise details of packets we fail to parse
							if err == nil {
								rp := RequestPacket{hdr.SrcAddr(), hdr.DestAddr(), tcpHdr.SrcPort, tcpHdr.DestPort, pkt.TimeString(), tcpHdr.FlagsString(), req}
								enc.Encode(rp)
							}
						}
					}
				}
			}
			out.Flush()
		}
	}

}
Beispiel #4
0
func pipeRequestResponse(server, client net.Conn) os.Error {

	// Read request from wire
	req, err := http.ReadRequest(bufio.NewReader(client))
	if err != nil {
		return err
	}

	rawReq, err := http.DumpRequest(req, true)
	if err != nil {
		return err
	}

	// forward it on
	server.Write(rawReq)

	// Read response from wire
	resp, err := http.ReadResponse(bufio.NewReader(server), req)
	if err != nil {
		return err
	}

	rawResp, err := http.DumpResponse(resp, true)
	if err != nil {
		return err
	}

	log.Printf("%s %s [%s]", req.Method, req.RawURL, resp.Status)

	// forward it on
	client.Write(rawResp)

	return nil
}
Beispiel #5
0
func TestURL(t *testing.T) {
	for _, ex := range examples {
		req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(ex.request)))
		if err != nil {
			t.Error(err)
		}

		if len(req.Header) > 1 {
			// Only works on requests without any headers
			// Host header has been removed
			continue
		}

		date := req.Header.Get("Date")

		url, err := http.ParseURL("http://" + req.Host + req.URL.RawPath)
		if err != nil {
			t.Error(err)
		}

		signed, err := URL(url, AWSAccessKeyId, AWSSecretAccessKey, req.Method, date)
		if err != nil {
			t.Error(err)
		}

		// Fudge a bit on this test.  The date should be in Unix timestamp
		// but we can only compare against known signatures for now so use
		// the existing date.

		if auth := addAuth(url.Raw, ex.auth, date); auth != signed.Raw {
			t.Error("Fail URL:", ex.name, "got:", signed.Raw, "want:", auth, "headers:", len(req.Header))
		}
	}
}
Beispiel #6
0
func newRequest(httpreq string) *http.Request {
	buf := bufio.NewReader(strings.NewReader(httpreq))
	req, err := http.ReadRequest(buf)
	if err != nil {
		panic("cgi: bogus http request in test: " + httpreq)
	}
	req.RemoteAddr = "1.2.3.4"
	return req
}
Beispiel #7
0
func (srv *Server) handler(c net.Conn) {
	startTime := time.Nanoseconds()
	defer srv.connectionFinished(c)
	buf, err := bufio.NewReaderSize(c, 8192)
	if err != nil {
		Error("%s Read buffer fail: %v", srv.serverLogPrefix(), err)
		return
	}
	var req *http.Request
	// no keepalive (for now)
	reqCount := 0
	keepAlive := true
	for err == nil && keepAlive {
		if req, err = http.ReadRequest(buf); err == nil {
			if req.Header.Get("Connection") != "Keep-Alive" {
				keepAlive = false
			}
			request := newRequest(req, c, startTime)
			reqCount++
			var res *http.Response

			pssInit := new(PipelineStageStat)
			pssInit.Name = "server.Init"
			pssInit.StartTime = startTime
			pssInit.EndTime = time.Nanoseconds()
			request.appendPipelineStage(pssInit)
			// execute the pipeline
			if res = srv.Pipeline.execute(request); res == nil {
				res = SimpleResponse(req, 404, nil, "Not Found")
			}
			// cleanup
			request.startPipelineStage("server.ResponseWrite")
			req.Body.Close()
			wbuf := bufio.NewWriter(c)
			res.Write(wbuf)
			wbuf.Flush()
			if res.Body != nil {
				res.Body.Close()
			}
			request.finishPipelineStage()
			request.finishRequest()
			srv.requestFinished(request)
		} else {
			// EOF is socket closed
			if err != io.ErrUnexpectedEOF {
				Error("%s %v ERROR reading request: %v", srv.serverLogPrefix(), c.RemoteAddr(), err)
			}
		}
	}
	//Debug("%s Processed %v requests on connection %v", srv.serverLogPrefix(), reqCount, c.RemoteAddr())
}
Beispiel #8
0
func TestAuthorize(t *testing.T) {
	for _, ex := range examples {
		req, err := http.ReadRequest(bufio.NewReader(strings.NewReader(ex.request)))
		if err != nil {
			t.Error(err)
		}

		Authorize(req, AWSAccessKeyId, AWSSecretAccessKey)

		if auth := req.Header.Get("Authorization"); auth != ex.auth {
			toSign := StringToSign(req.Method, req.URL, req.Header, "")
			t.Error("Fail Authorize:", ex.name, "got:", auth, "want:", ex.auth, "url:", req.URL.Host, "host:", req.Host, "string:", toSign)
		}

	}
}
Beispiel #9
0
// Test the hybiServerHandshaker supports firefox implementation and
// checks Connection request header include (but it's not necessary
// equal to) "upgrade"
func TestHybiServerFirefoxHandshake(t *testing.T) {
	config := new(Config)
	handshaker := &hybiServerHandshaker{Config: config}
	br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: keep-alive, upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

`))
	req, err := http.ReadRequest(br)
	if err != nil {
		t.Fatal("request", err)
	}
	code, err := handshaker.ReadHandshake(br, req)
	if err != nil {
		t.Errorf("handshake failed: %v", err)
	}
	if code != http.StatusSwitchingProtocols {
		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
	}
	b := bytes.NewBuffer([]byte{})
	bw := bufio.NewWriter(b)

	config.Protocol = []string{"chat"}

	err = handshaker.AcceptHandshake(bw)
	if err != nil {
		t.Errorf("handshake response failed: %v", err)
	}
	expectedResponse := strings.Join([]string{
		"HTTP/1.1 101 Switching Protocols",
		"Upgrade: websocket",
		"Connection: Upgrade",
		"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
		"Sec-WebSocket-Protocol: chat",
		"", ""}, "\r\n")

	if b.String() != expectedResponse {
		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
	}
}
Beispiel #10
0
func TestHixie76ServerHandshake(t *testing.T) {
	config := new(Config)
	handshaker := &hixie76ServerHandshaker{Config: config}
	br := bufio.NewReader(strings.NewReader(`GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U`))
	req, err := http.ReadRequest(br)
	if err != nil {
		t.Fatal("request", err)
	}
	code, err := handshaker.ReadHandshake(br, req)
	if err != nil {
		t.Errorf("handshake failed: %v", err)
	}
	if code != http.StatusSwitchingProtocols {
		t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code)
	}
	b := bytes.NewBuffer([]byte{})
	bw := bufio.NewWriter(b)

	err = handshaker.AcceptHandshake(bw)
	if err != nil {
		t.Errorf("handshake response failed: %v", err)
	}
	expectedResponse := strings.Join([]string{
		"HTTP/1.1 101 WebSocket Protocol Handshake",
		"Upgrade: WebSocket",
		"Connection: Upgrade",
		"Sec-WebSocket-Origin: http://example.com",
		"Sec-WebSocket-Location: ws://example.com/demo",
		"Sec-WebSocket-Protocol: sample",
		"", ""}, "\r\n") + "8jKS'y:G*Co,Wxa-"
	if b.String() != expectedResponse {
		t.Errorf("handshake expected %q but got %q", expectedResponse, b.String())
	}
}
Beispiel #11
0
func TestHybiClientHandshakeHybi08(t *testing.T) {
	b := bytes.NewBuffer([]byte{})
	bw := bufio.NewWriter(b)
	br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

`))
	var err os.Error
	config := new(Config)
	config.Location, err = url.ParseRequest("ws://server.example.com/chat")
	if err != nil {
		t.Fatal("location url", err)
	}
	config.Origin, err = url.ParseRequest("http://example.com")
	if err != nil {
		t.Fatal("origin url", err)
	}
	config.Protocol = append(config.Protocol, "chat")
	config.Protocol = append(config.Protocol, "superchat")
	config.Version = ProtocolVersionHybi08

	config.handshakeData = map[string]string{
		"key": "dGhlIHNhbXBsZSBub25jZQ==",
	}
	err = hybiClientHandshake(config, br, bw)
	if err != nil {
		t.Errorf("handshake failed: %v", err)
	}
	req, err := http.ReadRequest(bufio.NewReader(b))
	if err != nil {
		t.Fatalf("read request: %v", err)
	}
	if req.Method != "GET" {
		t.Errorf("request method expected GET, but got %q", req.Method)
	}
	if req.URL.Path != "/chat" {
		t.Errorf("request path expected /demo, but got %q", req.URL.Path)
	}
	if req.Proto != "HTTP/1.1" {
		t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
	}
	if req.Host != "server.example.com" {
		t.Errorf("request Host expected example.com, but got %v", req.Host)
	}
	var expectedHeader = map[string]string{
		"Connection":             "Upgrade",
		"Upgrade":                "websocket",
		"Sec-Websocket-Key":      config.handshakeData["key"],
		"Sec-Websocket-Origin":   config.Origin.String(),
		"Sec-Websocket-Protocol": "chat, superchat",
		"Sec-Websocket-Version":  fmt.Sprintf("%d", ProtocolVersionHybi08),
	}
	for k, v := range expectedHeader {
		if req.Header.Get(k) != v {
			t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
		}
	}
}
Beispiel #12
0
func TestCall(t *testing.T) {
	s := NewServer()
	s.Register(new(TestService))

	for i, test := range tests {
		str := "POST /json HTTP/1.1\nContent-Length: " + strconv.Itoa(len(test.req)) + "\n\n" + test.req
		r := bufio.NewReader(strings.NewReader(str))

		req, _ := http.ReadRequest(r)
		b := bytes.NewBuffer([]byte{})
		w := &TestResponseWriter{buffer: b, header: make(http.Header)}
		s.ServeHTTP(w, req)
		resp := new(jsonResponse)
		json.Unmarshal(b.Bytes(), resp)

		if test.error != nil {
			if resp.Error == nil {
				t.Error("Test", i, "Error not present")
				t.Fail()
				return
			} else {
				if test.error.(string) != resp.Error.(string) {
					t.Error("Test", i, resp.Error.(string))
					t.Fail()
					return
				}
			}
		} else {
			if resp.Error != nil {
				t.Error("Test", i, resp.Error.(string))
				t.Fail()
				return
			}
		}
		if test.resp == nil && resp.Result == nil {
			continue
		}

		switch test.resp.(type) {
		case float64:
			if fValue, ok := resp.Result.(float64); !ok || fValue != test.resp.(float64) {
				t.Error("Test", i, "Did not match float")
				t.Fail()
				return
			}
		case int:
			if iValue, ok := resp.Result.(int); !ok || iValue != test.resp.(int) {
				t.Error("Test", i, "Did not match int")
				t.Fail()
				return
			}
		case bool:
			if bValue, ok := resp.Result.(bool); !ok || bValue != test.resp.(bool) {
				t.Error("Test", i, "Did not match bool")
				t.Fail()
				return
			}
		case string:
			if sValue, ok := resp.Result.(string); !ok || sValue != test.resp.(string) {
				t.Error("Test", i, "Did not match string")
				t.Fail()
				return
			}
		case map[string]interface{}:
			mapValue, ok := resp.Result.(map[string]interface{})
			if !ok {
				t.Error("Test", i, "Result was not a map[string]interface{}")
				t.Fail()
				return
			}
			mapResult := test.resp.(map[string]interface{})
			if mapValue["x"].(string) != mapResult["x"].(string) || int(mapValue["y"].(float64)) != mapResult["y"].(int) {
				t.Error("Test", i, "Did not match object")
				t.Fail()
				return
			}
		default:
			t.Error("Test", i, "Unknown result")
			t.Fail()
			return
		}
	}
}
Beispiel #13
0
func TestHixie76ClientHandshake(t *testing.T) {
	b := bytes.NewBuffer([]byte{})
	bw := bufio.NewWriter(b)
	br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Location: ws://example.com/demo
Sec-WebSocket-Protocol: sample

8jKS'y:G*Co,Wxa-`))

	var err os.Error
	config := new(Config)
	config.Location, err = url.ParseRequest("ws://example.com/demo")
	if err != nil {
		t.Fatal("location url", err)
	}
	config.Origin, err = url.ParseRequest("http://example.com")
	if err != nil {
		t.Fatal("origin url", err)
	}
	config.Protocol = append(config.Protocol, "sample")
	config.Version = ProtocolVersionHixie76

	config.handshakeData = map[string]string{
		"key1":    "4 @1  46546xW%0l 1 5",
		"number1": "829309203",
		"key2":    "12998 5 Y3 1  .P00",
		"number2": "259970620",
		"key3":    "^n:ds[4U",
	}
	err = hixie76ClientHandshake(config, br, bw)
	if err != nil {
		t.Errorf("handshake failed: %v", err)
	}
	req, err := http.ReadRequest(bufio.NewReader(b))
	if err != nil {
		t.Fatalf("read request: %v", err)
	}
	if req.Method != "GET" {
		t.Errorf("request method expected GET, but got %q", req.Method)
	}
	if req.URL.Path != "/demo" {
		t.Errorf("request path expected /demo, but got %q", req.URL.Path)
	}
	if req.Proto != "HTTP/1.1" {
		t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto)
	}
	if req.Host != "example.com" {
		t.Errorf("request Host expected example.com, but got %v", req.Host)
	}
	var expectedHeader = map[string]string{
		"Connection":             "Upgrade",
		"Upgrade":                "WebSocket",
		"Origin":                 "http://example.com",
		"Sec-Websocket-Key1":     config.handshakeData["key1"],
		"Sec-Websocket-Key2":     config.handshakeData["key2"],
		"Sec-WebSocket-Protocol": config.Protocol[0],
	}
	for k, v := range expectedHeader {
		if req.Header.Get(k) != v {
			t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k)))
		}
	}
}