Skip to content

Commit ee05935

Browse files
committed
Porting finished
1 parent 891d2a8 commit ee05935

File tree

3 files changed

+70
-25
lines changed

3 files changed

+70
-25
lines changed

httphq/app.py

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,34 @@
66
77
Core of HTTP Request & Response service
88
9-
:copyright: (c) 2011 by Alexandr Sokolovskiy (alex@obout.ru).
9+
:copyright: (c) 2011 by Alexandr Lispython (alex@obout.ru).
1010
:license: BSD, see LICENSE for more details.
11+
:github: http://github.com/Lispython/httphq
1112
"""
1213

1314
import os
15+
import sys
1416
import time
1517
import tornado.ioloop
1618
import tornado
1719
import hmac
1820
import binascii
19-
import urlparse
21+
try:
22+
import urlparse
23+
except ImportError:
24+
# Python3
25+
from urllib import parse as urlparse
26+
2027
try:
2128
from urlparse import parse_qs
2229
parse_qs # placate pyflakes
2330
except ImportError:
24-
# fall back for Python 2.5
25-
from cgi import parse_qs
31+
try:
32+
# Python3
33+
from urllib.parse import parse_qs
34+
except ImportError:
35+
# fall back for Python 2.5
36+
from cgi import parse_qs
2637

2738
from tornado.web import Application
2839
from tornado.options import define, options
@@ -31,8 +42,6 @@
3142
from tornado.web import HTTPError
3243
from tornado.escape import utf8
3344

34-
import urllib
35-
from httplib import responses
3645
from random import choice
3746
from string import ascii_letters, ascii_uppercase, ascii_lowercase
3847

@@ -44,8 +53,10 @@
4453
import sha
4554

4655

47-
from taglines import taglines
48-
from utils import Authorization, WWWAuthentication, response, HA1, HA2, H
56+
from httphq.taglines import taglines
57+
from httphq.utils import Authorization, WWWAuthentication, response, HA1, HA2, H
58+
from httphq.settings import responses
59+
from httphq.compat import unquote, urlencode, quote
4960

5061
define("port", default=8889, help="run HTTP on the given port", type=int)
5162
define("ssl_port", default=8890, help="run HTTPS on the given port", type=int)
@@ -63,7 +74,7 @@ def rel(*args):
6374

6475

6576
random_string = lambda x=10: ''.join([choice(ascii_letters + ascii_uppercase + ascii_lowercase)
66-
for x in xrange(x)])
77+
for x in range(x)])
6778

6879

6980
def get_status_extdescription(status):
@@ -111,7 +122,7 @@ def __init__(self):
111122
(r"/oauth/(?P<version>.+)/protected_resource/(?P<consumer_secret>.+)/(?P<token_secret>.+)", OAuthProtectedResourceHandler)]
112123

113124
settings = dict(
114-
site_title=u"HTTP Request & Response service",
125+
site_title="HTTP Request & Response service",
115126
template_path=os.path.join(os.path.dirname(__file__), "templates"),
116127
static_path=os.path.join(os.path.dirname(__file__), "static"),
117128
xsrf_cookies=False,
@@ -166,8 +177,9 @@ class HomeHandler(CustomHandler):
166177

167178
def get(self):
168179
endpoints = []
180+
169181
replace_map = (
170-
("(?P<status_code>\d{3})", "{status_code: int}", str(choice(responses.keys()))),
182+
("(?P<status_code>\d{3})", "{status_code: int}", str(choice(list(responses.keys())))),
171183
("(?P<name>.+)", "{name: str}", "test_name"),
172184
("(?P<value>.+)", "{value: str}", "test_value"),
173185
("(?P<num>\d{1,2})", "{redirects_num: int}", '4'),
@@ -338,7 +350,7 @@ def get(self, username, password):
338350
else:
339351
try:
340352
authorization_info = Authorization.from_string(auth)
341-
except Exception, e:
353+
except Exception:
342354
self._request_auth()
343355

344356
if not auth.startswith("Basic "):
@@ -355,7 +367,7 @@ def get(self, username, password):
355367
'auth-type': 'basic'})
356368
else:
357369
self._request_auth()
358-
except Exception, e:
370+
except Exception:
359371
self._request_auth()
360372

361373

@@ -416,7 +428,7 @@ def get(self, username, password, qop=None):
416428
else:
417429
try:
418430
authorization_info = Authorization.from_string(auth)
419-
except Exception, e:
431+
except Exception:
420432
self._request_auth(qop)
421433
else:
422434
request_info = dict()
@@ -433,8 +445,8 @@ def get(self, username, password, qop=None):
433445
self.set_status(403)
434446
self.finish()
435447

436-
except Exception, e:
437-
print(e)
448+
except Exception:
449+
print(sys.exc_info()[1])
438450
self._request_auth(qop)
439451

440452

@@ -467,13 +479,13 @@ def normalize_parameters(url):
467479
query = urlparse.urlparse(url)[4]
468480
parameters = parse_qs(utf8(query), keep_blank_values=True)
469481
for k, v in parameters.iteritems():
470-
parameters[k] = urllib.unquote(v[0])
482+
parameters[k] = unquote(v[0])
471483
url_items = parameters.items()
472484
url_items = [(utf8(k), utf8(v)) for k, v in url_items if k != 'oauth_signature']
473485
items.extend(url_items)
474486

475487
items.sort()
476-
encoded_str = urllib.urlencode(items)
488+
encoded_str = urlencode(items)
477489
# Encode signature parameters per Oauth Core 1.0 protocol
478490
# spec draft 7, section 3.6
479491
# (http://tools.ietf.org/html/draft-hammer-oauth-07#section-3.6)
@@ -484,7 +496,7 @@ def normalize_parameters(url):
484496
def url_escape(value):
485497
"""Returns a valid URL-encoded version of the given value."""
486498
"""Escape a URL including any /."""
487-
return urllib.quote(value.encode('utf-8'), safe='~')
499+
return quote(value.encode('utf-8'), safe='~')
488500

489501

490502
class SignatureMethod(object):
@@ -624,13 +636,13 @@ def get_authorization(self):
624636
for k in self.REQUIRED_FIELDS:
625637
if k not in authorization.keys():
626638
self._request_auth()
627-
return
639+
self.finish()
628640
else:
629641
d = {}
630642
for k in self.REQUIRED_FIELDS:
631643
if k not in self.request.arguments.keys():
632644
self._request_auth()
633-
return
645+
self.finish()
634646
d[k] = self.request.arguments.get(k)[0]
635647
authorization = Authorization('OAuth', d)
636648

@@ -667,9 +679,12 @@ def get(self, version, consumer_key, consumer_secret, token_key, token_secret):
667679
raise HTTPError(400)
668680

669681
authorization = self.get_authorization()
682+
if not authorization:
683+
raise HTTPError(400)
684+
670685
self._check_timestamp(authorization.get('oauth_timestamp'))
671686
if self._check_signature(authorization, consumer_secret):
672-
self.finish(urllib.urlencode({
687+
self.finish(urlencode({
673688
"oauth_token": token_key,
674689
"oauth_token_secret": token_secret}))
675690

@@ -684,7 +699,7 @@ class OAuthAuthorizeHandler(OAuthBaseHandler):
684699
def get(self, version, pin):
685700
try:
686701
oauth_token = self.request.arguments.get('oauth_token')[0]
687-
except IndexError, e:
702+
except (IndexError, TypeError):
688703
self.set_status(500)
689704
self.finish("oauth token required")
690705
else:
@@ -705,7 +720,7 @@ def get(self, version, consumer_key, consumer_secret, tmp_token_key, tmp_token_s
705720

706721
if self._check_signature(authorization, str(consumer_secret), str(tmp_token_secret)):
707722
# token and token_secret for protected sources
708-
self.finish(urllib.urlencode({
723+
self.finish(urlencode({
709724
"oauth_token": token_key,
710725
"oauth_token_secret": token_secret}))
711726

httphq/compat.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
Compatibility module
6+
~~~~~~~~~~~~~~~~~~~~
7+
8+
Add utilities to support python2 and python3
9+
10+
:copyright: (c) 2013 by Alexandr Lispython (alex@obout.ru).
11+
:license: BSD, see LICENSE for more details.
12+
:github: http://github.com/Lispython/httphq
13+
14+
"""
15+
import sys
16+
17+
py_ver = sys.version_info
18+
19+
#: Python 2.x?
20+
is_py2 = (py_ver[0] == 2)
21+
22+
#: Python 3.x?
23+
is_py3 = (py_ver[0] == 3)
24+
25+
if is_py2:
26+
from urliib import unquote, urlencode, quote
27+
else:
28+
# Python3
29+
from urllib.parse import urlencode, unquote, quote

httphq/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from urllib.request import parse_http_list
2020

2121
from hashlib import md5
22+
from tornado.escape import utf8
2223

2324

2425
def parse_dict_header(value):
@@ -196,7 +197,7 @@ def to_header(self):
196197
# qop is a quality of protection
197198

198199
def H(data):
199-
return md5(data.encode("utf-8")).hexdigest()
200+
return md5(utf8(data)).hexdigest()
200201

201202

202203
def HA1(realm, username, password):

0 commit comments

Comments
 (0)