# Path: mozsvc/http_helpers.py
# def get_url(url, method='GET', data=None, user=None, password=None, timeout=5,
#             get_body=True, extra_headers=None):
#     """Performs a synchronous url call and returns the status and body.
# 
#     This function is to be used to provide a gateway service.
# 
#     If the url is not answering after `timeout` seconds, the function will
#     return a (504, {}, error).
# 
#     If the url is not reachable at all, the function will
#     return (502, {}, error)
# 
#     Other errors are managed by the urrlib2.urllopen call.
# 
#     Args:
#         - url: url to visit
#         - method: method to use
#         - data: data to send
#         - user: user to use for Basic Auth, if needed
#         - password: password to use for Basic Auth
#         - timeout: timeout in seconds.
#         - extra headers: mapping of headers to add
#         - get_body: if set to False, the body is not retrieved
# 
#     Returns:
#         - tuple : status code, headers, body
#     """
#     if isinstance(password, str):
#         password = password.encode('utf-8')
# 
#     req = urllib.request.Request(url, data=data)
#     req.get_method = lambda: method
# 
#     if user is not None and password is not None:
#         auth = base64.encodestring('%s:%s' % (user, password))
#         req.add_header("Authorization", "Basic %s" % auth.strip())
# 
#     if extra_headers is not None:
#         for name, value in list(extra_headers.items()):
#             req.add_header(name, value)
# 
#     try:
#         res = urllib.request.urlopen(req, timeout=timeout)
#     except urllib.error.HTTPError as e:
#         if hasattr(e, 'headers'):
#             headers = dict(e.headers)
#         else:
#             headers = {}
# 
#         if hasattr(e, 'read'):
#             body = e.read()
#         else:
#             body = ''
# 
#         return e.code, headers, body
# 
#     except urllib.error.URLError as e:
#         if isinstance(e.reason, socket.timeout):
#             return 504, {}, str(e)
#         return 502, {}, str(e)
# 
#     if get_body:
#         body = res.read()
#     else:
#         body = ''
# 
#     return res.getcode(), dict(res.headers), body
# 
# def proxy(request, scheme, netloc, timeout=5):
#     """Proxies and return the result from the other server.
# 
#     - scheme: http or https
#     - netloc: proxy location
#     """
#     parsed = urlparse(request.url)
#     path = parsed.path
#     params = parsed.params
#     query = parsed.query
#     fragment = parsed.fragment
#     url = urlunparse((scheme, netloc, path, params, query, fragment))
#     method = request.method
#     data = request.body
# 
#     # copying all X- headers
#     xheaders = {}
#     for header, value in list(request.headers.items()):
#         if not header.startswith('X-'):
#             continue
#         xheaders[header] = value
# 
#     if 'X-Forwarded-For' not in request.headers:
#         xheaders['X-Forwarded-For'] = request.remote_addr
# 
#     if hasattr(request, '_authorization'):
#         xheaders['Authorization'] = request._authorization
# 
#     status, headers, body = get_url(url, method, data, timeout=timeout,
#                                     extra_headers=xheaders)
# 
#     return Response(body, status, list(headers.items()))


import unittest
import urllib.request, urllib.error, urllib.parse
import socket
from mozsvc.http_helpers import get_url, proxy
                                      user='tarek',
                                      password='passat76')
        self.assertEqual(code, 200)
        self.assertEqual(body, '{}')

        # page that times out
        code, headers, body = get_url('http://timeout', timeout=0.1)
        self.assertEqual(code, 504)

        # page that fails
        code, headers, body = get_url('http://error', get_body=False)
        self.assertEqual(code, 500)

    def test_proxy(self):
        class FakeRequest(object):
            url = 'http://locahost'
            method = 'GET'
            body = 'xxx'
            headers = {'Content-Length': 3, 'X-Me-This': 1,
                       'X-Me-That': 2}
            remote_addr = '192.168.1.1'
            _authorization = 'Basic SomeToken'

        request = FakeRequest()
        response = proxy(request, 'http', 'newplace')
        self.assertEqual(response.content_length, 31)
        self.assertEqual(response.body, 'http://newplace Basic SomeToken')

        # we want to make sure that X- headers are proxied
        request = FakeRequest()

