def testSendNoContent(self): request = UtilTestCase.RequestMockup() util.send_no_content(request) self.assertEqual(request.response.status, 204) self.assertEqual(request.response.headers['Content-Type'], 'application/json') self.assertEqual(request.response.out.msg, '')
def get(self): """Handles an HTTP GET request. The URL must be in the following format: 'http://mlab-ns.appspot.com/tool-name?query_string', where tool-name is one of the tools running on M-Lab. For more information about the URL and the supported arguments in the query string, see the design doc at http://goo.gl/48S22. """ query = lookup_query.LookupQuery() query.initialize_from_http_request(self.request) # Check right away whether we should proxy this request. url = reverse_proxy.try_reverse_proxy_url(query, datetime.datetime.now()) if url: # NB: if sending the proxy url is unsuccessful, then fall through to # regular request handling. success = self.send_proxy_response(url) if success: logging.info('[reverse_proxy],true,%s', url) return logging.info('Policy is %s', query.policy) client_signature = query.calculate_client_signature() lookup_resolver = resolver.new_resolver(query.policy, client_signature) sliver_tools = lookup_resolver.answer_query(query) if sliver_tools is None: # NOTE: at this point, we know that either the query is invalid # (e.g. bad tool_id) or that a valid query has no capacity. if model.is_valid_tool(query.tool_id): # A.K.A. "no capacity". return util.send_no_content(self) else: # Invalid tool, so report "404 Not Found". return util.send_not_found(self, query.response_format) if query.response_format == message.FORMAT_JSON: self.send_json_response(sliver_tools, query) elif query.response_format == message.FORMAT_HTML: self.send_html_response(sliver_tools, query) elif query.response_format == message.FORMAT_REDIRECT: self.send_redirect_response(sliver_tools, query) elif query.response_format == message.FORMAT_BT: self.send_bt_response(sliver_tools, query) elif query.response_format == message.FORMAT_MAP: candidates = lookup_resolver.get_candidates(query) self.send_map_response(sliver_tools, query, candidates) else: # TODO (claudiu) Discuss what should be the default behaviour. # I think json it's OK since is valid for all tools, while # redirect only applies to web-based tools. self.send_json_response(sliver_tools, query) # At this point, the client has received a response but the server has # not closed the connection. self.log_location(query, sliver_tools) # TODO (claudiu) Add a FORMAT_TYPE column in the BigQuery schema. self.log_request(query, sliver_tools)
def send_json_response(self, sliver_tools, query): """Sends the response to the lookup request in json format. Args: sliver_tools: A list of SliverTool instances, representing the best sliver tool selected for this lookup request. query: A LookupQuery instance representing the user lookup request. """ if type(sliver_tools) is not list: logging.error("Problem: sliver_tools is not a list.") return # We will respond with HTTP status 204 if len(sliver_tools) == 0 array_response = False if len(sliver_tools) > 1: array_response = True tool = None json_data = "" for sliver_tool in sliver_tools: data = {} if tool == None: tool = model.get_tool_from_tool_id(sliver_tool.tool_id) if query.tool_address_family == message.ADDRESS_FAMILY_IPv4: ips = [sliver_tool.sliver_ipv4] elif query.tool_address_family == message.ADDRESS_FAMILY_IPv6: ips = [sliver_tool.sliver_ipv6] else: ips = [] if sliver_tool.status_ipv4 == message.STATUS_ONLINE: ips.append(sliver_tool.sliver_ipv4) if sliver_tool.status_ipv6 == message.STATUS_ONLINE: ips.append(sliver_tool.sliver_ipv6) fqdn = fqdn_rewrite.rewrite(sliver_tool.fqdn, query.tool_address_family, sliver_tool.tool_id) if sliver_tool.http_port: data['url'] = _create_tool_url(fqdn, sliver_tool.http_port) if sliver_tool.server_port: data['port'] = sliver_tool.server_port data['fqdn'] = fqdn data['ip'] = ips data['site'] = sliver_tool.site_id data['city'] = sliver_tool.city data['country'] = sliver_tool.country if sliver_tool.tool_extra and tool.show_tool_extra: data['tool_extra'] = sliver_tool.tool_extra if json_data != "": json_data += "," json_data += json.dumps(data) if array_response: json_data = "[" + json_data + "]" if json_data: self.response.headers['Access-Control-Allow-Origin'] = '*' self.response.headers['Content-Type'] = 'application/json' self.response.out.write(json_data) else: util.send_no_content(self)