代码之家  ›  专栏  ›  技术社区  ›  Adam Haile

使用python urllib2使用xml负载验证http post

  •  6
  • Adam Haile  · 技术社区  · 14 年前

    我试图使用ironpython中的urllib2发送一个纯xml有效负载的post消息。但是,每次我发送它,它都会返回错误代码400(错误请求)。

    我实际上是在模仿一个boxe-remove队列项调用,它的实际数据包如下所示(来自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代码发送邮件:

    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>")
    
    1 回复  |  直到 14 年前
        1
  •  0
  •   Mu Mind hora    14 年前

    这对我很有用:

    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'
    

    但我知道 400 Bad Request 如果我尝试删除当前不在队列中的引用ID。如果你使用的是从wireshark检测到的相同的转介ID,那么你也很可能会遇到这种情况。使用

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

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