【问题标题】:Authenticated HTTP POST with XML payload using Python urllib2使用 Python urllib2 使用 XML 有效负载进行身份验证的 HTTP POST
【发布时间】:2010-07-02 10:40:31
【问题描述】:

我正在尝试使用 IronPython 中的 urllib2 发送带有纯 XML 有效负载(我认为)的 POST 消息。但是,每次我发送它时,它都会返回错误代码 400(错误请求)。

我实际上是在尝试模仿 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 请求的了解还不够,不知道是什么。

编辑:顺便说一句,我调用代码如下(它实际上是动态的,但这是基本思想):

PostProtectedPage("http://app.boxee.tv/action/add", "user", "pass", "<message type=\"dequeue\" referral=\"3102296\"></message>")

【问题讨论】:

  • 一个提示。尝试首先在命令行上使用 curl 使其工作。您可以使用 curl 的调试选项来捕获它,这可能会给您一些线索。不幸的是,在 python 中,您也可能需要伪造 curl User-Agent 标头,因为某些编程 HTTP 接口拒绝未知的用户代理。另一种可能性是您需要模仿 boxee 将 Cookie 提供回服务器的方式。
  • 嗯,好点。我忽略了用户代理和 cookie,因为没有它,get 过程可以正常工作。会试一试。谢谢。
  • 我尝试设置一个帐户并自己进行测试,但我无法确定 boxee.tv 上的哪个位置可以正常触发此请求,因此我可以在 Wireshark 中看到它。
  • 你的问题解决了吗?

标签: python http post ironpython urllib2


【解决方案1】:

这对我来说很好用:

curl -v -A 'curl/7.16.3 (Windows  build 7600; en-US; beta) boxee/0.9.21.11487' \
 -H 'Content-Type: text/xml' -u "USER:PASS" \
 --data '<message type="dequeue" referral="12573293"></message>' \
 'http://app.boxee.tv/action/add'

但如果我尝试删除当前不在队列中的推荐 ID,我会收到 400 Bad Request。如果您使用的推荐 ID 与您从 Wireshark 检测到的相同,那么您很可能也会遇到这种情况。使用

wget -nv -m -nd --user=USER --password=PASS http://app.boxee.tv/api/get_queue

确保您要删除的内容确实在队列中。

【讨论】:

    猜你喜欢
    • 2010-10-28
    • 2021-10-13
    • 1970-01-01
    • 2020-12-04
    • 2016-05-11
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    相关资源
    最近更新 更多