Skip to content
This repository has been archived by the owner on Feb 11, 2019. It is now read-only.

Commit

Permalink
Merge branch 'release/0.4.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
hedleyroos committed Jun 10, 2015
2 parents 21a927c + f048faf commit 4c50115
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
@@ -1,6 +1,10 @@
Changelog
=========

0.4.2
-----
#. The Wurfl cloud handler can now go through an authenticated proxy.

0.4.1
-----
#. Ensure `EchoResource` properly encodes the headers.
Expand Down
83 changes: 69 additions & 14 deletions devproxy/handlers/wurfl_handler/scientia_mobile_cloud.py
@@ -1,16 +1,39 @@
import base64
import json
import warnings
from urllib import urlencode

from devproxy.handlers.wurfl_handler.base import WurflHandler
from twisted.internet.defer import inlineCallbacks, returnValue
from twisted.web.client import getPage
from twisted.internet.defer import inlineCallbacks, returnValue, Deferred
from twisted.internet import reactor
from twisted.internet.endpoints import HostnameEndpoint, TCP4ClientEndpoint
from twisted.web.client import ProxyAgent, getPage
from twisted.web.http_headers import Headers
from twisted.internet import protocol


class ScientiaMobileCloudHandlerConnectError(Exception):
pass


class ProxyConnectError(Exception):
pass


class SimpleReceiver(protocol.Protocol):
"""Receiver that reads data from a response"""

def __init__(self, d):
self.buf = ''
self.d = d

def dataReceived(self, data):
self.buf += data

def connectionLost(self, reason):
self.d.callback(self.buf)


class ScientiaMobileCloudHandler(WurflHandler):

SMCLOUD_CONFIG = {
Expand All @@ -28,6 +51,10 @@ def validate_config(self, config):
self.smcloud_api_key = config.get('smcloud_api_key')
if self.smcloud_api_key is None:
raise Exception('smcloud_api_key config option is required')
self.http_proxy_host = config.get('http_proxy_host')
self.http_proxy_port = config.get('http_proxy_port')
self.http_proxy_username = config.get('http_proxy_username')
self.http_proxy_password = config.get('http_proxy_password')

@inlineCallbacks
def setup_handler(self):
Expand Down Expand Up @@ -57,19 +84,47 @@ def get_device_from_smcloud(self, user_agent):
"""
Queries ScientiaMobile's API and returns a dictionary of the device.
"""
# create basic auth string
# Create basic auth string
b64 = base64.encodestring(self.smcloud_api_key).strip()
headers = {
#User-Agent is set by agent in getPage.
'X-Cloud-Client': self.SMCLOUD_CONFIG['client_version'],
'Authorization': 'Basic %s' % b64
}
try:
page = yield getPage(self.SMCLOUD_CONFIG['url'], headers=headers,
agent=user_agent, timeout=5)
except ConnectError, exc:
raise ScientiaMobileCloudHandlerConnectError(exc)
device = json.loads(page)
if self.http_proxy_host:
headers = {
'X-Cloud-Client': [self.SMCLOUD_CONFIG['client_version']],
'Authorization': ['Basic %s' % b64]
}
if self.http_proxy_username and self.http_proxy_password:
auth = base64.encodestring(
'%s:%s' % (
self.http_proxy_username, self.http_proxy_password
)
).strip()
# Cater for many proxy servers
headers['Proxy-Authorization'] = ['Basic %s' % auth]
headers['Proxy-Authenticate'] = ['Basic %s' % auth]
headers['Proxy-Authentication'] = ['Basic %s' % auth]
endpoint = TCP4ClientEndpoint(
reactor, self.http_proxy_host, self.http_proxy_port or 80,
timeout=5
)
agent = ProxyAgent(endpoint)
qs = urlencode({'agent': user_agent})
response = yield agent.request('GET', self.SMCLOUD_CONFIG['url'] + '?' + qs,
headers=Headers(headers))
if response.code != 200:
raise ProxyConnectError()
d = Deferred()
response.deliverBody(SimpleReceiver(d))
body = yield d
else:
headers = {
'X-Cloud-Client': self.SMCLOUD_CONFIG['client_version'],
'Authorization': 'Basic %s' % b64
}
try:
body = yield getPage(self.SMCLOUD_CONFIG['url'], headers=headers,
agent=user_agent, timeout=5)
except ConnectError, exc:
raise ScientiaMobileCloudHandlerConnectError(exc)
device = json.loads(body)
returnValue(device)

def handle_device(self, request, device):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -6,7 +6,7 @@ def listify(filename):

setup(
name="device-proxy",
version="0.4.1",
version="0.4.2",
url='http://github.com/praekelt/device-proxy',
license='BSD',
description="Device Proxy. A reverse HTTP Proxy that can inspect and "
Expand Down

0 comments on commit 4c50115

Please sign in to comment.