2016-04-06 3 views
1

Ich schreibe einen einfachen Webserver in Python und war dabei erfolgreich. Ich bin in der Lage, HTML-Seiten in Javascript-Dateien zu rendern, aber keine Bilder zu rendern. Einige der entsprechenden CodePNG-Bild als Antwort in benutzerdefinierten Python-Webserver

,

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

ich eine Buchse an den Client, und die Rückkehr der Reaktion unter Verwendung dieses,

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

ich die ganze Antwort kodieren, die eine Zeichenfolge , in utf8. Dies funktioniert für HTML-Seiten und js-Dateien und CSS-Dateien, aber nicht für Bilder. (Png, Gif usw.). Ich habe versucht, die Header und Codierung der Antwort von Bildern in base64 binary etc, aber ich bin nicht in der Lage, es zu erreichen.

  • Irgendwelche Vorschläge, wie man es macht?
  • Ist das sogar möglich, weil ich jetzt denke, es ist nicht möglich, Bilder mit dieser Methode zu rendern, da die Header in utf8 wären, während der Inhalt der Bilder in anderer Kodierung sein würde. Sie können also nicht verkettet werden. Korrigiere mich, wenn ich falsch liege.
+0

Versuchen Sie nicht, einen http-Server selbst zu schreiben. Verwenden Sie einen Rahmen wie Flasche oder Flasche. – Daniel

+0

Offensichtlich werden die vorgefertigten Server viel besser sein, aber egal, es ist eine gute Lernerfahrung, um selbstständig zu schreiben, was hinter den Kulissen passiert – Keatinge

+0

@PinkeshBadjatiya: Ich bin neugierig. Warum übergibst du 'selbst' als Argument für' _handleGET'? Instanzmethoden sind bereits "self", also sollte es genügen, stattdessen 'self._handleGET (data)' zu verwenden. –

Antwort

0

Der Header von http ist nicht codiert und sollte reines ASCII sein. Der Inhaltsteil besteht aus beliebigen binären Daten. Für Text kann die Codierung in Content-Type angegeben werden. Daher createResponse hat seperat Text und binäre Daten zu handhaben, vielleicht mit expliziten Kodierung Parameter:

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 

mit mit:

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

aber, was sollte der Inhalt zurückgegeben werden, wenn ich ein PNG-Bild rendern möchte? sollte es binär sein? –

+0

richtig, 'content' sollte Bytes sein. – Daniel

+0

Ich versuche, was Sie mit einer MP3-Datei vorgeschlagen, aber es funktioniert nicht. Ich lese gerade die MP3-Daten mit 'data = fp.read()' durch Öffnen der Datei im Binärformat. Und dann die Antwort zurückgibt als 'Header + Daten', aber es gibt den folgenden Fehler 'UnicodeDecodeError:' Ascii 'Codec kann Byte 0xff in Position 21 nicht decodieren: Ordinal nicht im Bereich (128) ' –

Verwandte Themen