2012-05-29 102 views
0

尋找如何發佈使用Python大文件後,我碰到this和我寫了基於這樣的軟件,但是當我運行它,我得到了以下錯誤消息:Python的HTTP POST失敗

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() 

UPDATE

我從上面,現在我得到一些套接字錯誤改變了代碼。

更新代碼

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 
+0

你能發表'test_server/upload'代碼嗎? – dm03514

+0

完成! ,我想提一件事情,我可以使用cURL上傳文件,但沒有任何問題。 – cyberbemon

回答

4

要設置一個不存在的報頭,而不是Content-Type頭:

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

將其改爲:

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

改爲。

然而,您最大的問題在於您沒有上傳多部分POST,而只是將文件本身作爲POST正文,而您的服務器只需要分段上傳。

看看這個SO回答爲一個非常簡單的方法來生成一個適當的multipart POST機構:https://stackoverflow.com/a/681182/100297。請注意,您必須相應地調整您的Content-Type標頭。

+0

沒有修復它,它從錯誤消息中更改了前3行並將它們替換爲這些「File3.test3.py」,第178行,在 main() 文件「Test3.py」,第175行,在主 do_upload(options,args) 文件「Test3.py」,第39行,在do_upload response = urllib2.urlopen(request)' – cyberbemon

+0

謝謝,看看代碼我有點困惑, def post_multipart(主機,選擇器,字段,文件):'該函數中的選擇器意味着 – cyberbemon

+0

它是URL的路徑部分; '/ test_server/upload'在你的情況。 –