2010-10-02 20:45:29 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
import pycurl
|
|
|
|
import StringIO
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
from base import *
|
|
|
|
|
|
|
|
class CurlRequestException(Exception):
|
|
|
|
def __init__(self, value): self.value = value
|
|
|
|
def __str__(self): return repr(self.value)
|
|
|
|
|
|
|
|
class CurlRequest(TestBase):
|
|
|
|
URL = None
|
|
|
|
SCHEME = "http"
|
|
|
|
PORT = 0 # offset to Env.port
|
2010-10-03 13:41:30 +00:00
|
|
|
AUTH = None
|
2010-10-02 20:45:29 +00:00
|
|
|
|
|
|
|
EXPECT_RESPONSE_BODY = None
|
|
|
|
EXPECT_RESPONSE_CODE = None
|
|
|
|
EXPECT_RESPONSE_HEADERS = []
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
super(CurlRequest, self).__init__()
|
|
|
|
self.resp_header_list = []
|
|
|
|
self.resp_headers = { }
|
|
|
|
self.resp_first_line = None
|
|
|
|
|
|
|
|
def _recv_header(self, header):
|
|
|
|
header = header.rstrip()
|
|
|
|
if None == self.resp_first_line:
|
|
|
|
self.resp_first_line = header
|
|
|
|
return
|
|
|
|
if header == "":
|
|
|
|
return
|
|
|
|
try:
|
|
|
|
(key, value) = header.split(":", 1)
|
|
|
|
except:
|
|
|
|
print >> sys.stderr, "Couldn't parse header '%s'" % header
|
|
|
|
raise
|
|
|
|
key = key.strip()
|
|
|
|
value = value.strip()
|
|
|
|
self.resp_header_list.append((key, value))
|
|
|
|
if self.resp_headers.has_key(key):
|
|
|
|
self.resp_headers[key] += ", " + value
|
|
|
|
else:
|
|
|
|
self.resp_headers[key] = value
|
|
|
|
|
|
|
|
def Run(self):
|
|
|
|
if None == self.URL:
|
|
|
|
raise BasicException("You have to set URL in your CurlRequest instance")
|
|
|
|
c = pycurl.Curl()
|
|
|
|
c.setopt(pycurl.URL, self.SCHEME + ("://127.0.0.1:%i" % (Env.port + self.PORT)) + self.URL)
|
|
|
|
c.setopt(pycurl.HTTPHEADER, ["Host: " + self.vhost])
|
2013-04-09 14:29:39 +00:00
|
|
|
c.setopt(pycurl.NOSIGNAL, 1)
|
2013-05-01 15:31:53 +00:00
|
|
|
c.setopt(pycurl.TIMEOUT, 2)
|
2010-10-02 20:45:29 +00:00
|
|
|
b = StringIO.StringIO()
|
|
|
|
c.setopt(pycurl.WRITEFUNCTION, b.write)
|
|
|
|
c.setopt(pycurl.HEADERFUNCTION, self._recv_header)
|
|
|
|
|
2010-10-03 13:41:30 +00:00
|
|
|
if None != self.AUTH:
|
|
|
|
c.setopt(pycurl.USERPWD, self.AUTH)
|
|
|
|
c.setopt(pycurl.FOLLOWLOCATION, 1)
|
|
|
|
c.setopt(pycurl.MAXREDIRS, 5)
|
|
|
|
|
2010-10-02 20:45:29 +00:00
|
|
|
self.curl = c
|
|
|
|
self.buffer = b
|
|
|
|
|
|
|
|
self.PrepareRequest()
|
|
|
|
|
|
|
|
c.perform()
|
|
|
|
|
|
|
|
try:
|
|
|
|
if not self._checkResponse():
|
|
|
|
raise CurlRequestException("Response check failed")
|
|
|
|
except:
|
|
|
|
if not Env.debugRequests:
|
|
|
|
self.dump()
|
|
|
|
raise
|
2010-10-05 11:20:56 +00:00
|
|
|
finally:
|
|
|
|
c.close()
|
|
|
|
self.curl = None
|
2010-10-02 20:45:29 +00:00
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
def PrepareRequest(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def dump(self):
|
|
|
|
c = self.curl
|
2010-10-03 18:59:07 +00:00
|
|
|
Env.log.flush()
|
|
|
|
print >> Env.log, "Dumping request for test '%s'" % self.name
|
|
|
|
print >> Env.log, "Curl request: URL = %s://%s:%i%s" % (self.SCHEME, self.vhost, Env.port + self.PORT, self.URL)
|
|
|
|
print >> Env.log, "Curl response code: %i " % (c.getinfo(pycurl.RESPONSE_CODE))
|
|
|
|
print >> Env.log, "Curl response headers:"
|
2010-10-02 20:45:29 +00:00
|
|
|
for (k, v) in self.resp_header_list:
|
2010-10-03 18:59:07 +00:00
|
|
|
print >> Env.log, " %s: %s" % (k, v)
|
|
|
|
print >> Env.log, "Curl response body:"
|
|
|
|
print >> Env.log, self.buffer.getvalue()
|
|
|
|
Env.log.flush()
|
2010-10-02 20:45:29 +00:00
|
|
|
|
|
|
|
def _checkResponse(self):
|
|
|
|
c = self.curl
|
|
|
|
if Env.debugRequests:
|
|
|
|
self.dump()
|
|
|
|
|
|
|
|
if not self.CheckResponse():
|
|
|
|
return False
|
|
|
|
|
|
|
|
if None != self.EXPECT_RESPONSE_CODE:
|
|
|
|
code = c.getinfo(pycurl.RESPONSE_CODE)
|
|
|
|
if code != self.EXPECT_RESPONSE_CODE:
|
|
|
|
raise CurlRequestException("Unexpected response code %i (wanted %i)" % (code, self.EXPECT_RESPONSE_CODE))
|
|
|
|
|
|
|
|
if None != self.EXPECT_RESPONSE_BODY:
|
|
|
|
body = self.buffer.getvalue()
|
|
|
|
if body != self.EXPECT_RESPONSE_BODY:
|
|
|
|
raise CurlRequestException("Unexpected response body")
|
|
|
|
|
|
|
|
for (k, v) in self.EXPECT_RESPONSE_HEADERS:
|
|
|
|
if not self.resp_headers.has_key(k):
|
|
|
|
raise CurlRequestException("Didn't get wanted response header '%s'" % (k))
|
|
|
|
v1 = self.resp_headers[k]
|
|
|
|
if v1 != v:
|
2010-12-30 14:06:10 +00:00
|
|
|
raise CurlRequestException("Unexpected response header '%s' = '%s' (wanted '%s')" % (k, v1, v))
|
2010-10-02 20:45:29 +00:00
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
def CheckResponse(self):
|
|
|
|
return True
|