Merge lp:~leonardr/launchpad/understand-mod-compress into lp:launchpad

Proposed by Leonard Richardson
Status: Merged
Approved by: Aaron Bentley
Approved revision: no longer in the source branch.
Merged at revision: 10893
Proposed branch: lp:~leonardr/launchpad/understand-mod-compress
Merge into: lp:launchpad
Diff against target: 135 lines (+44/-9)
4 files modified
lib/canonical/launchpad/pagetests/webservice/conditional-write.txt (+36/-0)
lib/canonical/launchpad/rest/configuration.py (+1/-1)
lib/lp/bugs/stories/webservice/xx-bug.txt (+6/-7)
versions.cfg (+1/-1)
To merge this branch: bzr merge lp:~leonardr/launchpad/understand-mod-compress
Reviewer Review Type Date Requested Status
Aaron Bentley (community) Approve
Review via email: mp+25471@code.launchpad.net

Description of the change

This branch installs a new version of lazr.restful into Launchpad (the one defined by https://code.edge.launchpad.net/~leonardr/lazr.restful/understand-mod-compress) and adds tests to ensure that Launchpad's web service will correctly handle incoming ETags that were silently modified by mod_compress on the way out.

To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) wrote :

In the doc, the header should have two blank lines above it.

Since the difference between "foo-gzip" and "foo"-gzip is subtle, please provide the two forms side-by-side, e.g:
mod_compress may turn '"foo"' into '"foo"-gzip'

You use "info" where you mean "into".

Other than that, this looks fine.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/pagetests/webservice/conditional-write.txt'
2--- lib/canonical/launchpad/pagetests/webservice/conditional-write.txt 2010-03-17 14:46:16 +0000
3+++ lib/canonical/launchpad/pagetests/webservice/conditional-write.txt 2010-05-19 17:49:32 +0000
4@@ -101,3 +101,39 @@
5 resource, the later one still gets a 412 error. If an unwritable field
6 changes, a conditional read will fail, but a conditional write will
7 succeed, even though the ETags don't match exactly.
8+
9+
10+It's okay if mod_compress modifies outgoing ETags
11+=================================================
12+
13+Here's another way non-identical ETags may be treated as the
14+same. Apache's mod_compress modifies outgoing ETags when it compresses
15+the representations. Launchpad's web service will treat an ETag
16+modified by mod_compress as though it were the original ETag.
17+
18+ >>> etag = webservice.get(url).jsonBody()['http_etag']
19+
20+ >>> headers = {'If-None-Match': etag}
21+ >>> print webservice.get(url, headers=headers)
22+ HTTP/1.1 304 Not Modified
23+ ...
24+
25+Some versions of mod_compress turn '"foo"' into '"foo"-gzip', and some
26+versions turn it into '"foo-gzip"'. We treat all three forms the same.
27+
28+ >>> headers = {'If-None-Match': etag + "-gzip"}
29+ >>> print webservice.get(url, headers=headers)
30+ HTTP/1.1 304 Not Modified
31+ ...
32+
33+ >>> headers = {'If-None-Match': etag[:-1] + "-gzip" + etag[-1]}
34+ >>> print webservice.get(url, headers=headers)
35+ HTTP/1.1 304 Not Modified
36+ ...
37+
38+Any other modification to the ETag is treated as a distinct ETag.
39+
40+ >>> headers = {'If-None-Match': etag + "-not-gzip"}
41+ >>> print webservice.get(url, headers=headers)
42+ HTTP/1.1 200 Ok
43+ ...
44
45=== modified file 'lib/canonical/launchpad/rest/configuration.py'
46--- lib/canonical/launchpad/rest/configuration.py 2010-03-11 20:53:58 +0000
47+++ lib/canonical/launchpad/rest/configuration.py 2010-05-19 17:49:32 +0000
48@@ -26,7 +26,7 @@
49 active_versions = ["beta", "1.0", "devel"]
50 last_version_with_mutator_named_operations = "beta"
51 view_permission = "launchpad.View"
52- set_hop_by_hop_headers = True
53+ compensate_for_mod_compress_etag_modification = True
54
55 service_description = """The Launchpad web service allows automated
56 clients to access most of the functionality available on the
57
58=== modified file 'lib/lp/bugs/stories/webservice/xx-bug.txt'
59--- lib/lp/bugs/stories/webservice/xx-bug.txt 2010-04-29 17:49:19 +0000
60+++ lib/lp/bugs/stories/webservice/xx-bug.txt 2010-05-19 17:49:32 +0000
61@@ -271,7 +271,7 @@
62 ... content='This is a new message added through the webservice API.')
63 HTTP/1.1 201 Created...
64 Content-Length: 0
65- Content-Type: text/plain
66+ ...
67 Location: http://api.launchpad.dev/beta/firefox/+bug/5/comments/1
68 ...
69
70@@ -290,7 +290,7 @@
71 ... content='This is a new message with no subject.')
72 HTTP/1.1 201 Created...
73 Content-Length: 0
74- Content-Type: text/plain
75+ ...
76 Location: http://api.launchpad.dev/beta/firefox/+bug/5/comments/2
77 ...
78
79@@ -1071,7 +1071,6 @@
80 >>> print response
81 HTTP/1.1 400 Bad Request...
82 Content-Length: 47
83- Content-Type: text/plain
84 ...
85 <BLANKLINE>
86 url: You tried to modify a read-only attribute.
87@@ -1087,7 +1086,7 @@
88 >>> print response
89 HTTP/1.1 201 Created...
90 Content-Length: 0
91- Content-Type: text/plain
92+ ...
93 Location: http://.../bugs/1/+watch/13
94 ...
95
96@@ -1150,7 +1149,7 @@
97 >>> print response
98 HTTP/1.1 301 Moved Permanently...
99 Content-Length: 0
100- Content-Type: text/plain
101+ ...
102 Location: http://.../bugs/bugtrackers/bob
103 ...
104
105@@ -1160,7 +1159,7 @@
106 >>> print webservice.get(bug_tracker['self_link'])
107 HTTP/1.1 404 Not Found...
108 Content-Length: ...
109- Content-Type: text/plain
110+ ...
111 X-Lazr-Oopsid: OOPS-...
112 <BLANKLINE>
113 Object: <...BugTrackerSet object at ...>, name: u'mozilla.org'
114@@ -1233,7 +1232,7 @@
115 >>> print response
116 HTTP/1.1 201 Created...
117 Content-Length: 0
118- Content-Type: text/plain
119+ ...
120 Location: http://.../bugs/1/+attachment/1
121 ...
122
123
124=== modified file 'versions.cfg'
125--- versions.cfg 2010-05-10 21:46:36 +0000
126+++ versions.cfg 2010-05-19 17:49:32 +0000
127@@ -28,7 +28,7 @@
128 lazr.delegates = 1.1.0
129 lazr.enum = 1.1.2
130 lazr.lifecycle = 1.1
131-lazr.restful = 0.9.25
132+lazr.restful = 0.9.26
133 lazr.restfulclient = 0.9.14
134 lazr.smtptest = 1.1
135 lazr.testing = 0.1.1