Python HTTP Post失败

时间:2012-05-29 15:47:12

标签: python http-post

在搜索了如何使用python发布大文件之后,我遇到了this并且我编写了一个基于此的程序,但是当我运行它时,我收到以下错误消息:

  Traceback (most recent call last):
  File "Test3.py", line 187, in <module>
    main()
  File "Test3.py", line 184, in main
    do_upload(options, args)
  File "Test3.py", line 48, in do_upload
    response = urllib2.urlopen(request)
  File "C:\Python27\lib\urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "C:\Python27\lib\urllib2.py", line 400, in open
    response = meth(req, response)
  File "C:\Python27\lib\urllib2.py", line 513, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python27\lib\urllib2.py", line 438, in error
    return self._call_chain(*args)
  File "C:\Python27\lib\urllib2.py", line 372, in _call_chain
    result = func(*args)
  File "C:\Python27\lib\urllib2.py", line 521, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 500: Internal Server Error

这是我的代码,运行我使用--upload "path_to_file" [space] "filename"的程序。我是python编程的新手,所以大部分仍然让我感到困惑。

def do_upload(options, args):
    url = 'http://127.0.0.1/test_server/upload'

    path = args[0]
   # print path
    filename = args[1]
    if not os.access(args[0], os.F_OK):
                print "Directory/file Doesn't exist"
                exit(1)

    os.chdir(path)
    f = open(filename, 'rb')
    mmapped_file_as_string = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)


    request = urllib2.Request(url, mmapped_file_as_string)
    contenttype = mimetypes.guess_type(filename)[0] 
    request.add_header(contenttype, 'application/octet-stream')
    response = urllib2.urlopen(request)


    #close everything
    mmapped_file_as_string.close()
    f.close()

更新

我已经更改了上面的代码,现在我收到了一些套接字错误。

更新了代码

def do_upload(options, args):

    host = 'http://localhost:80'
    selector = '/test_server/upload'
    url = 'http://localhost:80/test_server/upload'

    if len(args) == 2:
        print "len of args = 2"
        files = "File is " + str(args[1])
        print files
        path = args[0]
        print "Path is " + str(args[0])



    content_type, body = encode_multipart_formdata(files)
    h = httplib.HTTP(host)
    h.putrequest('POST', selector)
    h.putheader('content-type', content_type)
    h.putheader('content-length', str(len(body)))
    h.endheaders()
    h.send(body)
    errcode, errmsg, headers = h.getreply()
    return h.file.read()

    f = open(files, 'rb')
    mmapped_file_as_string = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
    request = urllib2.Request(url, mmapped_file_as_string)
    request.add_header('Content-Type', content_type)
    response = urllib2.urlopen(request)

    mmapped_file_as_string.close()
    f.close()


def encode_multipart_formdata(files):

    BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
    CRLF = '\r\n'
    L = []

    for (filename) in files:
        L.append('--' + BOUNDARY)
        L.append('Content-Disposition: form-data;  filename="%s"' % (filename))
        L.append('Content-Type: %s' % get_content_type(filename))
        L.append('')
        #L.append(value)
    L.append('--' + BOUNDARY + '--')
    L.append('')
    body = CRLF.join(L)
    content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
    return content_type, body

def get_content_type(filename):
    return mimetypes.guess_type(filename)[0] or 'application/octet-stream'

错误消息

Traceback (most recent call last):
  File "Test3.py", line 208, in <module>
    main()
  File "Test3.py", line 205, in main
    do_upload(options, args)
  File "Test3.py", line 41, in do_upload
    h.endheaders()
  File "C:\Python27\lib\httplib.py", line 951, in endheaders
    self._send_output(message_body)
  File "C:\Python27\lib\httplib.py", line 811, in _send_output
    self.send(msg)
  File "C:\Python27\lib\httplib.py", line 773, in send
    self.connect()
  File "C:\Python27\lib\httplib.py", line 754, in connect
    self.timeout, self.source_address)
  File "C:\Python27\lib\socket.py", line 553, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno 11004] getaddrinfo failed

1 个答案:

答案 0 :(得分:4)

您正在设置不存在的标头而不是Content-Type标头:

request.add_header(contenttype, 'application/octet-stream')

将其更改为:

request.add_header('Content-Type', contenttype)

代替。

然而,您最大的问题是您没有上传多部分POST,而只是将文件本身作为POST正文,而您的服务器只需要进行分段上传。

看一下这个SO答案,找到一个非常简单的方法来生成一个正确的多部分POST主体:https://stackoverflow.com/a/681182/100297。请注意,您必须相应地调整Content-Type标头。