def test_call_method_few_times(self): client = socket.create_connection(('localhost', self.port), 1) data = '''POST / HTTP/1.1\r Content-Length: 85\r \r {"jsonrpc": "2.0", "id": "12345abc", "method": "test_result", "params": [123, "abc"]}''' client.send(data) client.send(data) client.send(data) base.loop(count=3) # First resp = http_client.HTTPResponse(client) resp.begin() data = resp.read() self.assertEqual(self.server.resp_code, 200) response = base.loads(data, [base.JsonRpcResponse]) self.assertTrue(isinstance(response, base.JsonRpcResponse)) self.assertEqual(response.id, '12345abc') self.assertEqual(response.result, { 'status': 'OK', 'params': { 'a': 123, 'b': 'abc' } }) # Second... resp = http_client.HTTPResponse(client) try: resp.begin() except http_client.BadStatusLine as err: self.assertEqual(str(err), "''") else: self.assertFalse(True) finally: client.close()
def __init__(self, response): r = http_client.HTTPResponse(self._FakeSocket(response)) r.begin() self.location = r.getheader("location") self.usn = r.getheader("usn") self.st = r.getheader("st") self.cache = r.getheader("cache-control").split("=")[1]
def encode_HarResponse_to_HTTPResponse(self, har): # headers = dict(map(utils.pair_from_obj, har.headers)) if har is None: return None class DummySocket(object): bufsize = 1024 def close(self): pass def sendall(self, data): pass def readline(self, bufsize=1024): return '' def read(self, bufsize=1024): return '' def makefile(self, mode, bufsize=1024): self.bufsize = bufsize return self resp = http_client.HTTPResponse(DummySocket()) resp.status = har.status resp.reason = har.statusText resp.version = utils.parse_http_version(har.httpVersion) resp.length = 0 resp.msg = http_client.HTTPMessage(resp.fp) resp.msg.startofheaders = har._statusLineSize resp.msg.startofbody = har.headersSize return resp
def test_call_invalid_dict_params(self): client = socket.create_connection(('localhost', self.port), 1) data = '''POST / HTTP/1.1\r Content-Length: 106\r \r {"jsonrpc": "2.0", "id": "12345abc", "method": "test_result", "params": {"a": 123, "b": "abc", "c": true}}''' client.send(data) base.loop(count=3) resp = http_client.HTTPResponse(client) resp.begin() data = resp.read() client.close() self.assertEqual(self.server.resp_code, 200) try: base.loads(data, [base.JsonRpcResponse]) except errors.JsonRpcError as err: self.assertEqual(err.code, -32602) self.assertEqual(err.message, 'Invalid params.') self.assertEqual( err.data, { 'method': 'test_result', 'params': { 'a': 123, 'b': 'abc', 'c': True } })
def __init__(self, response): r = http_client.HTTPResponse( self._FakeSocket(response)) r.begin() self.location = r.getheader('location') self.usn = r.getheader('usn') self.st = r.getheader('st') self.cache = r.getheader('cache-control').split('=')[1]
def discover_ssdp(port=1900, ttl=2, response_time=3, iface=None): """Discovers Redfish services via SSDP :param port: the port to use for the SSDP request :type port: int :param ttl: the time-to-live value for the request :type ttl: int :param response_time: the number of seconds in which a service can respond :type response_time: int :param iface: the interface to use for the request; None for all :type iface: string :returns: a set of discovery data """ # Sanity check the inputs ttl = sanitize(ttl, minimum=1, maximum=255) response_time = sanitize(response_time, minimum=1) # Initialize the multicast data mcast_ip = "239.255.255.250" msearch_str = ("M-SEARCH * HTTP/1.1\r\n" "Host: {}:{}\r\n" 'Man: "ssdp:discover"\r\n' "ST: urn:dmtf-org:service:redfish-rest:1\r\n" "MX: {}\r\n").format(mcast_ip, port, response_time) socket.setdefaulttimeout(response_time + 2) # Set up the socket and send the request sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl) if iface: sock.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, str(iface + "\0").encode("utf-8")) sock.sendto(bytearray(msearch_str, "utf-8"), (mcast_ip, port)) # On the same socket, wait for responses discovered_services = {} pattern = re.compile( "^uuid:([a-f0-9\-]*)::urn:dmtf-org:service:redfish-rest:1(:\d)?$" ) # noqa while True: try: response = http_client.HTTPResponse(FakeSocket(sock.recv(1024))) response.begin() uuid_search = pattern.search(response.getheader("USN").lower()) if uuid_search: discovered_services[uuid_search.group(1)] = response.getheader( "AL") except socket.timeout: # We hit the timeout; done waiting for responses break sock.close() return discovered_services
def discover_ssdp(port=1900, ttl=2, response_time=3): """Discovers Redfish services via SSDP :param port: the port to use for the SSDP request :type port: int :param ttl: the time-to-live value for the request :type ttl: int :param response_time: the number of seconds in which a service can respond :type response_time: int :returns: a set of discovery data """ # Sanity check the inputs if response_time < 1: response_time = 1 if ttl < 1: ttl = 1 if ttl > 255: ttl = 255 # Initialize the multicast data mcast_ip = '239.255.255.250' msearch_str = ('M-SEARCH * HTTP/1.1\r\n' 'Host: {}:{}\r\n' 'Man: "ssdp:discover"\r\n' 'ST: urn:dmtf-org:service:redfish-rest:1\r\n' 'MX: {}\r\n').format(mcast_ip, port, response_time) socket.setdefaulttimeout(response_time + 2) # Set up the socket and send the request sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl) sock.sendto(bytearray(msearch_str, 'utf-8'), (mcast_ip, port)) # On the same socket, wait for responses discovered_services = {} while True: try: response = http_client.HTTPResponse(FakeSocket(sock.recv(1024))) response.begin() uuid_search = re.search( '^uuid:([a-f0-9\-]*)::urn:dmtf-org:service:redfish-rest:1(:\d)?$', response.getheader('USN').lower()) if uuid_search: discovered_services[uuid_search.group(1)] = response.getheader( 'AL') except socket.timeout: # We hit the timeout; done waiting for responses break sock.close() return discovered_services
def test_notification(self): client = socket.create_connection(('localhost', self.port), 1) data = '''POST / HTTP/1.1\r Content-Length: 67\r \r {"jsonrpc": "2.0", "method": "test_result", "params": [123, "abc"]}''' client.send(data) base.loop(count=3) resp = http_client.HTTPResponse(client) self.assertRaises(http_client.BadStatusLine, resp.begin) self.assertEqual(self.server.resp_code, None) client.close()
def __init__(self, rest_request, resp_txt): """Initialization of RisRestResponse""" if not isinstance(resp_txt, string_types): resp_txt = "".join(map(chr, resp_txt)) self._respfh = StringIO(resp_txt) self._socket = _FakeSocket(bytearray(list(map(ord, self._respfh.read())))) response = http_client.HTTPResponse(self._socket) response.begin() response.data = response.read() response.headers = {ki[0]:ki[1] for ki in response.getheaders()} super(RisRestResponse, self).__init__(rest_request, response)
def test_python_issue_20007(self): """ Make sure we have a work-around for Python bug #20007 http://bugs.python.org/issue20007 """ class FakeSocket(object): def makefile(self, _mode, _bufsize=None): return BytesIO(b"HTTP/1.1 200 Ok\r\n\r\nText") source = http_client.HTTPResponse(FakeSocket()) source.begin() stream = HTMLInputStream(source) self.assertEqual(stream.charsUntil(" "), "Text")
def test_handle_request_auto_login_unauth(self): self.req._auto_login = True self.req._api_client = mock.Mock() self.req._api_client.need_login = True self.req._request_str = mock.Mock() self.req._request_str.return_value = 'http://cool/cool' import socket resp = httplib.HTTPResponse(socket.socket()) resp.status = httplib.UNAUTHORIZED mywaiter = mock.Mock() mywaiter.wait = mock.Mock() mywaiter.wait.return_value = resp self.req.spawn = mock.Mock(return_value=mywaiter) self.req._handle_request()
def test_http_post_data(self): client = socket.create_connection(('localhost', self.port), 1) data = 'POST / HTTP/1.1\r\nContent-Length: 14\r\n\r\nTest text data' client.send(data) base.loop(count=3) resp = http_client.HTTPResponse(client) resp.begin() data = resp.read() client.close() self.assertEqual(self.server.resp_code, 200) try: base.loads(data) except errors.JsonRpcError as err: self.assertEqual(err.code, -32700) self.assertEqual(err.message, 'Parse error.')
def test_python_issue_20007_b(self): """ Make sure we have a work-around for Python bug #20007 http://bugs.python.org/issue20007 """ if six.PY2: return class FakeSocket(object): def makefile(self, _mode, _bufsize=None): return BytesIO(b"HTTP/1.1 200 Ok\r\n\r\nText") source = http_client.HTTPResponse(FakeSocket()) source.begin() wrapped = urllib.response.addinfourl(source, source.msg, "http://example.com") stream = HTMLInputStream(wrapped) self.assertEqual(stream.charsUntil(" "), "Text")
def request(self, method, path, data, headers): req = webob.Request.blank(path) req.method = method req.body = data req.headers = headers req.headers['Accept'] = 'text/html' req.host = self.host # Call the WSGI app, get the HTTP response resp = str(req.get_response(self.app)) # For some reason, the response doesn't have "HTTP/1.0 " prepended; I # guess that's a function the web server usually provides. resp = "HTTP/1.0 %s" % resp self.sock = FakeHttplibSocket(resp) self.http_response = httplib.HTTPResponse(self.sock) # NOTE(vish): boto is accessing private variables for some reason self._HTTPConnection__response = self.http_response self.http_response.begin()
def request(self, method, path, data=None, headers=None): if not headers: headers = {} req_str = '%s %s HTTP/1.1\r\n' % (method, path) for key, value in headers.items(): req_str += "%s: %s\r\n" % (key, value) if data: req_str += '\r\n%s' % data # NOTE(vish): normally the http transport normailizes from unicode sock = FakeHttplibSocket(req_str.decode("latin-1").encode("utf-8")) # NOTE(vish): stop the server from trying to look up address from # the fake socket FakeDirectCMODEServerHandler.address_string = lambda x: '127.0.0.1' self.app = FakeDirectCMODEServerHandler(sock, '127.0.0.1:80', None) self.sock = FakeHttplibSocket(sock.result) self.http_response = http_client.HTTPResponse(self.sock)
def request(self, method, path, body="", headers=None): """Requests made via this connection actually get translated and routed into our WSGI app, we then wait for the response and turn it back into an `httplib.HTTPResponse`. """ if not headers: headers = {} req = webob.Request.blank(path) req.method = method req.headers = headers req.host = self.host req.body = encodeutils.safe_encode(body) resp = str(req.get_response(self.app)) resp = "HTTP/1.0 %s" % resp sock = FakeHttplibSocket(resp) self.http_response = httplib.HTTPResponse(sock) self.http_response.begin()
def test_interface_on_error(self): client = socket.create_connection(('localhost', self.port), 1) data = '''POST / HTTP/1.1\r Content-Length: 82\r \r {"jsonrpc": "2.0", "id": "12345abc", "method": "test_on_error", "params": ["efg"]}''' client.send(data) base.loop(count=3) resp = http_client.HTTPResponse(client) resp.begin() data = resp.read() client.close() self.assertEqual(self.server.resp_code, 200) try: base.loads(data, [base.JsonRpcResponse]) except errors.JsonRpcError as err: self.assertEqual(err.code, -32603) self.assertEqual(err.message, 'Internal error.') self.assertEqual(err.data, {'exception': 'efg'})
def test_call_private_method_not_found(self): client = socket.create_connection(('localhost', self.port), 1) data = '''POST / HTTP/1.1\r Content-Length: 96\r \r {"jsonrpc": "2.0", "id": "12345abc", "method": "_on_result", "params": {"a": "abc", "b": "efg"}}''' client.send(data) base.loop(count=3) resp = http_client.HTTPResponse(client) resp.begin() data = resp.read() client.close() self.assertEqual(self.server.resp_code, 200) try: base.loads(data, [base.JsonRpcResponse]) except errors.JsonRpcError as err: self.assertEqual(err.code, -32601) self.assertEqual(err.message, 'Method not found.') self.assertEqual(err.data, {'method': '_on_result'})
def __init__(self, rest_request, resp_txt): """Initialization of RisRestResponse :param rest_request: Holder for request information :type rest_request: RestRequest object :param resp_text: text from response to be buffered and read :type resp_text: str """ if not isinstance(resp_txt, string_types): resp_txt = "".join(map(chr, resp_txt)) self._respfh = StringIO(resp_txt) self._socket = _FakeSocket(bytearray(list(map(ord, self._respfh.\ read())))) response = http_client.HTTPResponse(self._socket) response.begin() response.data = response.read() response.headers = {ki[0]:ki[1] for ki in response.getheaders()} super(RisRestResponse, self).__init__(rest_request, response)
def test_interface_on_result(self): client = socket.create_connection(('localhost', self.port), 1) data = '''POST / HTTP/1.1\r Content-Length: 88\r \r {"jsonrpc": "2.0", "id": "12345abc", "method": "test_on_result", "params": [123, "abc"]}''' client.send(data) base.loop(count=3) resp = http_client.HTTPResponse(client) resp.begin() data = resp.read() client.close() self.assertEqual(self.server.resp_code, 200) response = base.loads(data, [base.JsonRpcResponse]) self.assertTrue(isinstance(response, base.JsonRpcResponse)) self.assertEqual(response.id, '12345abc') self.assertEqual(response.result, { 'status': 'OK', 'params': { 'a': 123, 'b': 'abc' } })
def _getresponse(self): ''' Read from recv and return a HTTPResponse object if possible. Either 1 - The client has succesfully closed the connection: Return '' 2 - The server has already closed the connection: Return the response if possible. ''' # Wait for a response self._conn.sock.setblocking(True) # Parse the response response = self._bytes while True: try: _bytes = self._conn.sock.recv(1) except http_client.socket.error: # For error 54: Connection reset by peer # (and perhaps others) return six.b('') if _bytes == six.b(''): break else: response += _bytes # Set recv to be non-blocking again self._conn.sock.setblocking(False) # Convert the response string to a http_client.HTTPResponse # object with a bit of a hack if response != six.b(''): # Taken from # http://pythonwise.blogspot.ca/2010/02/parse-http-response.html try: response = http_client.HTTPResponse(_FakeSocket(response)) response.begin() except: # Bad headers ... etc. response = six.b('') return response
def discover(timeout=2, retries=1, st=ST_ECP): group = ('239.255.255.250', 1900) message = '\r\n'.join([ 'M-SEARCH * HTTP/1.1', 'HOST: {0}:{1}'.format(*group), 'MAN: "ssdp:discover"', 'ST: {st}', 'MX: 3', '', '' ]) socket.setdefaulttimeout(timeout) responses = {} for _ in range(retries): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) m = message.format(st=st) if six.PY2: sock.sendto(m, group) elif six.PY3: sock.sendto(m.encode(), group) while 1: try: rhttp = http_client.HTTPResponse(_FakeSocket(sock.recv(1024))) rhttp.begin() if rhttp.status == 200: rssdp = SSDPResponse(rhttp) responses[rssdp.location] = rssdp except socket.timeout: break return responses.values()
def __enter__(self): self.request_context = mock.patch.object(http_client.HTTPConnection, 'request') self.request_context.return_value = None self.request_mock = self.request_context.__enter__() self.fixture_file = open(join(dirname(__file__), 'fixtures', self.fixture), 'rb') # Read through the request. preamble_line = self.fixture_file.readline().strip() try: self.method, self.uri, http_version = preamble_line.split(None, 2) self.method = self.method.decode() self.uri = self.uri.decode() except ValueError: raise ValueError("Couldn't parse preamble line from fixture file %r; does it have a fixture in it?" % self.fixture) # Read request headers def read_headers(fp): while True: try: line = fp.readline() except EOFError: return if not line or line == six.b('\n'): return yield line if six.PY2: msg = http_client.HTTPMessage(self.fixture_file, 0) self.headers = dict((k, v.strip()) for k, v in (header.split(':', 1) for header in msg.headers)) else: # http.client.HTTPMessage doesn't have importing headers from file msg = http_client.HTTPMessage() headers = email.message_from_bytes(six.b('').join(read_headers(self.fixture_file))) self.headers = dict((k, v.strip()) for k, v in headers._headers) # self.headers = {k: v for k, v in headers._headers} msg.fp = None # Read through to the vertical space. def nextline(fp): while True: try: line = fp.readline() except EOFError: return if not line or line.startswith(six.b('\x16')): return yield line body = six.b('').join(nextline(self.fixture_file)) # exhaust the request either way self.body = None if self.method in ('PUT', 'POST'): if 'Content-Type' in self.headers: if 'application/xml' in self.headers['Content-Type']: self.body = xml(body) else: self.body = body # Set up the response returner. sock = mock.Mock() sock.makefile = mock.Mock(return_value=self.fixture_file) response = http_client.HTTPResponse(sock, method=self.method) response.begin() self.response_context = mock.patch.object(http_client.HTTPConnection, 'getresponse', lambda self: response) self.response_mock = self.response_context.__enter__() return self