30 March 2016

code

  1. http client to post using multipart/form-data (python recipe)

    1. original

       import httplib, mimetypes
      
       def post_multipart(host, selector, fields, files):
           """
           Post fields and files to an http host as multipart/form-data.
           fields is a sequence of (name, value) elements for regular form fields.
           files is a sequence of (name, filename, value) elements for data to be uploaded as files
           Return the server's response page.
           """
           content_type, body = encode_multipart_formdata(fields, files)
           h = httplib.HTTP(host)
           h.putrequest('POST', selector)
           h.putheader('content-type', content_type)
           h.putheader('content-length', str(len(body)))
           h.endheaders()
           h.send(body)
           errcode, errmsg, headers = h.getreply()
           return h.file.read()
      
       def encode_multipart_formdata(fields, files):
           """
           fields is a sequence of (name, value) elements for regular form fields.
           files is a sequence of (name, filename, value) elements for data to be uploaded as files
           Return (content_type, body) ready for httplib.HTTP instance
           """
           BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
           CRLF = '\r\n'
           L = []
           for (key, value) in fields:
               L.append('--' + BOUNDARY)
               L.append('Content-Disposition: form-data; name="%s"' % key)
               L.append('')
               L.append(value)
           for (key, filename, value) in files:
               L.append('--' + BOUNDARY)
               L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
               L.append('Content-Type: %s' % get_content_type(filename))
               L.append('')
               L.append(value)
           L.append('--' + BOUNDARY + '--')
           L.append('')
           body = CRLF.join(L)
           content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
           return content_type, body
      
       def get_content_type(filename):
           return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
      
    2. use HTTPConnection

       def post_multipart(host, selector, fields, files):
           content_type, body = encode_multipart_formdata(fields, files)
           h = httplib.HTTPConnection(host)
           headers = {
               'User-Agent': 'INSERT USERAGENTNAME',
               'Content-Type': content_type
               }
           h.request('POST', selector, body, headers)
           res = h.getresponse()
           return res.status, res.reason, res.read()
      
    3. with cookie support

       import httplib, mimetypes, mimetools, urllib2, cookielib
      
       cj = cookielib.CookieJar()
       opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
       urllib2.install_opener(opener)
      
       def post_multipart(host, selector, fields, files):
           """
           Post fields and files to an http host as multipart/form-data.
           fields is a sequence of (name, value) elements for regular form fields.
           files is a sequence of (name, filename, value) elements for data to be uploaded as files
           Return the server's response page.
           """
           content_type, body = encode_multipart_formdata(fields, files)
           headers = {'Content-Type': content_type,
                      'Content-Length': str(len(body))}
           r = urllib2.Request("http://%s%s" % (host, selector), body, headers)
           return urllib2.urlopen(r).read()
      
       def encode_multipart_formdata(fields, files):
           """
           fields is a sequence of (name, value) elements for regular form fields.
           files is a sequence of (name, filename, value) elements for data to be uploaded as files
           Return (content_type, body) ready for httplib.HTTP instance
           """
           BOUNDARY = mimetools.choose_boundary()
           CRLF = '\r\n'
           L = []
           for (key, value) in fields:
               L.append('--' + BOUNDARY)
               L.append('Content-Disposition: form-data; name="%s"' % key)
               L.append('')
               L.append(value)
           for (key, filename, value) in files:
               L.append('--' + BOUNDARY)
               L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
               L.append('Content-Type: %s' % get_content_type(filename))
               L.append('')
               L.append(value)
           L.append('--' + BOUNDARY + '--')
           L.append('')
           body = CRLF.join(L)
           content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
           return content_type, body
      
       def get_content_type(filename):
           return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
      
    4. using urllib2 hierarchy

       import MultipartPostHandler, urllib2, cookielib
      
       cookies = cookielib.CookieJar()
       opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
                                       MultipartPostHandler.MultipartPostHandler)
       params = { "username" : "bob", "password" : "riviera",
                  "file" : open("filename", "rb") }
       opener.open("http://wwww.bobsite.com/upload/", params)
      
  2. poster

    1. test_client.py

       # test_client.py
       from poster.encode import multipart_encode
       from poster.streaminghttp import register_openers
       import urllib2
      
       # Register the streaming http handlers with urllib2
       register_openers()
      
       # Start the multipart/form-data encoding of the file "DSC0001.jpg"
       # "image1" is the name of the parameter, which is normally set
       # via the "name" parameter of the HTML <input> tag.
      
       # headers contains the necessary Content-Type and Content-Length
       # datagen is a generator object that yields the encoded parameters
       datagen, headers = multipart_encode({"image1": open("DSC0001.jpg", "rb")})
      
       # Create the Request object
       request = urllib2.Request("http://localhost:5000/upload_image", datagen, headers)
       # Actually do the request, and get the response
       print urllib2.urlopen(request).read()
      
    2. test_server.py

       # test_server.py
       import webob
       from paste import httpserver
      
       def app(environ, start_response):
           request = webob.Request(environ)
           start_response("200 OK", [("Content-Type", "text/plain")])
      
           for name,value in request.POST.items():
               yield "%s: %s\n" % (name, value)
      
       httpserver.serve(app, port=5000)
      
    3. combine poster with other urllib2 handlers, e.g. for sending cookies

       opener = poster.streaminghttp.register_openers()
       opener.add_handler(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
      
       params = {'file': open("test.txt", "rb"), 'name': 'upload test'}
       datagen, headers = poster.encode.multipart_encode(params)
       request = urllib2.Request(upload_url, datagen, headers)
       result = urllib2.urlopen(request)
      


blog comments powered by Disqus