~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/http/_pycurl.py

  • Committer: Vincent Ladeuil
  • Date: 2007-02-12 14:02:01 UTC
  • mto: (2323.7.1 redirection)
  • mto: This revision was merged to the branch mainline in revision 2390.
  • Revision ID: v.ladeuil+lp@free.fr-20070212140201-khf5tnm6skh2ic0k
Add tests.

* bzrlib/transport/http/_urllib.py:
(HttpTransport_urllib.has): Ignores 302 error code, it is already
handled.

* bzrlib/transport/http/_pycurl.py:
(PyCurlTransport.has): Set headers acquisition. Pass headers to
_curl_perform. Ignores 302 error code, it is already
handled.
(PyCurlTransport._get_full, PyCurlTransport._get_ranged): Pass
headers to _curl_perform.
(PyCurlTransport._post): Pass headers to _curl_perform.
(PyCurlTransport._set_curl_options): Do not follow redirections
anymore.
(PyCurlTransport._curl_perform): Handle redirections by raising

* bzrlib/tests/test_http.py:
(TestHTTPRedirections): Simplified.
(TestHTTPRedirections_pycurl): New class.

* bzrlib/tests/test_bzrdir.py:
(TestHTTPRedirectionLoop, TestHTTPRedirections_urllib,
TestHTTPRedirections_pycurl): New classes to test redirection
loops when opening bzrdirs.

* bzrlib/tests/HTTPTestUtil.py:
(HTTPServerRedirecting.redirect_to,
HTTPServerRedirecting.redirected_to_address): New methods.

* bzrlib/bzrdir.py:
(BzrDirMetaFormat1.probe_transport): Deleted.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
# whether we expect a particular file will be modified after it's committed.
24
24
# It's probably safer to just always revalidate.  mbp 20060321
25
25
 
 
26
# TODO: Some refactoring could be done to avoid the strange idiom
 
27
# used to capture data and headers while setting up the request
 
28
# (and having to pass 'header' to _curl_perform to handle
 
29
# redirections) . This could be achieved by creating a
 
30
# specialized Curl object and returning code, headers and data
 
31
# from _curl_perform.  Not done because we may deprecate pycurl in the
 
32
# future -- vila 20070212
 
33
 
26
34
import os
27
35
from cStringIO import StringIO
28
36
 
102
110
        # don't want the body - ie just do a HEAD request
103
111
        # This means "NO BODY" not 'nobody'
104
112
        curl.setopt(pycurl.NOBODY, 1)
 
113
        # But we need headers to handle redirections
 
114
        header = StringIO()
 
115
        curl.setopt(pycurl.HEADERFUNCTION, header.write)
105
116
        # In some erroneous cases, pycurl will emit text on
106
117
        # stdout if we don't catch it (see InvalidStatus tests
107
118
        # for one such occurrence).
108
119
        blackhole = StringIO()
109
120
        curl.setopt(pycurl.WRITEFUNCTION, blackhole.write)
110
 
        self._curl_perform(curl)
 
121
        self._curl_perform(curl, header)
111
122
        code = curl.getinfo(pycurl.HTTP_CODE)
112
123
        if code == 404: # not found
113
124
            return False
114
 
        elif code in (200, 302): # "ok", "found"
 
125
        elif code == 200: # "ok"
115
126
            return True
116
127
        else:
117
128
            self._raise_curl_http_error(curl)
156
167
        """Make a request for the entire file"""
157
168
        curl = self._curl
158
169
        abspath, data, header = self._setup_get_request(curl, relpath)
159
 
        self._curl_perform(curl)
 
170
        self._curl_perform(curl, header)
160
171
 
161
172
        code = curl.getinfo(pycurl.HTTP_CODE)
162
173
        data.seek(0)
179
190
            # Forget ranges, the server can't handle them
180
191
            return self._get_full(relpath)
181
192
 
182
 
        self._curl_perform(curl, ['Range: bytes=%s'
183
 
                                  % self.range_header(ranges, tail_amount)])
 
193
        self._curl_perform(curl, header,
 
194
                           ['Range: bytes=%s'
 
195
                            % self.range_header(ranges, tail_amount)])
184
196
        data.seek(0)
185
197
 
186
198
        code = curl.getinfo(pycurl.HTTP_CODE)
201
213
        abspath, data, header = self._setup_request(curl, '.bzr/smart')
202
214
        # We override the Expect: header so that pycurl will send the POST
203
215
        # body immediately.
204
 
        self._curl_perform(curl,['Expect: '])
 
216
        self._curl_perform(curl, header, ['Expect: '])
205
217
        data.seek(0)
206
218
        code = curl.getinfo(pycurl.HTTP_CODE)
207
219
        headers = _extract_headers(header.getvalue(), abspath)
229
241
        # TODO: maybe include a summary of the pycurl version
230
242
        ua_str = 'bzr/%s (pycurl)' % (bzrlib.__version__,)
231
243
        curl.setopt(pycurl.USERAGENT, ua_str)
232
 
        curl.setopt(pycurl.FOLLOWLOCATION, 1) # follow redirect responses
233
244
 
234
 
    def _curl_perform(self, curl, more_headers=[]):
 
245
    def _curl_perform(self, curl, header, more_headers=[]):
235
246
        """Perform curl operation and translate exceptions."""
236
247
        try:
237
248
            # There's no way in http/1.0 to say "must
264
275
            # jam 20060713 The code didn't use to re-raise the exception here,
265
276
            # but that seemed bogus
266
277
            raise
 
278
        code = curl.getinfo(pycurl.HTTP_CODE)
 
279
        if code in (301, 302, 303, 307):
 
280
            url = curl.getinfo(pycurl.EFFECTIVE_URL)
 
281
            headers = _extract_headers(header.getvalue(), url)
 
282
            redirected_to = headers['Location']
 
283
            raise errors.RedirectRequested(url,
 
284
                                           redirected_to,
 
285
                                           is_permament=(code == 301),
 
286
                                           qual_proto=self._qualified_proto)
267
287
 
268
288
 
269
289
def get_test_permutations():