CherryPy 3.6 - 阅读Multipart Post http请求

时间:2015-02-22 22:40:32

标签: http post request cherrypy multipart

我编写了一个java客户端,它通过多部分post http请求向运行cherrypy 3.6的服务器发送一串元信息和一个字节数组。

我需要提取这两个值,我在服务器端的python3中对此进行了编码,以了解如何操作结果,因为我无法在互联网上找到任何解释如何阅读此html部分的相关文档

def controller(self, meta, data):

        print("meta", meta)
        print("data", type(data))

输出:

my meta information
<class 'cherrypy._cpreqbody.Part'>

注意: 数据部分包含原始二进制数据。

如何将http部分内容读入缓冲区或将其输出到磁盘文件?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

感谢您的回答。 我已经阅读过这个文档,但不幸的是read-into_file和make_file方法,读...它对我不起作用。例如,当我尝试读取从我的java客户端发送的zip文件时:

假设数据是Http post参数

<强> make_file()

fp = data.make_file()
print("fp type", type(fp)) # _io.BufferedRandom
zipFile =  fp.read()

输出:

AttributeError: 'bytes' object has no attribute 'seek'

第651行,在read_lines_to_boundary中引发EOFError(“多部分正文的非法结束。”)EOFError:多部分正文非法结束。

<强> read_into_file()

    file = data.read_into_file()
    print("file type", type(file))
    zipFile =  io.BytesIO(file.read())
    # zipFile =  file.read() # => raises same error

输出:

line 651, in read_lines_to_boundary raise EOFError("Illegal end of multipart body.")EOFError: Illegal end of multipart body.

我不明白会发生什么......

实际上“数据”不是像对象这样的文件,而是cherrypy._cpreqbody.Part。它将“文件”文件保存为_io.BufferedRandom类属性。

它的read()方法以二进制形式(字节)返回整个体内容。

所以最终直截了当的解决方案是:

class BinReceiver(object):

    def index(self, data):

        zipFile =  io.BytesIO(data.file.read())
        path = "/tmp/data.zip"
        fp = open(path)
        fp.write(zipFile, 'wb')
        fp.close()

        print("saved data into", path, "size", len(zipFile))

    index.exposed = True

这很好......

fyi:我正在运行python3.2

答案 1 :(得分:0)

似乎data是一个类似文件的对象,您可以调用.read。此外,CherryPy提供了一种方法read_into_file

在REPL中输入help(cherrypy._cpreqbody.Part),查看完整文档。

class Part(Entity)
 |  A MIME part entity, part of a multipart entity.
 |  
 |  Method resolution order:
 |      Part
 |      Entity
 |      __builtin__.object
 |  
 |  Methods defined here:
 |  
 |  __init__(self, fp, headers, boundary)
 |  
 |  default_proc(self)
 |      Called if a more-specific processor is not found for the
 |      ``Content-Type``.
 |  
 |  read_into_file(self, fp_out=None)
 |      Read the request body into fp_out (or make_file() if None).
 |      
 |      Return fp_out.
 |  
 |  read_lines_to_boundary(self, fp_out=None)
 |      Read bytes from self.fp and return or write them to a file.
 |      
 |      If the 'fp_out' argument is None (the default), all bytes read are
 |      returned in a single byte string.
 |      
 |      If the 'fp_out' argument is not None, it must be a file-like
 |      object that supports the 'write' method; all bytes read will be
 |      written to the fp, and that fp is returned.
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  from_fp(cls, fp, boundary) from __builtin__.type
 |  
 |  read_headers(cls, fp) from __builtin__.type
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  attempt_charsets = ['us-ascii', 'utf-8']
 |  
 |  boundary = None
 |  
 |  default_content_type = 'text/plain'
 |  
 |  maxrambytes = 1000
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from Entity:
 |  
 |  __iter__(self)
 |  
 |  __next__(self)
 |  
 |  fullvalue(self)
 |      Return this entity as a string, whether stored in a file or not.
 |  
 |  make_file(self)
 |      Return a file-like object into which the request body will be read.
 |      
 |      By default, this will return a TemporaryFile. Override as needed.
 |      See also :attr:`cherrypy._cpreqbody.Part.maxrambytes`.
 |  
 |  next(self)
 |  
 |  process(self)
 |      Execute the best-match processor for the given media type.
 |  
 |  read(self, size=None, fp_out=None)
 |  
 |  readline(self, size=None)
 |  
 |  readlines(self, sizehint=None)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from Entity:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
 |  
 |  type
 |      A deprecated alias for :attr:`content_type<cherrypy._cpreqbody.Entity.content_type>`.
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from Entity:
 |  
 |  charset = None
 |  
 |  content_type = None
 |  
 |  filename = None
 |  
 |  fp = None
 |  
 |  headers = None
 |  
 |  length = None
 |  
 |  name = None
 |  
 |  params = None
 |  
 |  part_class = <class 'cherrypy._cpreqbody.Part'>
 |      A MIME part entity, part of a multipart entity.
 |  
 |  parts = None
 |  
 |  processors = {'application/x-www-form-urlencoded': <function process_u...