title: Python SimpleHTTPServer to receive files
body: <p>I am using SimpleHTTPServer's do_POST method to receive file. The script is working fine if I upload the png file using curl but whenever I use python request library to upload file, File uploads but become corrupt. Here is the SimpleHTTPServer code</p>
  
  <pre><code>#!/usr/bin/env python
  # Simple HTTP Server With Upload.
  
  import os
  import posixpath
  import BaseHTTPServer
  import urllib
  import cgi
  import shutil
  import mimetypes
  import re
  try:
      from cStringIO import StringIO
  except ImportError:
      from StringIO import StringIO
  
  class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):    
      # Simple HTTP request handler with POST commands.
  
      def do_POST(self):
          """Serve a POST request."""
          r, info = self.deal_post_data()
          print r, info, "by: ", self.client_address
          f = StringIO()
  
          if r:
              f.write("&lt;strong&gt;Success:&lt;/strong&gt;")
          else:
              f.write("&lt;strong&gt;Failed:&lt;/strong&gt;")
  
          length = f.tell()
          f.seek(0)
          self.send_response(200)
          self.send_header("Content-type", "text/html")
          self.send_header("Content-Length", str(length))
          self.end_headers()
          if f:
              self.copyfile(f, self.wfile)
              f.close()
  
      def deal_post_data(self):
          print self.headers
          boundary = self.headers.plisttext.split("=")[1]
          print 'Boundary %s' %boundary
          remainbytes = int(self.headers['content-length'])
          print "Remain Bytes %s" %remainbytes
          line = self.rfile.readline()
          remainbytes -= len(line)
          if not boundary in line:
              return (False, "Content NOT begin with boundary")
          line = self.rfile.readline()
          remainbytes -= len(line)
          fn = re.findall(r'Content-Disposition.*name="file"; filename="(.*)"', line)
          if not fn:
              return (False, "Can't find out file name...")
          path = self.translate_path(self.path)
          fn = os.path.join(path, fn[0])
          line = self.rfile.readline()
          remainbytes -= len(line)
          line = self.rfile.readline()
          remainbytes -= len(line)
          try:
              out = open(fn, 'wb')
          except IOError:
              return (False, "Can't create file to write, do you have permission to write?")
  
          preline = self.rfile.readline()
          remainbytes -= len(preline)
          while remainbytes &gt; 0:
              line = self.rfile.readline()
              remainbytes -= len(line)
              if boundary in line:
                  preline = preline[0:-1]
                  if preline.endswith('\r'):
                      preline = preline[0:-1]
                  out.write(preline)
                  out.close()
                  return (True, "File '%s' upload success!" % fn)
              else:
                  out.write(preline)
                  preline = line
          return (False, "Unexpect Ends of data.")
  
  
  
      def translate_path(self, path):
          """Translate a /-separated PATH to the local filename syntax.
  
          Components that mean special things to the local file system
          (e.g. drive or directory names) are ignored.  (XXX They should
          probably be diagnosed.)
  
          """
          # abandon query parameters
          path = path.split('?',1)[0]
          path = path.split('#',1)[0]
          path = posixpath.normpath(urllib.unquote(path))
          words = path.split('/')
          words = filter(None, words)
          path = os.getcwd()
          for word in words:
              drive, word = os.path.splitdrive(word)
              head, word = os.path.split(word)
              if word in (os.curdir, os.pardir): continue
              path = os.path.join(path, word)
          return path
  
      def copyfile(self, source, outputfile):
          """Copy all data between two file objects.
  
          The SOURCE argument is a file object open for reading
          (or anything with a read() method) and the DESTINATION
          argument is a file object open for writing (or
          anything with a write() method).
  
          The only reason for overriding this would be to change
          the block size or perhaps to replace newlines by CRLF
          -- note however that this the default server uses this
          to copy binary data as well.
  
          """
          shutil.copyfileobj(source, outputfile)
  
  
  
  def test(HandlerClass = SimpleHTTPRequestHandler,
           ServerClass = BaseHTTPServer.HTTPServer):
      BaseHTTPServer.test(HandlerClass, ServerClass)
  
  if __name__ == '__main__':
      test()
  </code></pre>
  
  <p>client side code to upload a file is here</p>
  
  <pre><code>#!/usr/bin/python
  
  import requests
  
  files = {'file': open('test.png', 'rb')}
  r = requests.post('http://192.168.5.134:8000', files=files)
  print r.request.headers
  </code></pre>
  
  <p>File was uploaded successfully but become corrupted. </p>
  
  <p><a href="http://i.stack.imgur.com/NOmXc.png" rel="noreferrer">python request header</a></p>
  
  <p><a href="http://i.stack.imgur.com/Ct7ps.png" rel="noreferrer">SimpleHTTPServer response</a></p>
  
  <p>Using curl [ curl -F 'file=@test.png' 192.168.5.134:8000/ -v ], file uploaded and opened successfully.</p>
  
  <p>Is there any issue in python-request code?</p>