def test_proxy_connection_failed(self):
     with self.assertRaises(ProxyConnectFailed):
         self.proxy.process_request(CRLF.join([
             "GET http://unknown.domain HTTP/1.1",
             "Host: unknown.domain",
             CRLF
         ]))
    def test_http_get(self):
        self.proxy.client.buffer['out'] += "GET http://httpbin.org/get HTTP/1.1%s" % CRLF
        self.proxy.process_request(self.proxy.recv_from_client())
        self.assertEqual(self.proxy.server, None)

        self.proxy.client.buffer['out'] += CRLF.join([
            "User-Agent: curl/7.27.0",
            "Host: httpbin.org",
            "Accept: */*",
            "Proxy-Connection: Keep-Alive",
            CRLF
        ])
        self.proxy.process_request(self.proxy.recv_from_client())
        self.assertFalse(self.proxy.server == None)
        self.assertEqual(self.proxy.host, "httpbin.org")
        self.assertEqual(self.proxy.port, 80)

        self.proxy.flush_server_buffer()
        self.assertEqual(self.proxy.buffer['server'], '')

        data = self.proxy.recv_from_server()
        while data:
            self.proxy.process_response(data)
            if self.proxy.response.state == HTTP_PARSER_STATE_COMPLETE:
                break
            data = self.proxy.recv_from_server()

        self.assertEqual(self.proxy.response.state, HTTP_PARSER_STATE_COMPLETE)
        self.assertEqual(int(self.proxy.response.code), 200)
        self.proxy.close()
    def test_post_partial_parse(self):
        self.parser.parse(CRLF.join([
            "POST http://localhost HTTP/1.1",
            "Host: localhost",
            "Content-Length: 7",
            "Content-Type: application/x-www-form-urlencoded"
        ]))
        self.assertEqual(self.parser.method, "POST")
        self.assertEqual(self.parser.url.hostname, "localhost")
        self.assertEqual(self.parser.url.port, None)
        self.assertEqual(self.parser.version, "HTTP/1.1")
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_RCVING_HEADERS)

        self.parser.parse(CRLF)
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_RCVING_HEADERS)

        self.parser.parse(CRLF)
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_HEADERS_COMPLETE)

        self.parser.parse("a=b")
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_RCVING_BODY)
        self.assertEqual(self.parser.body, "a=b")
        self.assertEqual(self.parser.buffer, "")

        self.parser.parse("&c=d")
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_COMPLETE)
        self.assertEqual(self.parser.body, "a=b&c=d")
        self.assertEqual(self.parser.buffer, "")
    def test_https_get(self):
        self.proxy.client.buffer['out'] += CRLF.join([
            "CONNECT httpbin.org:80 HTTP/1.1",
            "Host: httpbin.org:80",
            "User-Agent: curl/7.27.0",
            "Proxy-Connection: Keep-Alive",
            CRLF
        ])
        self.proxy.process_request(self.proxy.recv_from_client())
        self.assertFalse(self.proxy.server == None)
        self.assertEqual(self.proxy.buffer['client'], self.proxy.connection_established_pkt)

        self.proxy.flush_client_buffer()
        self.assertEqual(self.proxy.buffer['client'], '')

        parser = HttpParser(HTTP_RESPONSE_PARSER)
        parser.parse(self.proxy.client.buffer['in'])
        self.assertEqual(parser.state, HTTP_PARSER_STATE_HEADERS_COMPLETE)
        self.assertEqual(int(parser.code), 200)

        self.proxy.client.buffer['out'] += CRLF.join([
            "GET /user-agent HTTP/1.1",
            "Host: httpbin.org",
            "User-Agent: curl/7.27.0",
            CRLF
        ])
        self.proxy.process_request(self.proxy.recv_from_client())
        self.proxy.flush_server_buffer()
        self.assertEqual(self.proxy.buffer['server'], '')

        parser = HttpParser(HTTP_RESPONSE_PARSER)
        data = self.proxy.recv_from_server()
        while data:
            parser.parse(data)
            if parser.state == HTTP_PARSER_STATE_COMPLETE:
                break
            data = self.proxy.recv_from_server()

        self.assertEqual(parser.state, HTTP_PARSER_STATE_COMPLETE)
        self.assertEqual(int(parser.code), 200)
        self.proxy.close()
 def test_get_full_parse(self):
     raw = CRLF.join([
         "GET %s HTTP/1.1",
         "Host: %s",
         CRLF
     ])
     self.parser.parse(raw % ('https://example.com/path/dir/?a=b&c=d#p=q', 'example.com'))
     self.assertEqual(self.parser.build_url(), '/path/dir/?a=b&c=d#p=q')
     self.assertEqual(self.parser.method, "GET")
     self.assertEqual(self.parser.url.hostname, "example.com")
     self.assertEqual(self.parser.url.port, None)
     self.assertEqual(self.parser.version, "HTTP/1.1")
     self.assertEqual(self.parser.state, HTTP_PARSER_STATE_COMPLETE)
     self.assertDictContainsSubset({'host':('Host', 'example.com')}, self.parser.headers)
     self.assertEqual(raw % ('/path/dir/?a=b&c=d#p=q', 'example.com'), self.parser.build(del_headers=['host'], add_headers=[('Host', 'example.com')]))
 def test_post_full_parse(self):
     raw = CRLF.join([
         "POST %s HTTP/1.1",
         "Host: localhost",
         "Content-Length: 7",
         "Content-Type: application/x-www-form-urlencoded%s" % CRLF,
         "a=b&c=d"
     ])
     self.parser.parse(raw % 'http://localhost')
     self.assertEqual(self.parser.method, "POST")
     self.assertEqual(self.parser.url.hostname, "localhost")
     self.assertEqual(self.parser.url.port, None)
     self.assertEqual(self.parser.version, "HTTP/1.1")
     self.assertDictContainsSubset({'content-type': ('Content-Type', 'application/x-www-form-urlencoded')}, self.parser.headers)
     self.assertDictContainsSubset({'content-length': ('Content-Length', '7')}, self.parser.headers)
     self.assertEqual(self.parser.body, "a=b&c=d")
     self.assertEqual(self.parser.buffer, "")
     self.assertEqual(self.parser.state, HTTP_PARSER_STATE_COMPLETE)
     self.assertEqual(len(self.parser.build()), len(raw % '/'))
    def test_get_partial_parse2(self):
        self.parser.parse(CRLF.join([
            "GET http://localhost:8080 HTTP/1.1",
            "Host: "
        ]))
        self.assertEqual(self.parser.method, "GET")
        self.assertEqual(self.parser.url.hostname, "localhost")
        self.assertEqual(self.parser.url.port, 8080)
        self.assertEqual(self.parser.version, "HTTP/1.1")
        self.assertEqual(self.parser.buffer, "Host: ")
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_LINE_RCVD)

        self.parser.parse("localhost:8080%s" % CRLF)
        self.assertDictContainsSubset({'host': ('Host', 'localhost:8080')}, self.parser.headers)
        self.assertEqual(self.parser.buffer, "")
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_RCVING_HEADERS)

        self.parser.parse("Content-Type: text/plain%s" % CRLF)
        self.assertEqual(self.parser.buffer, "")
        self.assertDictContainsSubset({'content-type': ('Content-Type', 'text/plain')}, self.parser.headers)
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_RCVING_HEADERS)

        self.parser.parse(CRLF)
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_COMPLETE)
    def test_get_partial_parse1(self):
        self.parser.parse(CRLF.join([
            "GET http://localhost:8080 HTTP/1.1"
        ]))
        self.assertEqual(self.parser.method, None)
        self.assertEqual(self.parser.url, None)
        self.assertEqual(self.parser.version, None)
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_INITIALIZED)

        self.parser.parse(CRLF)
        self.assertEqual(self.parser.method, "GET")
        self.assertEqual(self.parser.url.hostname, "localhost")
        self.assertEqual(self.parser.url.port, 8080)
        self.assertEqual(self.parser.version, "HTTP/1.1")
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_LINE_RCVD)

        self.parser.parse("Host: localhost:8080")
        self.assertDictEqual(self.parser.headers, dict())
        self.assertEqual(self.parser.buffer, "Host: localhost:8080")
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_LINE_RCVD)

        self.parser.parse(CRLF*2)
        self.assertDictContainsSubset({'host':('Host', 'localhost:8080')}, self.parser.headers)
        self.assertEqual(self.parser.state, HTTP_PARSER_STATE_COMPLETE)