Merge lp:~bac/lp2kanban/kill-httplib2 into lp:~launchpad/lp2kanban/trunk

Proposed by Brad Crittenden
Status: Merged
Approved by: Curtis Hovey
Approved revision: 86
Merge reported by: Brad Crittenden
Merged at revision: not available
Proposed branch: lp:~bac/lp2kanban/kill-httplib2
Merge into: lp:~launchpad/lp2kanban/trunk
Diff against target: 118 lines (+23/-14)
4 files modified
buildout.cfg (+3/-1)
setup.py (+2/-1)
src/lp2kanban/bugs2cards.py (+3/-3)
src/lp2kanban/kanban.py (+15/-9)
To merge this branch: bzr merge lp:~bac/lp2kanban/kill-httplib2
Reviewer Review Type Date Requested Status
Björn Tillenius (community) Approve
Curtis Hovey (community) code Approve
Benji York (community) code Approve
Review via email: mp+163334@code.launchpad.net

Description of the change

On the new AMI we're forced to use in canonistack, the cert for leankitkanban cannot be verified because httplib2 keeps its own copy of cacerts.txt and it does not appear to have the CA for the cert. Note the cert is valid as modern browsers verify and accept it.

Switching from httplib2 with that deficiency to the new hotness 'requests' allows cert verification. Probably a good move for the long run anyway.

To post a comment you must log in.
Revision history for this message
Benji York (benji) wrote :

Looks great.

review: Approve (code)
Revision history for this message
Curtis Hovey (sinzui) wrote :

Thank you.

review: Approve (code)
Revision history for this message
Björn Tillenius (bjornt) wrote :

Does 'requests' support using a proxy? With httplib2 you can set the https_proxy environment variable, but I can't get it to work with this branch.

review: Needs Information
Revision history for this message
Brad Crittenden (bac) wrote :

Bjorn it does support proxies but perhaps not through the same mechanism. If that is important to you I'll defer landing this branch until it is resolved. Thanks for bringing it up.

Revision history for this message
Björn Tillenius (bjornt) wrote :

On Fri, May 10, 2013 at 10:26:24PM -0000, Brad Crittenden wrote:
> Bjorn it does support proxies but perhaps not through the same
> mechanism. If that is important to you I'll defer landing this branch
> until it is resolved. Thanks for bringing it up.

Thanks. Yes, we do depend on proxy support, since we run the script on
an IS computer, which doesn't allow direct outgoing connections.

Revision history for this message
Brad Crittenden (bac) wrote :

Bjorn 'requests' claims to support the HTTPS_PROXY environment variable. I haven't set up an environment to test it yet.

Could you review their docs and perhaps test again to verify it really doesn't work?

http://docs.python-requests.org/en/latest/user/advanced/?highlight=https_proxy#proxies

Revision history for this message
Björn Tillenius (bjornt) wrote :

On Tue, May 14, 2013 at 04:05:30PM -0000, Brad Crittenden wrote:
> Bjorn 'requests' claims to support the HTTPS_PROXY environment
> variable. I haven't set up an environment to test it yet.
>
> Could you review their docs and perhaps test again to verify it really
> doesn't work?

Indeed, I can see that there's some support for it. I'm debugging now
why doesn't work...

--
Björn Tillenius | https://launchpad.net/~bjornt

Revision history for this message
Björn Tillenius (bjornt) wrote :

On Tue, May 14, 2013 at 04:05:30PM -0000, Brad Crittenden wrote:
> Bjorn 'requests' claims to support the HTTPS_PROXY environment
> variable. I haven't set up an environment to test it yet.
>
> Could you review their docs and perhaps test again to verify it really
> doesn't work?

So, if I change the code to use self.http.request() instead of creating
the Request manually, it does try to use the proxy. However, it still
doesn't work, I get a 501 error, method not allowed. I suspect that it
tries to use CONNECT, instead of GET. I don't see a way of changing the
way it uses the proxy, but I might be missing something.

BTW, I would be fine with no proxy support, if we could get Leankit to
provide a stable IP for the API endpoint. At the moment it's changing
all the time, which means that we can't simply open up the firewall to
allow that traffic.

--
Björn Tillenius | https://launchpad.net/~bjornt

lp:~bac/lp2kanban/kill-httplib2 updated
87. By Brad Crittenden

Use an older version of requests to get around https proxy bug.

Revision history for this message
Brad Crittenden (bac) wrote :

Hi Bjorn,

I found this discussion about https proxy and requests:
https://github.com/kennethreitz/requests/issues/905

In that thread there was mention that 0.7.6 of requests was the last version that appeared to work. I've just pushed an lp2kanban branch that specifies that version. Could you test it in your environment?

lp:~bac/lp2kanban/kill-httplib2 updated
88. By Brad Crittenden

requests API changes

89. By Brad Crittenden

Changes to revert back to request 0.7.6

Revision history for this message
Björn Tillenius (bjornt) wrote :

Thanks Brad, 0.7.6 does work. You need to apply the following patch to your branch, though, otherwise the proxy won't be used:

  http://pastebin.ubuntu.com/5673322/

