6
我正嘗試使用IronPython中的urllib2發送純粹的XML負載(我認爲)的POST消息。但是,每次我發送它時,都會返回錯誤代碼400(錯誤請求)。使用Python對XML負載進行身份驗證HTTP POST urllib2
我實際上是試圖模擬天生一個Boxee的刪除隊列項呼籲其實際的數據包看起來像這樣(從Wireshark的):
POST /action/add HTTP/1.1
User-Agent: curl/7.16.3 (Windows build 7600; en-US; beta) boxee/0.9.21.11487
Host: app.boxee.tv
Accept: */*
Accept-Encoding: deflate, gzip
Cookie: boxee_ping_version=9; X-Mapping-oompknoc=76D730BC9E858725098BF13AEFE32EB5; boxee_app=e01e36e85d368d4112fe4d1b6587b1fd
Connection: keep-alive
Content-Type: text/xml
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Language: en-us,en;q=0.5
Keep-Alive: 300
Connection: keep-alive
Content-Length: 53
<message type="dequeue" referral="3102296"></message>
我使用下面的Python代碼發送POST :
def PostProtectedPage(theurl, username, password, postdata):
req = urllib2.Request(theurl, data=postdata)
req.add_header('Content-Type', 'text/xml')
try:
handle = urllib2.urlopen(req)
except IOError, e: # here we are assuming we fail
pass
else: # If we don't fail then the page isn't protected
print "This page isn't protected by authentication."
sys.exit(1)
if not hasattr(e, 'code') or e.code != 401: # we got an error - but not a 401 error
print "This page isn't protected by authentication."
print 'But we failed for another reason.'
sys.exit(1)
authline = e.headers.get('www-authenticate', '') # this gets the www-authenticat line from the headers - which has the authentication scheme and realm in it
if not authline:
print 'A 401 error without an authentication response header - very weird.'
sys.exit(1)
authobj = re.compile(r'''(?:\s*www-authenticate\s*:)?\s*(\w*)\s+realm=['"](\w+)['"]''', re.IGNORECASE) # this regular expression is used to extract scheme and realm
matchobj = authobj.match(authline)
if not matchobj: # if the authline isn't matched by the regular expression then something is wrong
print 'The authentication line is badly formed.'
sys.exit(1)
scheme = matchobj.group(1)
realm = matchobj.group(2)
if scheme.lower() != 'basic':
print 'This example only works with BASIC authentication.'
sys.exit(1)
base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
authheader = "Basic %s" % base64string
req.add_header("Authorization", authheader)
try:
handle = urllib2.urlopen(req)
except IOError, e: # here we shouldn't fail if the username/password is right
print "It looks like the username or password is wrong."
print e
sys.exit(1)
thepage = handle.read()
return thepage
但是,每當我運行它,它會返回錯誤400(無效請求)
我知道驗證是正確的,因爲我用它在其他地方獲取隊列(我無法想象它不會使用,否則它會怎麼樣哪個帳戶應用更改?)
看看網絡捕獲,我可以簡單地缺少添加一些頭到請求?可能有些簡單,但我對python或HTTP請求知之甚少。
編輯:BTW,我打電話的代碼如下所示(它實際上是動態的,但是這是基本的想法):
PostProtectedPage("http://app.boxee.tv/action/add", "user", "pass", "<message type=\"dequeue\" referral=\"3102296\"></message>")
一個提示。嘗試讓它在命令行中首先使用curl工作。你可以使用curl的調試選項來捕獲它,這可能會給你一些線索。在python中也可能需要僞造curl用戶代理頭,因爲一些程序化的HTTP接口拒絕未知的用戶代理。 另一種可能性是您需要模仿boxee向服務器提供Cookies的方式。 – 2010-07-02 13:56:11
嗯,好點。我忽略了用戶代理和cookie,因爲沒有它,get過程運行良好。會給它一個鏡頭。謝謝。 – 2010-07-02 14:26:19
我試着自己建立一個帳戶並進行測試,但我無法弄清楚boxee.tv上的哪個地方能正常觸發這個請求,所以我可以在Wireshark中看到它。 – 2011-05-23 16:17:18