2016-04-06 8 views
1

私はPythonで単純なWebサーバーを作成しており、これを成功させました。私はjavascriptファイルでhtmlページをレンダリングできますが、イメージをレンダリングできません。カスタムPython Webサーバーでの応答のpngイメージ

関連するコードの一部、

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:私は好奇心が強い。なぜあなたは '_handleGET'の引数として' self'を渡していますか?インスタンスメソッドはすでに 'self'を渡されているので、代わりに' self._handleGET(data) 'を実行すれば十分です。 –

答えて

0

httpのヘッダーはエンコードされておらず、純粋なASCIIである必要があります。コンテンツ部分は任意のバイナリデータです。テキストの場合、エンコーディングはContent-Typeで指定することができます。 したがってcreateResponse多分明示的なエンコーディングパラメータを、個別にテキストとバイナリデータを処理しなければならない:

使用
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データを読み込んでいます。そして、「ヘッダ+データ」として応答を返しますが、UnicodeDecodeError: 'ascii'コーデックは位置21のバイト0xffをデコードできません:範囲内の序数(128) –