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)