2016-04-06 101 views
1

我正在寫一個簡單的網絡服務器在Python中,並已成功這樣做。我能夠在JavaScript文件中呈現html頁面,但無法呈現圖像。PNG圖像在自定義python網絡服務器響應

一些相關的代碼,

def createResponse(self, data):#, last_modified=0): 
     # print data 
     response_code = data[0] 
     mimetype = data[1][1] 
     data = data[1][0]    # (200, (data, mimetype)) 

     res = "HTTP/1.0 " + self.config['STATUS_STRING'][str(response_code)] + "\r\n" 
     res += "Content-Type: " + mimetype + "\r\n" 
     res += "Date: " + strftime("%a, %d %b %Y %X GMT", gmtime()) + "\r\n" 
     # if last_modified: 
     #  res += "Last Modified: " + last_modified + "\r\n" 
     res += 'Server: ' + self.config['SERVER_NAME'] + "\r\n" 
     res += 'Connection: close' + '\r\n' # signal that the conection wil be closed after complting the request 
     res += "\r\n" 
     res += data 

     return res.encode("utf8") 

def _handleGET(self, path): 
    # some stuff, then 
    # File exists and read permission, so give file 
    try: 
     fp = open(filepath, "rb") 
    except IOError as e: 
     if e.errno == errno.EACCES: 
      return (500, self._readFile(self.config['ERROR_DIR'] + '/' + str(500) + ".html")); 
     # Not a permission error. 
     raise 
    else: 
     with fp: 
      return (200, (fp.read().decode("utf8"), mimetypes.guess_type(filepath)[0])) # return (200,(data,mimetype)) 

我創建一個套接字到客戶端,並返回使用該響應,

clientSocket.sendall(self.createResponse(self._handleGET(data))) 

我編碼整個響應,這是一個字符串在utf8中。這適用於html頁面和js文件,以及css文件,但不適用於圖像。 (PNG,GIF等)。我嘗試設置標題和編碼base64二進制等圖像的響應,但我無法實現它。

  • 關於如何做到這一點有什麼建議?
  • 這甚至可能,因爲現在我覺得它不是有可能使使用這種方法圖像,標題將是utf8,而圖像的內容將是其它編碼。所以他們不能連接。糾正我,如果我錯了。
+0

不要嘗試自己寫一個HTTP服務器。使用像燒瓶或瓶子這樣的框架。 – Daniel

+0

顯然,預製服務器將會好得多,但無論是自己寫一個基本的服務器以瞭解幕後發生的事情的好學習經驗, – Keatinge

+0

@PinkeshBadjatiya:我很好奇。爲什麼你將'self'作爲參數傳遞給'_handleGET'?實例方法已經通過'self',所以它應該只需要'self._handleGET(data)'就足夠了。 –

回答

0

HTTP的標題不被編碼,而應該是純ASCII。內容部分是任何二進制數據。對於文本,可以在Content-Type中指定編碼。 因此createResponse必須處理文本和二進制數據seperately,也許有明確的編碼參數:

def create_response(self, content, response_code=200, mimetype='text/html', encoding='UTF-8', additional_params=None): 
    header_params = { 
     'Content-Type', '%s; charset=%s' %(mimetype, encoding) if encoding else mimetype, 
     'Date': strftime("%a, %d %b %Y %X GMT", gmtime()), 
     'Server': self.config['SERVER_NAME'], 
     'Connection': 'close', 
    } 
    if additional_params: 
     header_params.update(additional_params) 

    if encoding: 
     content = content.encode(encoding) 

    header = "HTTP/1.0 %s\r\n%s\r\n" % (
     self.config['STATUS_STRING'][str(response_code)], 
     ''.join('%s: %s\r\n' % kv for kv in header_params.iteritems()) 
    ) 
    return header.encode('utf8') + content 

使用:

with fp: 
     return self.create_response(fp.read(), mime_type=mimetypes.guess_type(filepath)[0], encoding=None) 
+0

但是,當我想呈現一個PNG圖像時,應該返回什麼內容?它應該是二進制的嗎? –

+0

正確,'content'應該是字節。 – Daniel

+0

我正在嘗試使用mp3文件提供的建議,但不起作用。 我只是用'data = fp.read()'通過以二進制格式打開文件來讀取mp3數據。然後返回響應爲'header + data',但它給出了以下錯誤:UnicodeDecodeError:'ascii'編解碼器無法解碼位置21中的字節0xff:序號不在範圍內(128) ' –