# Path: mozsvc/http_helpers.py
# def get_url(url, method='GET', data=None, user=None, password=None, timeout=5,
#             get_body=True, extra_headers=None):
#     """Performs a synchronous url call and returns the status and body.
# 
#     This function is to be used to provide a gateway service.
# 
#     If the url is not answering after `timeout` seconds, the function will
#     return a (504, {}, error).
# 
#     If the url is not reachable at all, the function will
#     return (502, {}, error)
# 
#     Other errors are managed by the urrlib2.urllopen call.
# 
#     Args:
#         - url: url to visit
#         - method: method to use
#         - data: data to send
#         - user: user to use for Basic Auth, if needed
#         - password: password to use for Basic Auth
#         - timeout: timeout in seconds.
#         - extra headers: mapping of headers to add
#         - get_body: if set to False, the body is not retrieved
# 
#     Returns:
#         - tuple : status code, headers, body
#     """
#     if isinstance(password, str):
#         password = password.encode('utf-8')
# 
#     req = urllib.request.Request(url, data=data)
#     req.get_method = lambda: method
# 
#     if user is not None and password is not None:
#         auth = base64.encodestring('%s:%s' % (user, password))
#         req.add_header("Authorization", "Basic %s" % auth.strip())
# 
#     if extra_headers is not None:
#         for name, value in list(extra_headers.items()):
#             req.add_header(name, value)
# 
#     try:
#         res = urllib.request.urlopen(req, timeout=timeout)
#     except urllib.error.HTTPError as e:
#         if hasattr(e, 'headers'):
#             headers = dict(e.headers)
#         else:
#             headers = {}
# 
#         if hasattr(e, 'read'):
#             body = e.read()
#         else:
#             body = ''
# 
#         return e.code, headers, body
# 
#     except urllib.error.URLError as e:
#         if isinstance(e.reason, socket.timeout):
#             return 504, {}, str(e)
#         return 502, {}, str(e)
# 
#     if get_body:
#         body = res.read()
#     else:
#         body = ''
# 
#     return res.getcode(), dict(res.headers), body
# 
# def proxy(request, scheme, netloc, timeout=5):
#     """Proxies and return the result from the other server.
# 
#     - scheme: http or https
#     - netloc: proxy location
#     """
#     parsed = urlparse(request.url)
#     path = parsed.path
#     params = parsed.params
#     query = parsed.query
#     fragment = parsed.fragment
#     url = urlunparse((scheme, netloc, path, params, query, fragment))
#     method = request.method
#     data = request.body
# 
#     # copying all X- headers
#     xheaders = {}
#     for header, value in list(request.headers.items()):
#         if not header.startswith('X-'):
#             continue
#         xheaders[header] = value
# 
#     if 'X-Forwarded-For' not in request.headers:
#         xheaders['X-Forwarded-For'] = request.remote_addr
# 
#     if hasattr(request, '_authorization'):
#         xheaders['Authorization'] = request._authorization
# 
#     status, headers, body = get_url(url, method, data, timeout=timeout,
#                                     extra_headers=xheaders)
# 
#     return Response(body, status, list(headers.items()))


# Path: mozsvc/tests/test_http_helpers.py
import unittest
import urllib.request, urllib.error, urllib.parse
import socket
from mozsvc.http_helpers import get_url, proxy

                                      user='tarek',
                                      password='passat76')
        self.assertEqual(code, 200)
        self.assertEqual(body, '{}')

        # page that times out
        code, headers, body = get_url('http://timeout', timeout=0.1)
        self.assertEqual(code, 504)

        # page that fails
        code, headers, body = get_url('http://error', get_body=False)
        self.assertEqual(code, 500)

    def test_proxy(self):
        class FakeRequest(object):
            url = 'http://locahost'
            method = 'GET'
            body = 'xxx'
            headers = {'Content-Length': 3, 'X-Me-This': 1,
                       'X-Me-That': 2}
            remote_addr = '192.168.1.1'
            _authorization = 'Basic SomeToken'

        request = FakeRequest()
        response = proxy(request, 'http', 'newplace')
        self.assertEqual(response.content_length, 31)
        self.assertEqual(response.body, 'http://newplace Basic SomeToken')

        # we want to make sure that X- headers are proxied
        request = FakeRequest()

        response = proxy(request, 'http', 'xheaders')