def request(self, method, url, headers, post_data=None):
s = util.StringIO.StringIO()
rheaders = util.StringIO.StringIO()
curl = pycurl.Curl()
proxy = self._get_proxy(url)
if proxy:
if proxy.hostname:
curl.setopt(pycurl.PROXY, proxy.hostname)
if proxy.port:
curl.setopt(pycurl.PROXYPORT, proxy.port)
if proxy.username or proxy.password:
curl.setopt(
pycurl.PROXYUSERPWD,
"%s:%s" % (proxy.username, proxy.password))
if method == 'get':
curl.setopt(pycurl.HTTPGET, 1)
elif method == 'post':
curl.setopt(pycurl.POST, 1)
curl.setopt(pycurl.POSTFIELDS, post_data)
else:
curl.setopt(pycurl.CUSTOMREQUEST, method.upper())
# pycurl doesn't like unicode URLs
curl.setopt(pycurl.URL, util.utf8(url))
curl.setopt(pycurl.WRITEFUNCTION, s.write)
curl.setopt(pycurl.HEADERFUNCTION, rheaders.write)
curl.setopt(pycurl.NOSIGNAL, 1)
curl.setopt(pycurl.CONNECTTIMEOUT, 30)
curl.setopt(pycurl.TIMEOUT, 80)
curl.setopt(pycurl.HTTPHEADER, ['%s: %s' % (k, v)
for k, v in headers.items()])
if self._verify_ssl_certs:
curl.setopt(pycurl.CAINFO, os.path.join(
os.path.dirname(__file__), 'data/ca-certificates.crt'))
else:
curl.setopt(pycurl.SSL_VERIFYHOST, False)
try:
curl.perform()
except pycurl.error as e:
self._handle_request_error(e)
rbody = s.getvalue()
rcode = curl.getinfo(pycurl.RESPONSE_CODE)
return rbody, rcode, self.parse_headers(rheaders.getvalue())
python类POST的实例源码
def submit(self, captcha, captchaType="file", match=None):
try:
img = Image.open(captcha)
output = StringIO.StringIO()
self.log_debug("CAPTCHA IMAGE", img, img.format, img.mode)
if img.format in ("GIF", "JPEG"):
img.save(output, img.format)
else:
if img.mode != "RGB":
img = img.convert("RGB")
img.save(output, "JPEG")
data = output.getvalue()
output.close()
except Exception, e:
raise CaptchaBrotherhoodException(
"Reading or converting captcha image failed: %s" % e)
req = get_request()
url = "%ssendNewCaptcha.aspx?%s" % (self.API_URL,
urllib.urlencode({'username': self.config.get('username'),
'password': self.config.get('password'),
'captchaSource': "pyLoad",
'timeout': "80"}))
req.c.setopt(pycurl.URL, url)
req.c.setopt(pycurl.POST, 1)
req.c.setopt(pycurl.POSTFIELDS, data)
req.c.setopt(pycurl.HTTPHEADER, ["Content-Type: text/html"])
try:
req.c.perform()
res = req.getResponse()
except Exception, e:
raise CaptchaBrotherhoodException("Submit captcha image failed")
req.close()
if not res.startswith("OK"):
raise CaptchaBrotherhoodException(res[1])
ticket = res[3:]
for _i in range(15):
time.sleep(5)
res = self.api_response("askCaptchaResult", ticket)
if res.startswith("OK-answered"):
return ticket, res[12:]
raise CaptchaBrotherhoodException("No solution received in time")
def set_request_context(self, url, get, post,
referer, cookies, multipart=False):
"""
Sets everything needed for the request.
"""
url = safequote(url)
if get:
get = urlencode(get)
url = "{0}?{1}".format(url, get)
self.setopt(pycurl.URL, url)
if post:
self.setopt(pycurl.POST, 1)
if not multipart:
if isinstance(post, str):
post = convert.to_bytes(post, post)
elif not isinstance(post, bytes):
post = safeurlencode(post)
self.setopt(pycurl.POSTFIELDS, post)
else:
post = [(x, convert.to_bytes(y, y))
for x, y in post.items()]
self.setopt(pycurl.HTTPPOST, post)
else:
self.setopt(pycurl.POST, 0)
if referer and self.last_url:
self.headers['Referer'] = str(self.last_url)
else:
self.headers['Referer'] = ""
if cookies:
for c in self.cj.output().splitlines():
self.setopt(pycurl.COOKIELIST, c)
else:
# Magic string that erases all cookies
self.setopt(pycurl.COOKIELIST, 'ALL')
# TODO: remove auth again
if "auth" in self.options:
self.setopt(pycurl.USERPWD, self.options['auth'])
self.setopt(pycurl.HTTPHEADER, self.headers.list())
def load(self, url, get={}, post={}, referer=True, cookies=True,
just_header=False, multipart=False, decode=False):
"""
Load and returns a given page.
"""
self.set_request_context(url, get, post, referer, cookies, multipart)
# TODO: use http/rfc message instead
self.header = ""
if "header" in self.options:
# TODO
# print("custom header not implemented")
self.setopt(pycurl.HTTPHEADER, self.options['header'])
if just_header:
self.setopt(pycurl.FOLLOWLOCATION, 0)
self.setopt(pycurl.NOBODY, 1) # TODO: nobody= no post?
# overwrite HEAD request, we want a common request type
if post:
self.setopt(pycurl.CUSTOMREQUEST, 'POST')
else:
self.setopt(pycurl.CUSTOMREQUEST, 'GET')
try:
self.c.perform()
rep = self.header
finally:
self.setopt(pycurl.FOLLOWLOCATION, 1)
self.setopt(pycurl.NOBODY, 0)
self.unsetopt(pycurl.CUSTOMREQUEST)
else:
self.c.perform()
rep = self.get_response()
self.setopt(pycurl.POSTFIELDS, '')
self.last_url = safequote(url)
self.last_effective_url = self.c.getinfo(pycurl.EFFECTIVE_URL)
if self.last_effective_url:
self.last_url = self.last_effective_url
self.code = self.verify_header()
if cookies:
self.parse_cookies()
if decode:
rep = self.decode_response(rep)
return rep
def fetch(self, url, body=None, headers=None):
"""Perform an HTTP request
@raises Exception: Any exception that can be raised by httplib2
@see: C{L{HTTPFetcher.fetch}}
"""
if body:
method = 'POST'
else:
method = 'GET'
if headers is None:
headers = {}
# httplib2 doesn't check to make sure that the URL's scheme is
# 'http' so we do it here.
if not (url.startswith('http://') or url.startswith('https://')):
raise ValueError('URL is not a HTTP URL: %r' % (url,))
httplib2_response, content = self.httplib2.request(
url, method, body=body, headers=headers)
# Translate the httplib2 response to our HTTP response abstraction
# When a 400 is returned, there is no "content-location"
# header set. This seems like a bug to me. I can't think of a
# case where we really care about the final URL when it is an
# error response, but being careful about it can't hurt.
try:
final_url = httplib2_response['content-location']
except KeyError:
# We're assuming that no redirects occurred
assert not httplib2_response.previous
# And this should never happen for a successful response
assert httplib2_response.status != 200
final_url = url
return HTTPResponse(
body=content,
final_url=final_url,
headers=dict(httplib2_response.items()),
status=httplib2_response.status,
)
def submit(self, captcha, captchaType="file", match=None):
try:
img = Image.open(captcha)
output = StringIO.StringIO()
self.log_debug("CAPTCHA IMAGE", img, img.format, img.mode)
if img.format in ("GIF", "JPEG"):
img.save(output, img.format)
else:
if img.mode != "RGB":
img = img.convert("RGB")
img.save(output, "JPEG")
data = output.getvalue()
output.close()
except Exception, e:
raise CaptchaBrotherhoodException(
"Reading or converting captcha image failed: %s" % e)
req = get_request()
url = "%ssendNewCaptcha.aspx?%s" % (self.API_URL,
urllib.urlencode({'username': self.config.get('username'),
'password': self.config.get('password'),
'captchaSource': "pyLoad",
'timeout': "80"}))
req.c.setopt(pycurl.URL, url)
req.c.setopt(pycurl.POST, 1)
req.c.setopt(pycurl.POSTFIELDS, data)
req.c.setopt(pycurl.HTTPHEADER, ["Content-Type: text/html"])
try:
req.c.perform()
res = req.getResponse()
except Exception, e:
raise CaptchaBrotherhoodException("Submit captcha image failed")
req.close()
if not res.startswith("OK"):
raise CaptchaBrotherhoodException(res[1])
ticket = res[3:]
for _i in range(15):
time.sleep(5)
res = self.api_response("askCaptchaResult", ticket)
if res.startswith("OK-answered"):
return ticket, res[12:]
raise CaptchaBrotherhoodException("No solution received in time")
def version_update(self):
if not obplayer.Config.setting('sync_url'):
return
obplayer.Log.log('sending player version to server: ' + obplayer.Config.version, 'sync')
postfields = {}
postfields['id'] = obplayer.Config.setting('sync_device_id')
postfields['pw'] = obplayer.Config.setting('sync_device_password')
postfields['version'] = obplayer.Config.version
postfields['longitude'] = obplayer.Config.setting('location_longitude')
postfields['latitude'] = obplayer.Config.setting('location_latitude')
curl = pycurl.Curl()
enc_postfields = urllib.urlencode(postfields)
curl.setopt(pycurl.NOSIGNAL, 1)
curl.setopt(pycurl.USERAGENT, 'OpenBroadcaster Player')
curl.setopt(pycurl.URL, obplayer.Config.setting('sync_url') + '?action=version')
curl.setopt(pycurl.HEADER, False)
curl.setopt(pycurl.POST, True)
curl.setopt(pycurl.POSTFIELDS, enc_postfields)
curl.setopt(pycurl.LOW_SPEED_LIMIT, 10)
curl.setopt(pycurl.LOW_SPEED_TIME, 60)
curl.setopt(pycurl.NOPROGRESS, 0)
curl.setopt(pycurl.PROGRESSFUNCTION, self.curl_progress)
class CurlResponse:
def __init__(self):
self.buffer = u''
def __call__(self, data):
self.buffer += data.decode('utf-8')
curl_response = CurlResponse()
curl.setopt(pycurl.WRITEFUNCTION, curl_response)
try:
curl.perform()
except:
obplayer.Log.log("exception in VersionUpdate thread", 'error')
obplayer.Log.log(traceback.format_exc(), 'error')
curl.close()
if curl_response.buffer:
version = json.loads(curl_response.buffer)
obplayer.Log.log("server version reported as " + str(version), 'sync')
if not self.check_min_version(version):
obplayer.Log.log("minimum server version " + str(MIN_SERVER_VERSION) + " is required. Please update server software before continuing", 'error')
else:
obplayer.Log.log("server did not report a version number", 'warning')
def now_playing_update_thread(self, playlist_id, playlist_end, media_id, media_end, show_name):
if not obplayer.Config.setting('sync_url'):
return
postfields = {}
postfields['id'] = obplayer.Config.setting('sync_device_id')
postfields['pw'] = obplayer.Config.setting('sync_device_password')
postfields['playlist_id'] = playlist_id
postfields['media_id'] = media_id
postfields['show_name'] = show_name
if playlist_end != '':
postfields['playlist_end'] = int(round(playlist_end))
else:
postfields['playlist_end'] = ''
if media_end != '':
postfields['media_end'] = int(round(media_end))
else:
postfields['media_end'] = ''
curl = pycurl.Curl()
enc_postfields = urllib.urlencode(postfields)
curl.setopt(pycurl.NOSIGNAL, 1)
curl.setopt(pycurl.USERAGENT, 'OpenBroadcaster Player')
curl.setopt(pycurl.URL, obplayer.Config.setting('sync_url') + '?action=now_playing')
curl.setopt(pycurl.HEADER, False)
curl.setopt(pycurl.POST, True)
curl.setopt(pycurl.POSTFIELDS, enc_postfields)
#curl.setopt(pycurl.FOLLOWLOCATION, 1)
curl.setopt(pycurl.LOW_SPEED_LIMIT, 10)
curl.setopt(pycurl.LOW_SPEED_TIME, 60)
curl.setopt(pycurl.NOPROGRESS, 0)
curl.setopt(pycurl.PROGRESSFUNCTION, self.curl_progress)
try:
curl.perform()
except:
obplayer.Log.log("exception in NowPlayingUpdate thread", 'error')
obplayer.Log.log(traceback.format_exc(), 'error')
curl.close()
#
# Request sync data from web application.
# This is used by sync (with request_type='schedule') and sync_priority_broadcasts (with request_type='emerg').
# Function outputs XML response from server.
#
def sync_request(self, request_type='', data=False):
sync_url = obplayer.Config.setting('sync_url')
if not sync_url:
obplayer.Log.log("sync url is blank, skipping sync request", 'sync')
return ''
curl = pycurl.Curl()
postfields = {}
postfields['id'] = obplayer.Config.setting('sync_device_id')
postfields['pw'] = obplayer.Config.setting('sync_device_password')
postfields['hbuffer'] = obplayer.Config.setting('sync_buffer')
if data:
postfields['data'] = data
enc_postfields = urllib.urlencode(postfields)
curl.setopt(pycurl.NOSIGNAL, 1)
curl.setopt(pycurl.USERAGENT, 'OpenBroadcaster Player')
curl.setopt(pycurl.URL, sync_url + '?action=' + request_type)
curl.setopt(pycurl.HEADER, False)
curl.setopt(pycurl.POST, True)
curl.setopt(pycurl.POSTFIELDS, enc_postfields)
# some options so that it'll abort the transfer if the speed is too low (i.e., network problem)
# low speed abort set to 0.01Kbytes/s for 60 seconds).
curl.setopt(pycurl.LOW_SPEED_LIMIT, 10)
curl.setopt(pycurl.LOW_SPEED_TIME, 60)
curl.setopt(pycurl.NOPROGRESS, 0)
curl.setopt(pycurl.PROGRESSFUNCTION, self.curl_progress)
class CurlResponse:
def __init__(self):
self.buffer = u''
def __call__(self, data):
self.buffer += data.decode('utf-8')
curl_response = CurlResponse()
curl.setopt(pycurl.WRITEFUNCTION, curl_response)
try:
curl.perform()
#except pycurl.error as error:
# (errno, errstr) = error
# obplayer.Log.log('network error: ' + errstr, 'error')
except:
obplayer.Log.log("exception in sync " + request_type + " thread", 'error')
obplayer.Log.log(traceback.format_exc(), 'error')
curl.close()
return curl_response.buffer
#
# Fetch media from web application. Saves under media directory.
# media_id : id of the media we want
# filename : filename to save under.
#
def fetch(self, url, body=None, headers=None):
"""Perform an HTTP request
@raises Exception: Any exception that can be raised by httplib2
@see: C{L{HTTPFetcher.fetch}}
"""
if body:
method = 'POST'
else:
method = 'GET'
if headers is None:
headers = {}
# httplib2 doesn't check to make sure that the URL's scheme is
# 'http' so we do it here.
if not (url.startswith('http://') or url.startswith('https://')):
raise ValueError('URL is not a HTTP URL: %r' % (url,))
httplib2_response, content = self.httplib2.request(
url, method, body=body, headers=headers)
# Translate the httplib2 response to our HTTP response abstraction
# When a 400 is returned, there is no "content-location"
# header set. This seems like a bug to me. I can't think of a
# case where we really care about the final URL when it is an
# error response, but being careful about it can't hurt.
try:
final_url = httplib2_response['content-location']
except KeyError:
# We're assuming that no redirects occurred
assert not httplib2_response.previous
# And this should never happen for a successful response
assert httplib2_response.status != 200
final_url = url
return HTTPResponse(
body=content,
final_url=final_url,
headers=dict(httplib2_response.items()),
status=httplib2_response.status,
)