95
95
abspath = self._real_abspath(relpath)
96
96
curl.setopt(pycurl.URL, abspath)
97
97
self._set_curl_options(curl)
98
curl.setopt(pycurl.HTTPGET, 1)
98
99
# don't want the body - ie just do a HEAD request
99
100
# This means "NO BODY" not 'nobody'
100
101
curl.setopt(pycurl.NOBODY, 1)
115
116
return self._get_full(relpath)
117
118
def _setup_get_request(self, curl, relpath):
119
# Make sure we do a GET request. versions > 7.14.1 also set the
120
# NO BODY flag, but we'll do it ourselves in case it is an older
122
curl.setopt(pycurl.NOBODY, 0)
123
curl.setopt(pycurl.HTTPGET, 1)
124
return self._setup_request(curl, relpath)
126
def _setup_request(self, curl, relpath):
118
127
"""Do the common setup stuff for making a request
120
129
:param curl: The curl object to place the request on
127
136
abspath = self._real_abspath(relpath)
128
137
curl.setopt(pycurl.URL, abspath)
129
138
self._set_curl_options(curl)
130
# Make sure we do a GET request. versions > 7.14.1 also set the
131
# NO BODY flag, but we'll do it ourselves in case it is an older
133
curl.setopt(pycurl.NOBODY, 0)
134
curl.setopt(pycurl.HTTPGET, 1)
136
140
data = StringIO()
137
141
header = StringIO()
179
183
# handle_response will raise NoSuchFile, etc based on the response code
180
184
return code, response.handle_response(abspath, code, headers, data)
182
def _raise_curl_connection_error(self, curl):
183
curl_errno = curl.getinfo(pycurl.OS_ERRNO)
184
url = curl.getinfo(pycurl.EFFECTIVE_URL)
185
raise ConnectionError('curl connection error (%s) on %s'
186
% (os.strerror(curl_errno), url))
186
def _post(self, body_bytes):
187
fake_file = StringIO(body_bytes)
188
curl = self._base_curl
189
# Other places that use _base_curl for GET requests explicitly set
190
# HTTPGET, so it should be safe to re-use the same object for both GETs
192
curl.setopt(pycurl.POST, 1)
193
curl.setopt(pycurl.POSTFIELDSIZE, len(body_bytes))
194
curl.setopt(pycurl.READFUNCTION, fake_file.read)
195
abspath, data, header = self._setup_request(curl, '.bzr/smart')
196
self._curl_perform(curl)
198
code = curl.getinfo(pycurl.HTTP_CODE)
199
headers = _extract_headers(header.getvalue(), abspath)
200
return code, response.handle_response(abspath, code, headers, data)
188
202
def _raise_curl_http_error(self, curl, info=None):
189
203
code = curl.getinfo(pycurl.HTTP_CODE)
200
214
# There's no way in http/1.0 to say "must revalidate"; we don't want
201
215
# to force it to always retrieve. so just turn off the default Pragma
202
216
# provided by Curl.
217
# Also, we override the Expect: header so that pycurl will send the POST
203
219
headers = ['Cache-control: max-age=0',
204
220
'Pragma: no-cache',
205
'Connection: Keep-Alive']
221
'Connection: Keep-Alive',
206
223
## curl.setopt(pycurl.VERBOSE, 1)
207
224
# TODO: maybe include a summary of the pycurl version
208
225
ua_str = 'bzr/%s (pycurl)' % (bzrlib.__version__,)
220
237
mutter('got pycurl error: %s, %s, %s, url: %s ',
221
238
e[0], _pycurl_errors.errorcode[e[0]], e, url)
222
239
if e[0] in (_pycurl_errors.CURLE_COULDNT_RESOLVE_HOST,
223
_pycurl_errors.CURLE_COULDNT_CONNECT):
224
self._raise_curl_connection_error(curl)
240
_pycurl_errors.CURLE_COULDNT_CONNECT,
241
_pycurl_errors.CURLE_COULDNT_RESOLVE_PROXY):
242
raise ConnectionError('curl connection error (%s)\non %s'
225
244
# jam 20060713 The code didn't use to re-raise the exception here
226
245
# but that seemed bogus