And while you're at it, maybe you could remove the AttributeError handler in the except clause, since it's httplib2-specific?

review: Approve
lp:~bac/lp2kanban/kill-httplib2 updated
90. By Brad Crittenden

Fix for https proxy as suggested by Bjorn in review.

Revision history for this message
Brad Crittenden (bac) wrote :

Thanks for the QA and patch Bjorn. Finally landed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'buildout.cfg'
2--- buildout.cfg 2012-11-23 13:22:23 +0000
3+++ buildout.cfg 2013-05-16 15:17:25 +0000
4@@ -29,7 +29,9 @@
5 [versions]
6 argparse = 1.2
7 elementtree = 1.2.7-20070827-preview
8-httplib2 >= 0.7.0
9+# The last version of requests to use urllib2 instead of urllib3 is 0.7.6.
10+# This avoids an urllib3 bug that causes https_proxy to not work.
11+requests = 0.7.6
12 keyring = 0.5.1
13 launchpadlib = 1.9.8
14 lazr.authentication = 0.1.2
15
16=== modified file 'setup.py'
17--- setup.py 2013-01-18 17:45:01 +0000
18+++ setup.py 2013-05-16 15:17:25 +0000
19@@ -15,7 +15,8 @@
20 'argparse',
21 'launchpadlib',
22 'lazr.uri',
23+ 'requests',
24+ 'setuptools',
25 'testtools',
26- 'setuptools',
27 ],
28 )
29
30=== modified file 'src/lp2kanban/bugs2cards.py'
31--- src/lp2kanban/bugs2cards.py 2013-04-08 12:46:05 +0000
32+++ src/lp2kanban/bugs2cards.py 2013-05-16 15:17:25 +0000
33@@ -2,7 +2,6 @@
34 #
35 from ConfigParser import ConfigParser
36 from argparse import ArgumentParser
37-import httplib2
38 from launchpadlib.launchpad import Launchpad
39 from lp2kanban.cards2workitems import (
40 convert_cards_to_work_items,
41@@ -424,7 +423,7 @@
42 else:
43 lp = Launchpad.login_anonymously(
44 'lp2kanban', config['lp_server'], version="devel",
45- launchapdlib_dir=launchpadlib_dir)
46+ launchpadlib_dir=launchpadlib_dir)
47 print (" Accessing Launchpad anonymously. "
48 "Private bugs will not be synced.")
49 return lp
50@@ -578,7 +577,8 @@
51 args = get_arg_parser().parse_args()
52
53 if args.debug:
54- httplib2.debuglevel = 1
55+ import httplib
56+ httplib.HTTPConnection.debuglevel = 1
57
58 config = ConfigParser()
59 config.read(args.config)
60
61=== modified file 'src/lp2kanban/kanban.py'
62--- src/lp2kanban/kanban.py 2013-04-16 16:57:45 +0000
63+++ src/lp2kanban/kanban.py 2013-05-16 15:17:25 +0000
64@@ -1,7 +1,7 @@
65 # Copyright 2011-2012 Canonical Ltd
66 # -*- coding: utf-8 -*-
67
68-import httplib2
69+import requests
70 import json
71 import operator
72 from pprint import pprint
73@@ -63,9 +63,9 @@
74
75 def _configure_auth(self, username=None, password=None):
76 """Configure the http object to use basic auth headers."""
77- http = httplib2.Http()
78+ http = requests.sessions.Session()
79 if username is not None and password is not None:
80- http.add_credentials(username, password)
81+ http.auth = (username, password)
82 return http
83
84 def post(self, url, data, handle_errors=True):
85@@ -89,8 +89,14 @@
86 self.last_request_time = time.time()
87 try:
88 #print "Fetching " + self.base_api_url + url + "..."
89- resp, content = self.http.request(
90- self.base_api_url + url, action, data, headers)
91+ request = requests.Request(
92+ method=action,
93+ url=self.base_api_url + url,
94+ data=data,
95+ auth=self.http.auth,
96+ headers=headers,
97+ config={})
98+ sent = request.send()
99 except AttributeError as e:
100 # Weirdly, httplib2 has a habit of throwing an AttributeError
101 # when it can't connect, so we handle that nicely.
102@@ -98,12 +104,12 @@
103 except Exception as e:
104 raise IOError("Unable to make HTTP request: %s" % e.message)
105
106- if int(resp['status']) not in LeankitResponseCodes.SUCCESS_CODES:
107+ if not sent or request.response.status_code not in LeankitResponseCodes.SUCCESS_CODES:
108 print "Error from kanban"
109- pprint(resp)
110- raise IOError('kanban error %s' % (resp['status']))
111+ pprint(request.response)
112+ raise IOError('kanban error %d' % (request.response.status_code))
113
114- response = Record(json.loads(content))
115+ response = Record(json.loads(request.response.content))
116
117 if (handle_errors and
118 response.ReplyCode not in LeankitResponseCodes.SUCCESS_CODES):

Subscribers

People subscribed via source and target branches