2013-12-19 81 views
1

我想在python中編寫簡單的應用程序,他們會使用POST HTTP方法向服務器發送一些文本,然後獲取包含一些文本的響應。無法從POST請求獲取響應正文python

服務器:

from http.server import * 
class MyServer(BaseHTTPRequestHandler): 

    def do_POST(self): 
     self.send_response(200) 
     self.send_header("Content-type","text/plain") 
     self.end_headers() 
     print(self.rfile.read().decode("UTF-8")) 
     self.wfile.write(bytes("TEST RESPONSE", "UTF-8")) 

address = ("",8000) 
httpd = HTTPServer(address, MyServer) 
httpd.serve_forever() 

客戶:

import http.client 
class client: 
    def __init__(self): 
     h = self.request("127.0.0.1:8000", "POST", "OH YEA") 
     resp = h.getresponse() 
     print(resp.status) 
     #data = resp.read() 


    def request(self, host, metoda, strona): 
     headers = { "Host" : host, "Accept": r"text/plain" } 
     h = http.client.HTTPConnection(host) 
     h.request(metoda,"",strona,headers) 
     return h 

a = client() 

那麼只要行數據= resp.read()保持評論的一切工作正常(以及服務器GET請求打印到控制檯體它併發送響應),但是當我嘗試讀取響應身體服務器不打印請求正文,我不明白,即使我得到響應狀態200我不能讀取響應身體(以及整個應用程序「掛斷」)。我究竟做錯了什麼?我猜測,服務器的行爲與未完成的響應處理有關,但我無法完成它因爲我無法得到響應身體。

回答

1

您錯過了HTTP響應中的Content-Length標題。 HTTP客戶端不知道響應完成時,所以它不斷等待更多:

def do_POST(self): 
    content = bytes("TEST RESPONSE", "UTF-8") 
    self.send_response(200) 
    self.send_header("Content-type","text/plain") 
    self.send_header("Content-Length", len(content)) 
    self.end_headers() 
    print(self.rfile.read().decode("UTF-8")) 
    self.wfile.write(content) 

這完全不起作用,但:服務器有同樣的問題:它只是不斷從閱讀rfile

def do_POST(self): 
    content = bytes("TEST RESPONSE", "UTF-8") 
    self.send_response(200) 
    self.send_header("Content-type","text/plain") 
    self.send_header("Content-Length", len(content)) 
    self.end_headers() 
    print(self.rfile.read(int(self.headers['Content-Length'])).decode("UTF-8")) 
    self.wfile.write(content) 

使用curl,這工作得很好:

$ curl -X POST http://localhost:8000 -d 'testrequest' 
TEST RESPONSE 

有辦法做到這一點沒有Content-Length頭,但一開始,這已經足夠了。

編輯:這是一個很好的鍛鍊編寫HTTP客戶端/服務器,但對於生產使用,你可能要考慮更高層次的抽象,如requests爲客戶端和WSGI或完整的web框架對於服務器端(根據您的要求,FlaskDjango是流行的選擇)。

+1

我的上帝的男人我很喜歡你:)因爲http://docs.python.org/2/library/httplib.html我認爲內容長度設置爲automaticaly。現在它當然有效:)謝謝你:)順便說一句:聖誕快樂,新年快樂! – user2184057

+0

謝謝:-)我可能對客戶端的「Content-Length」有錯,您是否嘗試過而不手動設置它?我只是看着文檔,它應該工作:-)順便說一句。 [這是Python 3.x的文檔](http://docs.python.org/3/library/http.html),你正在閱讀2.x版本 – sk1p

相關問題