def testGetContentHeadersOnly(self): r = RequestMock().request(HTTP_ACCEPT="application/json", CONTENT_TYPE="text/html") content_header = get_content_request_headers_only(r) self.assertIn("CONTENT-TYPE", content_header) self.assertNotIn("CONTENT_TYPE", content_header) self.assertNotIn("ACCEPT", content_header) self.assertEqual(content_header.get('CONTENT-TYPE'), "text/html") custom_headers = {"X-FOO": "BAR", "X-BAZ": "BAT"} custom_content_header = get_content_request_headers_only(r, custom_headers=custom_headers) self.assertIn("CONTENT-TYPE", custom_content_header) self.assertNotIn("CONTENT_TYPE", custom_content_header) self.assertNotIn("ACCEPT", custom_content_header) self.assertEqual(custom_content_header.get('CONTENT-TYPE'), "text/html") self.assertIn("X-FOO", custom_content_header) self.assertIn("X-BAZ", custom_content_header) self.assertEqual(custom_content_header.get('X-FOO'), "BAR")
def dispatch(self, request, *args, **kwargs): self.request = request self.err = None custom_headers = {} if general_config().domain_name is not None: custom_headers = {'X_FORWARDED_HOST': general_config().domain_name} self.get_url_to_call() if not self.auth_flow(custom_headers, *args, **kwargs): return HttpResponse(json.dumps(self.err), content_type="application/json", status=self.err.get('error')) if not self.is_allowed(): return HttpResponse(json.dumps(self.err), content_type="application/json", status=self.err.get('error')) if self.cached: cache_key_maker = CacheKeyMaker() cache_key_maker.set_request(self.request) for rule in self.cache_rules: rule.run_rule(cache_key_maker) cache_key = cache_key_maker.build_key() response = general_config().cache.store.retrieve(cache_key) if response is not None: logger.info("Cache HIT for %s" % cache_key) return response else: logger.info("Cache MISS for %s" % cache_key) if not self.is_service_up(): return HttpResponse(json.dumps(self.err), content_type="application/json", status=self.err.get('error')) try: request.GET = request.GET.copy() # make request objects mutable for the transformers for transformer in self.request_transformers: request = transformer.transform_request(request) if request.method.lower() in ['post', 'put']: self.web_call = partial(self.web_call, data=request.body, params=request.GET.lists()) else: self.web_call = partial(self.web_call, params=request.GET.lists()) if self.cfg.get('pass_headers', False): self.web_call = partial(self.web_call, headers=get_all_http_request_headers(request, custom_headers)) else: self.web_call = partial(self.web_call, headers=get_content_request_headers_only(request, custom_headers)) response = self.web_call(self.url_to_call, timeout=general_config().timeout) django_resp = HttpResponse(response.text, status=response.status_code) for header in response.headers.keys(): if header not in hop_headers: if header != "content-encoding": django_resp[header] = response.headers.get(header) django_resp['content-length'] = len(response.content) for transformer in self.response_transformers: django_resp = transformer.transform_response(django_resp) self.analytics.increment("proxy.%s.dispatch.server.success" % (self.cfg.get('name').lower(),)) if self.cached: general_config().cache.store.store(cache_key, django_resp) return django_resp except TransformerException as e: self.analytics.increment("proxy.%s.dispatch.server.transformer_exception.fail" % (self.cfg.get('name').lower(), )) err = e.to_dict() return HttpResponse(json.dumps(err, sort_keys=False), content_type="application/json", status=e.error_code) except FaceOffException as e: self.analytics.increment("proxy.%s.dispatch.server.faceoff_exception.fail" % (self.cfg.get('name').lower(), )) err = e.to_dict() return HttpResponse(json.dumps(err, sort_keys=False), content_type="application/json", status=e.error_code) except (SSLError, Timeout) as e: # Timeouts are SSLErrors if url is SSL err = OrderedDict({"error": "408", "message": "service_time_out"}) self.analytics.increment("proxy.%s.dispatch.server.service_time_out.fail" % (self.cfg.get('name').lower(), )) logger.warning("Service timed out for %s" % self.cfg.get('name') ) return HttpResponse(json.dumps(err, sort_keys=False), content_type="application/json", status=408) except ConnectionError as e: err = OrderedDict({"error": "1", "message": "connection_error"}) self.analytics.increment("proxy.%s.dispatch.server.connection_error.fail" % (self.cfg.get('name').lower(), )) logger.warning("Service connection errored for %s" % self.cfg.get('name') ) return HttpResponse(json.dumps(err, sort_keys=False), content_type="application/json", status=502) except Exception as e: err = OrderedDict({"error": "500", "message": "service_error"}) self.analytics.increment("proxy.%s.dispatch.server.generic_service_exception.fail" % (self.cfg.get('name').lower(), )) return HttpResponse(json.dumps(err, sort_keys=False), content_type="application/json", status=500)