代码之家  ›  专栏  ›  技术社区  ›  Paul Nathan

httplib:读取不完整

  •  2
  • Paul Nathan  · 技术社区  · 14 年前

    我在客户端和服务器端都有一些Python代码。我收到了一个未完成的读异常,原因似乎不是很好。我可以使用firefox导航到url而不显示任何错误消息,也可以设置为不显示任何奇怪的结果。

    服务器代码为:

    import random
    import hashlib
    print "Content-Type: text/html"     
    print                              
    
    m = hashlib.md5()
    m.update(str(random.random()))
    print m.hexdigest()
    print
    

    在客户机站点上,我使用相对简单的post方法:

        data = urllib.urlencode({"username": username,
                         "password" : password})
        #POST in the data.
        req = urllib2.Request(url, data)
    
        response = urllib2.urlopen(req)
        string =  response.read()
    

    而response.read()则抛出错误。

    编辑:更多信息-添加明确的CRLF排放不会改变更改。检查错误日志

    [Wed Sep 08 10:36:43 2010] [error] [client 192.168.80.1] (104)Connection reset by peer: ap_content_length_filter: apr_bucket_read() failed
    

    ssl访问日志显示(轻度修订):

    192.168.80.1 - - [08/Sep/2010:10:38:02 -0700] "POST /serverfile.py HTTP/1.1" 200 1357 "-" "Python-urllib/2.7"
    
    4 回复  |  直到 12 年前
        1
  •  1
  •   Carlos Valiente    14 年前

    是否使用 \r\n 有什么区别吗?像这样:

    import random
    import hashlib
    import sys
    
    sys.stdout.write("Content-Type: text/html\r\n\r\n")
    
    m = hashlib.md5()
    m.update(str(random.random()))
    print m.hexdigest()
    print
    
        2
  •  1
  •   Paul Nathan    14 年前

    问题是Apache中的一个bug。

    当接收脚本不使用所有post请求时,Apache会抛出这种特定类型的错误。

    Apache开发人员认为这是一种“按设计”的设计。

    解决办法是 尽快 :

    workaround = cgi.FieldStorage()
    
        3
  •  0
  •   FutureNerd    12 年前

    当我未能完全阅读 以前的 响应,例如:

    # This is using an opener from urllib2, but I am guessing similar...
    response1 = opener.open(url1)
    for line in response1:
        m = re.match("href='(.*)'", line):
        if m:
            url2 = m.group(1) # Grab the URL from line, that's all I want.
            break             # Oops.  Apache is mad because I suck.
    
    response2 = opener.open(url2)
    for line in response2:
        print line
    

    服务器在第一次请求时给了我“200 OK”,接着是数据到我要查找的链接,然后在第二次打开时等待了5分钟,然后在第二次请求时给了我“200 OK”,接着是第二次请求的所有数据,然后在第一次请求时给了我未完成的读取!

    我在读保罗的原稿登录的字里行间 在第二个站点上发现了问题。

    我可以看到并行阅读两页可能是一个很好的功能。那么,我该怎么做才能优雅地告诉服务器“不用了,谢谢?”我通过阅读并忽略第一个请求的其余部分(在本例中只有200K)来解决这个问题。

    如果允许我评论而不是回答,我会问保罗·内森,

    是什么

    workaround = cgi.FieldStorage()
    

    你所说的“尽快”是什么意思?它在这里有什么帮助?可怜一个初学者。

        4
  •  0
  •   FutureNerd    12 年前

    我猜原来的海报实际上运行了两次请求,第一次成功,第二次失败。

    我(从阿帕奇)没有完全读完 以前的 响应,例如:

    # This is using an opener from urllib2, but I am guessing similar...
    response1 = opener.open(url1)
    for line in response1:
        m = re.match("href='(.*)'", line):
        if m:
            url2 = m.group(1) # Grab the URL from line, that's all I want.
            break             # Oops.  Apache is mad because I suck.
    
    response2 = opener.open(url2)
    for line in response2:
        print line
    

    服务器在第一次请求时给了我“200可以”,接着是数据到我正在寻找的链接,然后在第二次打开时等待了5分钟,然后在第二次请求时给了我“200可以”,接着是第二次请求的所有数据,然后给了我未完成的读取!在第二个for语句中(对我来说)发生了错误,可能是在它碰到文件末尾的时候。

    我可以想象想要同时打开两个响应进行阅读。所以问题是,我该如何回答呢?即使我不需要这些数据,我也必须读取所有的数据吗?不, urllib.urlopen documentation )响应就像一个文件,只需关闭它,所以在我的示例中,

    for line in response1:
        m = re.match("href='(.*)'", line):
        if m:
            url2 = m.group(1) # Grab the URL from line, that's all I want.
            break
    
    response1.close()
    response2 = opener.open(url2)
    ...