2015-07-18 14 views
5

Sto provando a fare un esercizio dal corso Full Stack Foundations di Udacity. Ho il metodo do_POST dentro il mio sottoclasse da BaseHTTPRequestHandler, fondamentalmente voglio ottenere un valore postale di nome message presentato con un modulo multistrato, questo è il codice per il metodo:La funzione cgi.parse_multipart lancia TypeError in Python 3

def do_POST(self): 
    try: 
     if self.path.endswith("/Hello"): 
      self.send_response(200) 
      self.send_header('Content-type', 'text/html') 
      self.end_headers 
      ctype, pdict = cgi.parse_header(self.headers['content-type']) 
      if ctype == 'multipart/form-data': 
       fields = cgi.parse_multipart(self.rfile, pdict) 
       messagecontent = fields.get('message') 
      output = "" 
      output += "<html><body>" 
      output += "<h2>Ok, how about this?</h2>" 
      output += "<h1>{}</h1>".format(messagecontent) 
      output += "<form method='POST' enctype='multipart/form-data' action='/Hello'>" 
      output += "<h2>What would you like to say?</h2>" 
      output += "<input name='message' type='text'/><br/><input type='submit' value='Submit'/>" 
      output += "</form></body></html>" 
      self.wfile.write(output.encode('utf-8')) 
      print(output) 
      return 
    except: 
     self.send_error(404, "{}".format(sys.exc_info()[0])) 
     print(sys.exc_info() ) 

Il problema è che il cgi.parse_multipart(self.rfile, pdict) sta gettando un'eccezione: TypeError: can't concat bytes to str, l'implementazione è stata fornita nei video per il corso, ma stanno usando Python 2.7 e sto usando python 3, ho cercato una soluzione per tutto il pomeriggio ma non ho trovato nulla di utile, cosa sarebbe essere il modo corretto di leggere i dati passati da un modulo multipart in python 3?

risposta

9

Mi sono imbattuto qui per risolvere lo stesso problema come voi. Ho trovato una soluzione sciocca per questo. Ho appena convertito l'elemento 'boundary' nel dizionario da stringa a byte con un'opzione di codifica.

ctype, pdict = cgi.parse_header(self.headers['content-type']) 
    pdict['boundary'] = bytes(pdict['boundary'], "utf-8") 
    if ctype == 'multipart/form-data': 
      fields = cgi.parse_multipart(self.rfile, pdict) 

Nel mio caso, sembra funzionare correttamente.

+1

Questo mi dà un altro errore, 'oggetto 'byte' non ha alcun attributo 'readline' '. Come affrontare questo? –

+0

@AmitBadhekaPykihStaff puoi provare a fare quanto segue 'da io import BytesIO' e poi' cgi.parse_multipart (BytesIO (yourcontent), pdict) ' – CarlJ

0

Un'altra soluzione di hack è modificare la sorgente del modulo cgi.

All'inizio del parse_multipart (intorno alla linea 226a): modificare l'utilizzo del boundary al str(boundary)

... 
boundary = b"" 
if 'boundary' in pdict: 
    boundary = pdict['boundary'] 
if not valid_boundary(boundary): 
    raise ValueError('Invalid boundary in multipart form: %r' 
         % (boundary,)) 

nextpart = b"--" + str(boundary) 
lastpart = b"--" + str(boundary) + b"--" 
... 
Problemi correlati