1#!/usr/bin/env python3
 2
 3"""Allow the EPP webserver to proxy certain endpoints to the MPSTAR webserver."""
 4
 5import logging
 6import urllib.request, urllib.error, urllib.parse
 7
 8from django.http import HttpResponse
 9from django.urls import reverse
10
11from chart.project import settings
12
13
14def proxy_if_configured(func):
15    """Decorator for a django view function which will redirect the request to
16    settings.WEB_PROXY if non-None.
17    """
18    def inner(request, *args, **kwargs):
19        """Implementation of proxy request."""
20        if settings.WEB_PROXY is not None:
21            # logging.debug('prefix ' + settings.PREFIX)
22            local_url = request.get_full_path()
23            # logging.debug('local url ' + local_url)
24            just_prefix = settings.PREFIX.replace('^', '')
25            tail_pos = local_url.find(just_prefix)
26            # logging.debug('tail pos ' + str(tail_pos))
27            if tail_pos == 0:
28                # no prefix
29                tail = local_url
30
31            else:
32                tail = local_url[tail_pos + len(just_prefix):]
33
34            # logging.debug('tail ' + tail)
35            proxy_endpoint = settings.WEB_PROXY + tail
36            # logging.debug('proxy ' + proxy_endpoint)
37            return proxy(proxy_endpoint)
38
39        else:
40            return func(request, *args, **kwargs)
41
42    return inner
43
44
45def proxy(proxy_url):
46    """Forward `django_reqest` to be handled on remote system `proxy_url`.
47    Query parameters are preserved.
48    """
49    url = '{proxy}'.format(proxy=proxy_url)
50    http_response = urllib.request.urlopen(url)
51    try:
52        response_body = http_response.read()
53        status = http_response.getcode()
54        # logger.debug(self.msg % response_body)
55    except urllib.error.HTTPError as e:
56        response_body = e.read()
57        # logger.error(self.msg % response_body)
58        status = e.code
59
60    return HttpResponse(response_body, status=status,
61                        content_type=http_response.headers['content-type'])