def test_http_basic_auth(self): http_auth_config = self.config.copy() http_auth_config.update({ 'identities': { 'username': '******', } }) transport = yield self.tx_helper.get_transport(http_auth_config) url = '%s%s?%s' % ( transport.get_transport_url(), self.config['web_path'], urlencode({ 'to_msisdn': '123', 'from_msisdn': '456', 'message': 'hello', })) response = yield http_request_full(url, '', method='GET') self.assertEqual(response.code, http.UNAUTHORIZED) self.assertEqual([], self.tx_helper.get_dispatched_inbound()) response = yield http_request_full(url, '', headers={ 'Authorization': ['Basic %s' % b64encode('username:password')] }, method='GET') self.assertEqual(response.code, http.OK) [msg] = self.tx_helper.get_dispatched_inbound() self.assertEqual(msg['content'], 'hello') self.assertEqual(msg['transport_metadata'], { 'http_user': '******', })
def test_http_basic_auth(self): http_auth_config = self.config.copy() http_auth_config.update({'identities': { 'username': '******', }}) transport = yield self.get_transport(http_auth_config) url = '%s%s?%s' % (transport.get_transport_url(), self.config['web_path'], urlencode({ 'to_msisdn': '123', 'from_msisdn': '456', 'message': 'hello', })) response = yield http_request_full(url, '', method='GET') self.assertEqual(response.code, http.UNAUTHORIZED) self.assertEqual([], self.get_dispatched_messages()) response = yield http_request_full( url, '', headers={ 'Authorization': ['Basic %s' % b64encode('username:password')] }, method='GET') self.assertEqual(response.code, http.OK) [msg] = self.get_dispatched_messages() self.assertEqual(msg['content'], 'hello') self.assertEqual(msg['transport_metadata'], { 'http_user': '******', })
def test_health_response(self): health_url = 'http://%s:%s%s' % (self.addr.host, self.addr.port, self.config['health_path']) response = yield http_request_full(health_url, method='GET') self.assertEqual(response.delivered_body, '0') yield self.app_helper.make_dispatch_inbound('in 1', message_id='1', conv=self.conversation) queue = DeferredQueue() stream_url = '%s/%s/messages.json' % (self.url, self.conversation.key) stream_receiver = self.client.stream(TransportUserMessage, queue.put, queue.put, stream_url, Headers(self.auth_headers)) yield queue.get() response = yield http_request_full(health_url, method='GET') self.assertEqual(response.delivered_body, '1') stream_receiver.disconnect() response = yield http_request_full(health_url, method='GET') self.assertEqual(response.delivered_body, '0') self.assertEqual( self.app.client_manager.clients, {'sphex.stream.message.%s' % (self.conversation.key, ): []})
def test_health_response(self): health_url = 'http://%s:%s%s' % ( self.addr.host, self.addr.port, self.config['health_path']) response = yield http_request_full(health_url, method='GET') self.assertEqual(response.delivered_body, '0') yield self.app_helper.make_dispatch_inbound( 'in 1', message_id='1', conv=self.conversation) queue = DeferredQueue() stream_url = '%s/%s/messages.json' % (self.url, self.conversation.key) stream_receiver = self.client.stream( TransportUserMessage, queue.put, queue.put, stream_url, Headers(self.auth_headers)) yield queue.get() response = yield http_request_full(health_url, method='GET') self.assertEqual(response.delivered_body, '1') stream_receiver.disconnect() response = yield http_request_full(health_url, method='GET') self.assertEqual(response.delivered_body, '0') self.assertEqual(self.app.client_manager.clients, { 'sphex.stream.message.%s' % (self.conversation.key,): [] })
def test_http_request_full_headers(self): def check_ua(request): self.assertEqual('blah', request.getHeader('user-agent')) return "Yay" self.set_render(check_ua) request = yield http_request_full(self.url, '', {'User-Agent': ['blah']}) self.assertEqual(request.delivered_body, "Yay") self.assertEqual(request.code, http.OK) request = yield http_request_full(self.url, '', {'User-Agent': 'blah'}) self.assertEqual(request.delivered_body, "Yay") self.assertEqual(request.code, http.OK)
def test_bad_command(self): resp = yield http_request_full(self.get_conversation_url( self.conversation.key, 'config'), headers=self.auth_headers) self.assertEqual(resp.code, http.NOT_FOUND) resp = yield http_request_full(self.get_conversation_url( self.conversation.key, 'config', 'foo', 'bar'), headers=self.auth_headers) self.assertEqual(resp.code, http.NOT_FOUND) resp = yield http_request_full(self.get_conversation_url( self.conversation.key, 'config', 'foo'), headers=self.auth_headers) self.assertEqual(resp.code, http.BAD_REQUEST)
def test_valid_auth(self): resp = yield http_request_full(self.get_conversation_url( self.conversation.key), data='', method='GET', headers=self.auth_headers) self.assertNotEqual(resp.code, http.UNAUTHORIZED)
def test_send_to(self): msg = { 'to_addr': '+2345', 'content': 'foo', 'message_id': 'evil_id', } # TaggingMiddleware.add_tag_to_msg(msg, self.tag) url = '%s/%s/messages.json' % (self.url, self.conversation.key) response = yield http_request_full(url, json.dumps(msg), self.auth_headers, method='PUT') self.assertEqual(response.code, http.OK) put_msg = json.loads(response.delivered_body) [sent_msg] = self.app_helper.get_dispatched_outbound() self.assertEqual(sent_msg['to_addr'], sent_msg['to_addr']) self.assertEqual( sent_msg['helper_metadata'], { 'go': { 'conversation_key': self.conversation.key, 'conversation_type': 'http_api', 'user_account': self.conversation.user_account.key, }, }) # We do not respect the message_id that's been given. self.assertNotEqual(sent_msg['message_id'], msg['message_id']) self.assertEqual(sent_msg['message_id'], put_msg['message_id']) self.assertEqual(sent_msg['to_addr'], msg['to_addr']) self.assertEqual(sent_msg['from_addr'], None)
def test_unicode_rendering(self): resp_d = http_request_full(self.url, headers=self.sample_req_headers) [msg] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.tx_helper.make_dispatch_reply(msg, self.sample_unicode_menu_resp) resp = yield resp_d self.assertTrue('Hell\xc3\xb8' in resp.delivered_body) self.assertTrue('\xc3\xb8pti\xc3\xb8n 1' in resp.delivered_body)
def test_cleanup_as_seen_in_production(self): """what's a technical spec between friends?""" yield self.session_manager.create_session('13697502734175597', to_addr='*167*7#', from_addr='254XXXXXXXXX') query_string = ("msisdn=254XXXXXXXXX&clean=cleann&error=523" "&SessionID=13697502734175597&MSC=254XXXXXXXXX" "&=&=en&=9031510005344&=&=&=postpaid" "&=20130528171235405&=200220130528171113956582" "&userid=%s&password=%s" % (self.airtel_username, self.airtel_password)) response = yield http_request_full( '%s?%s' % (self.transport_url, query_string), data='', method='GET') self.assertEqual(response.code, http.OK) self.assertEqual(response.delivered_body, '') [msg] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(msg['session_event'], TransportUserMessage.SESSION_CLOSE) self.assertEqual(msg['to_addr'], '*167*7#') self.assertEqual(msg['from_addr'], '254XXXXXXXXX') self.assertEqual(msg['transport_metadata'], { 'airtel': { 'clean': 'cleann', 'error': '523', } })
def handle_outbound_message(self, message): headers = { 'Content-Type': 'application/json; charset=utf-8', } headers.update(self.get_auth_headers()) params = { 'to_addr': message['to_addr'], 'content': message['content'], 'message_id': message['message_id'], 'in_reply_to': message['in_reply_to'], 'session_event': message['session_event'] } if 'helper_metadata' in message: params['helper_metadata'] = message['helper_metadata'] resp = yield http_request_full( self.get_url('messages.json'), data=json.dumps(params).encode('utf-8'), headers=headers, method='PUT') if resp.code != http.OK: log.warning('Unexpected status code: %s, body: %s' % ( resp.code, resp.delivered_body)) yield self.publish_nack(message['message_id'], reason='Unexpected status code: %s' % ( resp.code,)) return remote_message = json.loads(resp.delivered_body) yield self.map_message_id( remote_message['message_id'], message['message_id']) yield self.publish_ack(user_message_id=message['message_id'], sent_message_id=remote_message['message_id'])
def test_concurrency_limits(self): config = yield self.app.get_config(None) concurrency = config.concurrency_limit queue = DeferredQueue() url = '%s/%s/messages.json' % (self.url, self.conversation.key) max_receivers = [ self.client.stream(TransportUserMessage, queue.put, queue.put, url, Headers(self.auth_headers)) for _ in range(concurrency) ] for i in range(concurrency): msg = yield self.app_helper.make_dispatch_inbound( 'in %s' % (i, ), message_id=str(i), conv=self.conversation) received = yield queue.get() self.assertEqual(msg['message_id'], received['message_id']) maxed_out_resp = yield http_request_full(url, method='GET', headers=self.auth_headers) self.assertEqual(maxed_out_resp.code, 403) self.assertTrue( 'Too many concurrent connections' in maxed_out_resp.delivered_body) [r.disconnect() for r in max_receivers]
def request_new_access_token(self): config = self.get_static_config() response = yield http_request_full(self.make_url( 'token', { 'grant_type': 'client_credential', 'appid': config.wechat_appid, 'secret': config.wechat_secret, }), method='GET') if not http_ok(response): raise WeChatApiException( ('Received HTTP status code %r when ' 'requesting access token.') % (response.code, )) data = json.loads(response.delivered_body) if 'errcode' in data: raise WeChatApiException( 'Error when requesting access token. ' 'Errcode: %(errcode)s, Errmsg: %(errmsg)s.' % data) # make sure we're always ahead of the WeChat expiry access_token = data['access_token'] expiry = int(data['expires_in']) * 0.90 yield self.redis.setex(self.ACCESS_TOKEN_KEY, int(expiry), access_token) returnValue(access_token)
def test_send_to(self): yield self.start_app_worker() msg = { 'to_addr': '+2345', 'content': 'foo', 'helper_metadata': {'voice': {'foo': 'bar'}}, 'session_event': 'new', 'message_id': 'evil_id', } url = '%s/%s/messages.json' % (self.url, self.conversation) response = yield http_request_full(url, json.dumps(msg), self.auth_headers, method='PUT') self.assertEqual(response.code, http.OK) self.assertEqual( response.headers.getRawHeaders('content-type'), ['application/json; charset=utf-8']) put_msg = json.loads(response.delivered_body) [sent_msg] = self.app_helper.get_dispatched_outbound() self.assertEqual(sent_msg['to_addr'], sent_msg['to_addr']) # We do not respect the message_id that's been given. self.assertNotEqual(sent_msg['message_id'], msg['message_id']) self.assertEqual(sent_msg['message_id'], put_msg['message_id']) self.assertEqual(sent_msg['to_addr'], msg['to_addr']) self.assertEqual(sent_msg['from_addr'], None) self.assertEqual(sent_msg['session_event'], 'new') self.assertEqual( sent_msg['helper_metadata'], {'voice': {'foo': 'bar'}})
def test_health_response(self): yield self.start_app_worker() health_url = 'http://%s:%s%s' % ( self.addr.host, self.addr.port, self.config['health_path']) response = yield http_request_full(health_url, method='GET') self.assertEqual(response.delivered_body, 'OK')
def test_get_outbound_for_time_range_bad_args(self): yield self.start_server() batch_id = yield self.make_batch(('foo', 'bar')) resp = yield self.make_request('GET', batch_id, 'outbound.json', start='foo') self.assertEqual(resp.code, 400) self.assertEqual( resp.delivered_body, "Invalid 'start' parameter: Unable to parse date string 'foo'") resp = yield self.make_request('GET', batch_id, 'outbound.json', end='bar') self.assertEqual(resp.code, 400) self.assertEqual( resp.delivered_body, "Invalid 'end' parameter: Unable to parse date string 'bar'") url = '%s/%s/%s/%s?start=foo&start=bar' % (self.url, 'resource_path', batch_id, 'outbound.json') resp = yield http_request_full(method='GET', url=url) self.assertEqual(resp.code, 400) self.assertEqual(resp.delivered_body, "Invalid 'start' parameter: Too many values")
def handle_outbound_message(self, message): log.msg("Outbound message to be processed %s" % repr(message)) try: cmparser = CMXMLParser() params = cmparser.build({ 'customer_id': self.config['customer_id'], 'login': self.config['login'], 'password': self.config['password'], 'from_addr': self.config['default_origin'], 'to_addr': message['to_addr'], 'content': message['content']}) log.msg('Hitting %s with %r' % (self.config['outbound_url'], params)) response = yield http_request_full( self.config['outbound_url'], params, {'User-Agent': ['Vumi CM YO Transport'], 'Content-Type': ['application/json;charset=UTF-8'], }, method='POST') log.msg("Response: (%s) %r" % (response.code, response.delivered_body)) content = response.delivered_body.strip() if response.code != 200 or response.delivered_body: error = self.KNOWN_ERROR_RESPONSE_CODES.get(content, 'Unknown response code: %s' % (content,)) yield self.publish_nack(message['message_id'], error) return yield self.publish_ack(user_message_id=message['message_id'], sent_message_id=message['message_id']) except Exception as ex: log.msg("Unexpected error %s" % repr(ex))
def handle_outbound_message(self, message): log.msg("Outbound message to be processed %s" % repr(message)) params = { 'ybsacctno': self.config['ybsacctno'], 'password': self.config['password'], 'origin': message['from_addr'], 'sms_content': message['content'], 'destinations': self.phone_format_to_yo(message['to_addr']), } log.msg('Hitting %s with %s' % (self.config['url'], urlencode(params))) try: response = yield http_request_full( "%s?%s" % (self.config['url'], urlencode(params)), "", {'User-Agent': ['Vumi Yo Transport'], 'Content-Type': ['application/json;charset=UTF-8'], }, 'GET') except ConnectionRefusedError: log.msg("Connection failed sending message: %s" % message) #raise TemporaryFailure('connection refused') except Exception as ex: log.msg("Unexpected error %s" % repr(ex)) if response.code != 200: log.msg("Http Error %s: %s" % (response.code, response.delivered_body)) yield self.publish_delivery_report( user_message_id=message['message_id'], delivery_status='failed', failure_level='http', failure_code=response.code, failure_reason=response.delivered_body ) return try: response_attr = parse_qs(unquote(response.delivered_body)) [ybs_status] = response_attr['ybs_autocreate_status'] ybs_msg = response_attr['ybs_autocreate_message'][0] if 'ybs_autocreate_message' in response_attr else None if (ybs_status == 'ERROR'): log.msg("Yo Error %s: %s" % (response.code, response.delivered_body)) yield self.publish_delivery_report( user_message_id=message['message_id'], delivery_status='failed', failure_level='service', failure_code=ybs_status, failure_reason=ybs_msg ) return log.msg("Sms received and accepted by Yo %s" % response.delivered_body) yield self.publish_delivery_report( user_message_id=message['message_id'], delivery_status='delivered', to_addr=message['to_addr'] ) except Exception as ex: log.msg("Unexpected error %s" % repr(ex))
def handle_outbound_message(self, message): creds = self._credentials.get(message['from_addr'], {}) username = creds.get('username', '') password = creds.get('password', '') params = { 'username': username, 'password': password, 'source': message['from_addr'], 'destination': message['to_addr'], 'message': message['content'], } log.msg("Sending outbound message: %s" % (message, )) url = '%s?%s' % (self._outbound_url, urlencode(params)) log.msg("Making HTTP request: %s" % (url, )) response = yield http_request_full(url, '', method='GET') log.msg("Response: (%s) %r" % (response.code, response.delivered_body)) content = response.delivered_body.strip() # we'll only send 1 message at a time and so the API can only # return this on a valid ack if content == '1': yield self.publish_ack(user_message_id=message['message_id'], sent_message_id=message['message_id']) else: error = self.KNOWN_ERROR_RESPONSE_CODES.get( content, 'Unknown response code: %s' % (content, )) yield self.publish_nack(message['message_id'], error)
def test_in_reply_to(self): inbound_msg = yield self.app_helper.make_stored_inbound( self.conversation, 'in 1', message_id='1') msg = { 'content': 'foo', 'in_reply_to': inbound_msg['message_id'], } url = '%s/%s/messages.json' % (self.url, self.conversation.key) response = yield http_request_full(url, json.dumps(msg), self.auth_headers, method='PUT') put_msg = json.loads(response.delivered_body) self.assertEqual(response.code, http.OK) [sent_msg] = self.app_helper.get_dispatched_outbound() self.assertEqual(sent_msg['to_addr'], put_msg['to_addr']) self.assertEqual( sent_msg['helper_metadata'], { 'go': { 'conversation_key': self.conversation.key, 'conversation_type': 'http_api', 'user_account': self.conversation.user_account.key, }, }) self.assertEqual(sent_msg['message_id'], put_msg['message_id']) self.assertEqual(sent_msg['session_event'], None) self.assertEqual(sent_msg['to_addr'], inbound_msg['from_addr']) self.assertEqual(sent_msg['from_addr'], '9292')
def test_postcommit(self): resp = yield http_request_full(self.get_conversation_url( self.conversation.key, 'config', 'postcommit', foo="bar", baz=1), data='pickles', method='POST', headers=self.auth_headers) self.assertEqual(resp.code, http.OK) args, kwargs = self.mocked_url_call.call_args [url] = args self.assertEqual(args, ('http://sourcecode/', )) self.assertEqual(kwargs, {'method': 'GET'}) conv = yield self.user_helper.user_api.get_wrapped_conversation( self.conversation.key) conv_config = conv.get_config() self.assertEqual(conv_config['jsbox'], { 'source_url': 'http://sourcecode/', 'javascript': 'javascript!', }) self.assertEqual( conv_config['jsbox_app_config'], { 'config': { 'source_url': 'http://configsourcecode/', 'value': 'javascript!' } })
def test_invalid_credentials(self): url = self.mkurl_raw(ServiceNumber='12345', SMSBODY='hello', USN='something', PWD='wrong', Operator='foo', PhoneNumber='1234') response = yield http_request_full(url, '', method='GET') self.assertEqual(400, response.code) self.assertEqual(json.loads(response.delivered_body), {'credentials': 'invalid'})
def push(self, url, vumi_message): config = self.get_static_config() data = vumi_message.to_json().encode('utf-8') try: auth, url = extract_auth_from_url(url.encode('utf-8')) headers = { 'Content-Type': 'application/json; charset=utf-8', } if auth is not None: username, password = auth if username is None: username = '' if password is None: password = '' headers.update({ 'Authorization': 'Basic %s' % ( base64.b64encode('%s:%s' % (username, password)),) }) resp = yield http_request_full( url, data=data, headers=headers, timeout=config.timeout) if not (200 <= resp.code < 300): # We didn't get a 2xx response. log.warning('Got unexpected response code %s from %s' % ( resp.code, url)) except SchemeNotSupported: log.warning('Unsupported scheme for URL: %s' % (url,)) except HttpTimeoutError: log.warning("Timeout pushing message to %s" % (url,)) except DNSLookupError: log.warning("DNS lookup error pushing message to %s" % (url,)) except ConnectionRefusedError: log.warning("Connection refused pushing message to %s" % (url,))
def test_in_reply_to_with_evil_message_id(self): inbound_msg = yield self.app_helper.make_stored_inbound( self.conversation, 'in 1', message_id='1') msg = { 'content': 'foo', 'in_reply_to': inbound_msg['message_id'], 'message_id': 'evil_id' } url = '%s/%s/messages.json' % (self.url, self.conversation.key) response = yield http_request_full(url, json.dumps(msg), self.auth_headers, method='PUT') self.assertEqual(response.code, http.OK) put_msg = json.loads(response.delivered_body) [sent_msg] = self.app_helper.get_dispatched_outbound() # We do not respect the message_id that's been given. self.assertNotEqual(sent_msg['message_id'], msg['message_id']) self.assertEqual(sent_msg['message_id'], put_msg['message_id']) self.assertEqual(sent_msg['to_addr'], inbound_msg['from_addr']) self.assertEqual(sent_msg['from_addr'], '9292')
def request_new_access_token(self): config = self.get_static_config() response = yield http_request_full( self.make_url( "token", {"grant_type": "client_credential", "appid": config.wechat_appid, "secret": config.wechat_secret}, ), method="GET", ) if not http_ok(response): raise WeChatApiException( ("Received HTTP status code %r when " "requesting access token.") % (response.code,) ) data = json.loads(response.delivered_body) if "errcode" in data: raise WeChatApiException( "Error when requesting access token. " "Errcode: %(errcode)s, Errmsg: %(errmsg)s." % data ) # make sure we're always ahead of the WeChat expiry access_token = data["access_token"] expiry = int(data["expires_in"]) * 0.90 yield self.redis.setex(self.ACCESS_TOKEN_KEY, int(expiry), access_token) returnValue(access_token)
def test_unicode_rendering(self): resp_d = http_request_full(self.url, headers=self.sample_req_headers) [msg] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.tx_helper.make_dispatch_reply(msg, self.sample_unicode_menu_resp) resp = yield resp_d self.assertTrue("Hell\xc3\xb8" in resp.delivered_body) self.assertTrue("\xc3\xb8pti\xc3\xb8n 1" in resp.delivered_body)
def test_http_request_full_timeout_after_first_receive(self): # This tests the case where the client connects, receives # some data and creates its receiver but then times out # because the server takes too long to finish sending the data. def interrupt(r): raise self.InterruptHttp request_started = Deferred() self.set_render(interrupt, request_started) client_done = http_request_full(self.url, '', timeout=0.1) request = yield request_started request.write("some data") def check_server_response(reason): self.assertTrue( reason.check('twisted.internet.error' '.ConnectionDone')) request_done = request.notifyFinish() request_done.addBoth(check_server_response) yield request_done def check_client_response(reason): self.assertTrue(reason.check('vumi.utils.HttpTimeoutError')) client_done.addBoth(check_client_response) yield client_done
def _make_call(self, params): params.setdefault('format', 'json') url = '%s?%s' % (self.url, urlencode(params)) if isinstance(url, unicode): url = url.encode('utf-8') headers = {'User-Agent': self.user_agent} if self.gzip: headers['Accept-Encoding'] = 'gzip' if self.PRINT_DEBUG: print "\n=====\n\n%s /?%s\n" % ('GET', url.split('?', 1)[1]) response = yield http_request_full(url, '', headers, method='GET', timeout=self.api_timeout, agent_class=redirect_agent_builder) if self.PRINT_DEBUG: print response.delivered_body print "\n=====" try: returnValue(json.loads(response.delivered_body)) except Exception, e: log.msg("Error reading API response: %s %r" % (response.code, response.delivered_body)) log.err() raise APIError(e)
def test_send_to_within_content_length_limit(self): yield self.start_app_worker({ 'content_length_limit': 182, }) msg = { 'content': 'foo', 'to_addr': '+1234', } url = '%s/%s/messages.json' % (self.url, self.conversation) response = yield http_request_full(url, json.dumps(msg), self.auth_headers, method='PUT') self.assertEqual( response.headers.getRawHeaders('content-type'), ['application/json; charset=utf-8']) put_msg = json.loads(response.delivered_body) self.assertEqual(response.code, http.OK) [sent_msg] = self.app_helper.get_dispatched_outbound() self.assertEqual(sent_msg['to_addr'], put_msg['to_addr']) self.assertEqual(sent_msg['message_id'], put_msg['message_id']) self.assertEqual(sent_msg['session_event'], None) self.assertEqual(sent_msg['to_addr'], '+1234') self.assertEqual(sent_msg['from_addr'], None)
def make_request(self, params): log.msg("Making HTTP request: %s" % (repr(params))) config = self.get_static_config() return http_request_full(config.outbound_url, urlencode(params), method='POST', headers=self.headers)
def test_missing_parameters(self): url = self.mkurl_raw(ServiceNumber='12345', SMSBODY='hello', USN='user', PWD='pass', Operator='foo') response = yield http_request_full(url, '', method='GET') self.assertEqual(400, response.code) self.assertEqual(json.loads(response.delivered_body), {'missing_parameter': ['PhoneNumber']})
def test_http_request_full_ok_with_timeout_set(self): # If we don't cancel the pending timeout check this test will fail with # a dirty reactor. self.set_render(lambda r: "Yay") request = yield http_request_full(self.url, '', timeout=100) self.assertEqual(request.delivered_body, "Yay") self.assertEqual(request.code, http.OK)
def test_bad_parameter_in_permissive_mode(self): url = self.mkurl('hello', foo='bar') response = yield http_request_full(url, '', method='GET') [msg] = self.tx_helper.get_dispatched_inbound() self.assertEqual(200, response.code) self.assertEqual(json.loads(response.delivered_body), {'message_id': msg['message_id']})
def test_send_to(self): msg = { 'to_addr': '+2345', 'content': 'foo', 'message_id': 'evil_id', } # TaggingMiddleware.add_tag_to_msg(msg, self.tag) url = '%s/%s/messages.json' % (self.url, self.conversation.key) response = yield http_request_full(url, json.dumps(msg), self.auth_headers, method='PUT') self.assertEqual(response.code, http.OK) put_msg = json.loads(response.delivered_body) [sent_msg] = self.app_helper.get_dispatched_outbound() self.assertEqual(sent_msg['to_addr'], sent_msg['to_addr']) self.assertEqual(sent_msg['helper_metadata'], { 'go': { 'conversation_key': self.conversation.key, 'conversation_type': 'http_api', 'user_account': self.conversation.user_account.key, }, }) # We do not respect the message_id that's been given. self.assertNotEqual(sent_msg['message_id'], msg['message_id']) self.assertEqual(sent_msg['message_id'], put_msg['message_id']) self.assertEqual(sent_msg['to_addr'], msg['to_addr']) self.assertEqual(sent_msg['from_addr'], None)
def test_get_outbound_for_time_range_bad_args(self): """ The server rejects requests for outbound messages with badly-formed time range arguments and returns a 400 response code. """ yield self.start_server() batch_id = yield self.make_batch(('foo', 'bar')) resp = yield self.make_request('GET', batch_id, 'outbound.json', start='foo') self.assertEqual(resp.code, 400) self.assertEqual( resp.delivered_body, "Invalid 'start' parameter: Unable to parse date string 'foo'") resp = yield self.make_request('GET', batch_id, 'outbound.json', end='bar') self.assertEqual(resp.code, 400) self.assertEqual( resp.delivered_body, "Invalid 'end' parameter: Unable to parse date string 'bar'") url = '%s/%s/%s/%s?start=foo&start=bar' % (self.url, 'resource_path', batch_id, 'outbound.json') resp = yield http_request_full(method='GET', url=url) self.assertEqual(resp.code, 400) self.assertEqual( resp.delivered_body, "Invalid 'start' parameter: Exactly one value required")
def test_in_reply_to(self): inbound_msg = yield self.app_helper.make_stored_inbound( self.conversation, 'in 1', message_id='1') msg = { 'content': 'foo', 'in_reply_to': inbound_msg['message_id'], } url = '%s/%s/messages.json' % (self.url, self.conversation.key) response = yield http_request_full(url, json.dumps(msg), self.auth_headers, method='PUT') put_msg = json.loads(response.delivered_body) self.assertEqual(response.code, http.OK) [sent_msg] = self.app_helper.get_dispatched_outbound() self.assertEqual(sent_msg['to_addr'], put_msg['to_addr']) self.assertEqual(sent_msg['helper_metadata'], { 'go': { 'conversation_key': self.conversation.key, 'conversation_type': 'http_api', 'user_account': self.conversation.user_account.key, }, }) self.assertEqual(sent_msg['message_id'], put_msg['message_id']) self.assertEqual(sent_msg['session_event'], None) self.assertEqual(sent_msg['to_addr'], inbound_msg['from_addr']) self.assertEqual(sent_msg['from_addr'], '9292')
def handle_outbound_message(self, message): headers = {"Content-Type": "application/json; charset=utf-8"} headers.update(self.get_auth_headers()) params = { "to_addr": message["to_addr"], "content": message["content"], "message_id": message["message_id"], "in_reply_to": message["in_reply_to"], "session_event": message["session_event"], } if "helper_metadata" in message: params["helper_metadata"] = message["helper_metadata"] resp = yield http_request_full( self.get_url("messages.json"), data=json.dumps(params).encode("utf-8"), headers=headers, method="PUT", agent_class=self.agent_factory, ) if resp.code != http.OK: log.warning("Unexpected status code: %s, body: %s" % (resp.code, resp.delivered_body)) yield self.publish_nack(message["message_id"], reason="Unexpected status code: %s" % (resp.code,)) return remote_message = json.loads(resp.delivered_body) yield self.map_message_id(remote_message["message_id"], message["message_id"]) yield self.publish_ack(user_message_id=message["message_id"], sent_message_id=remote_message["message_id"])
def handle_outbound_message(self, message): creds = self._credentials.get(message['from_addr'], {}) username = creds.get('username', '') password = creds.get('password', '') params = { 'username': username, 'password': password, 'source': message['from_addr'], 'destination': message['to_addr'], 'message': message['content'], } log.msg("Sending outbound message: %s" % (message,)) url = '%s?%s' % (self._outbound_url, urlencode(params)) log.msg("Making HTTP request: %s" % (url,)) response = yield http_request_full(url, '', method='GET') log.msg("Response: (%s) %r" % (response.code, response.delivered_body)) content = response.delivered_body.strip() # we'll only send 1 message at a time and so the API can only # return this on a valid ack if content == '1': yield self.publish_ack(user_message_id=message['message_id'], sent_message_id=message['message_id']) else: error = self.KNOWN_ERROR_RESPONSE_CODES.get(content, 'Unknown response code: %s' % (content,)) yield self.publish_nack(message['message_id'], error)
def get_shortened_url(self, msg, config, url): if isinstance(url, unicode): url = url.encode('utf-8') user_token = self.hash_user(msg.user()) headers = { 'User-Agent': 'vumi-wikipedia-http-request', 'content-type': 'application/json' } shortening_api_url = config.shortening_api_url.geturl() auth_header, clean_api_url = self.get_basic_auth_header( shortening_api_url ) if auth_header: headers.update(auth_header) payload = {'long_url': url, 'user_token': user_token} api_url = urljoin(clean_api_url, 'create') response = yield http_request_full( api_url, json.dumps(payload), headers, method='PUT') try: result = json.loads(response.delivered_body) returnValue(result['short_url']) except Exception, e: log.msg("Error reading API response: %s %r" % ( response.code, response.delivered_body)) log.err() raise APIError(e)
def test_http_request_full_timeout_after_first_receive(self): # This tests the case where the client connects, receives # some data and creates its receiver but then times out # because the server takes too long to finish sending the data. def interrupt(r): raise self.InterruptHttp request_started = Deferred() self.set_render(interrupt, request_started) client_done = http_request_full(self.url, '', timeout=0.1) request = yield request_started request.write("some data") def check_server_response(reason): self.assertTrue(reason.check('twisted.internet.error' '.ConnectionDone')) request_done = request.notifyFinish() request_done.addBoth(check_server_response) yield request_done def check_client_response(reason): self.assertTrue(reason.check('vumi.utils.HttpTimeoutError')) client_done.addBoth(check_client_response) yield client_done
def test_http_request_full_err(self): def err(r): raise ValueError("Bad") self.set_render(err) request = yield http_request_full(self.url, '') self.assertEqual(request.delivered_body, "Bad") self.assertEqual(request.code, http.INTERNAL_SERVER_ERROR)
def handle_outbound_message(self, message): creds = self._credentials.get(message["from_addr"], {}) username = creds.get("username", "") password = creds.get("password", "") params = { "username": username, "password": password, "source": message["from_addr"], "destination": message["to_addr"], "message": message["content"], } log.msg("Sending outbound message: %s" % (message,)) url = "%s?%s" % (self._outbound_url, urlencode(params)) log.msg("Making HTTP request: %s" % (url,)) response = yield http_request_full(url, "", method="GET", agent_class=self.agent_factory) log.msg("Response: (%s) %r" % (response.code, response.delivered_body)) content = response.delivered_body.strip() # we'll only send 1 message at a time and so the API can only # return this on a valid ack if content == "1": yield self.publish_ack(user_message_id=message["message_id"], sent_message_id=message["message_id"]) else: error = self.KNOWN_ERROR_RESPONSE_CODES.get(content, "Unknown response code: %s" % (content,)) yield self.publish_nack(message["message_id"], error)
def handle_outbound_message(self, message): if message.payload.get('in_reply_to') and 'content' in message.payload: super(MediaEdgeGSMTransport, self).handle_outbound_message(message) else: msisdn = message['to_addr'].lstrip('+') params = { "USN": self._outbound_url_username, "PWD": self._outbound_url_password, "SmsID": message['message_id'], "PhoneNumber": msisdn, "Operator": get_operator_name(msisdn, self._operator_mappings), "SmsBody": message['content'], } url = '%s?%s' % (self._outbound_url, urlencode(params)) response = yield http_request_full(url, '', method='GET') log.msg("Response: (%s) %r" % (response.code, response.delivered_body)) if response.code == http.OK: yield self.publish_ack(user_message_id=message['message_id'], sent_message_id=message['message_id']) else: yield self.publish_nack(user_message_id=message['message_id'], sent_message_id=message['message_id'], reason='Unexpected response code: %s' % (response.code,))
def handle_outbound_message(self, message): if message.payload.get('in_reply_to') and 'content' in message.payload: super(MediaEdgeGSMTransport, self).handle_outbound_message(message) else: msisdn = message['to_addr'].lstrip('+') params = { "USN": self._outbound_url_username, "PWD": self._outbound_url_password, "SmsID": message['message_id'], "PhoneNumber": msisdn, "Operator": get_operator_name(msisdn, self._operator_mappings), "SmsBody": message['content'], } url = '%s?%s' % (self._outbound_url, urlencode(params)) response = yield http_request_full(url, '', method='GET', agent_class=self.agent_factory) log.msg("Response: (%s) %r" % (response.code, response.delivered_body)) if response.code == http.OK: yield self.publish_ack(user_message_id=message['message_id'], sent_message_id=message['message_id']) else: yield self.publish_nack(user_message_id=message['message_id'], sent_message_id=message['message_id'], reason='Unexpected response code: %s' % (response.code, ))
def handle_outbound_message(self, message): headers = { 'Content-Type': 'application/json; charset=utf-8', } headers.update(self.get_auth_headers()) params = { 'to_addr': message['to_addr'], 'content': message['content'], 'message_id': message['message_id'], 'in_reply_to': message['in_reply_to'], 'session_event': message['session_event'] } if 'helper_metadata' in message: params['helper_metadata'] = message['helper_metadata'] resp = yield http_request_full(self.get_url('messages.json'), data=json.dumps(params).encode('utf-8'), headers=headers, method='PUT') if resp.code != http.OK: log.warning('Unexpected status code: %s, body: %s' % (resp.code, resp.delivered_body)) yield self.publish_nack(message['message_id'], reason='Unexpected status code: %s' % (resp.code, )) return remote_message = json.loads(resp.delivered_body) yield self.map_message_id(remote_message['message_id'], message['message_id']) yield self.publish_ack(user_message_id=message['message_id'], sent_message_id=remote_message['message_id'])
def handle_outbound_message(self, message): log.msg("Outbound message to be processed %s" % repr(message)) try: cmparser = CMXMLParser() params = cmparser.build({ 'customer_id': self.config['customer_id'], 'login': self.config['login'], 'password': self.config['password'], 'from_addr': self.config['default_origin'], 'to_addr': message['to_addr'], 'content': message['content'] }) log.msg('Hitting %s with %r' % (self.config['outbound_url'], params)) response = yield http_request_full( self.config['outbound_url'], params, { 'User-Agent': ['Vumi CM YO Transport'], 'Content-Type': ['application/json;charset=UTF-8'], }, method='POST') log.msg("Response: (%s) %r" % (response.code, response.delivered_body)) content = response.delivered_body.strip() if response.code != 200 or response.delivered_body: error = self.KNOWN_ERROR_RESPONSE_CODES.get( content, 'Unknown response code: %s' % (content, )) yield self.publish_nack(message['message_id'], error) return yield self.publish_ack(user_message_id=message['message_id'], sent_message_id=message['message_id']) except Exception as ex: log.msg("Unexpected error %s" % repr(ex))
def handle_outbound_message(self, message): log.msg("Outbound message to be processed %s" % repr(message)) try: params = { 'DA': message['from_addr'], 'SOA': message['to_addr'], 'content': (message['content'] or '').encode("utf8"), 'u': self.config['login'], 'p': self.config['password']} encoded_params = urlencode(params) log.msg('Hitting %s with %s' % (self.config['outbound_url'], encoded_params)) response = yield http_request_full( "%s?%s" % (self.config['outbound_url'], encoded_params), method='GET') log.msg("Response: (%s) %r" % (response.code, response.delivered_body)) content = response.delivered_body.strip() if response.code == 200: yield self.publish_ack( user_message_id=message['message_id'], sent_message_id=message['message_id'] ) else: error = self.KNOWN_ERROR_RESPONSE_CODES.get( content, 'Unknown response code: %s' % (content,)) yield self.publish_nack(message['message_id'], error) except Exception as ex: log.msg("Unexpected error %s" % repr(ex))
def _call_relay(self, data, auth=None): data = json.dumps(data) host = self.app.web_resource.getHost() send_url = "http://127.0.0.1:%d/send" % (host.port,) headers = {} if auth is not None: headers['Authorization'] = basic_auth_string(*auth) return http_request_full(send_url, data, headers=headers)
def test_bad_command(self): resp = yield http_request_full( self.get_conversation_url( self.conversation.key, 'config'), headers=self.auth_headers) self.assertEqual(resp.code, http.NOT_FOUND) resp = yield http_request_full( self.get_conversation_url( self.conversation.key, 'config', 'foo', 'bar'), headers=self.auth_headers) self.assertEqual(resp.code, http.NOT_FOUND) resp = yield http_request_full( self.get_conversation_url( self.conversation.key, 'config', 'foo'), headers=self.auth_headers) self.assertEqual(resp.code, http.BAD_REQUEST)
def do_post(self, path, data, headers={}): url = '%s%s' % (self.url, path) default_headers = { 'Content-Type': 'application/json; charset=utf-8', } default_headers.update(headers) return http_request_full(url, data=json.dumps(data), headers=default_headers, method='POST')
def _call_relay(self, data, auth=None): data = json.dumps(data) host = self.app.web_resource.getHost() send_url = "http://127.0.0.1:%d/send" % (host.port, ) headers = {} if auth is not None: headers['Authorization'] = basic_auth_string(*auth) return http_request_full(send_url, data, headers=headers)
def check(d): response = yield http_request_full(url, method='GET') [progress_status] = response.headers.getRawHeaders( self.match_resource.RESP_IN_PROGRESS_HEADER) if progress_status == '0': d.callback(response) else: reactor.callLater(0, check, d)