file binary data (POST)

243 views
Skip to first unread message

cj

unread,
Apr 24, 2008, 6:01:02 PM4/24/08
to web2py Web Framework
Hey all,

If I have someone that POSTs to my server and the main body of that Is
binary data of a file can web2py handle that ?

Many thanks,

CJ

Massimo Di Pierro

unread,
Apr 24, 2008, 6:12:18 PM4/24/08
to web...@googlegroups.com
Are you talking about the content of a file or a regular text field?

In the first case there is no problem. In the second case it is
complicated because the data has to be encoded somehow. web2py assumes
enctype="multipart/form-data". This is transparent to web2py but there
are many parts that may fail, from form parsing to database back-end.
I would not recommend doing it unless mime/json encode the binary data
before sending it.

Massimo

cj

unread,
Apr 24, 2008, 6:22:13 PM4/24/08
to web2py Web Framework
Hi Massimo,

I'm talking about the binary data of a file(contents of a file) being
sent In the body of a POST, how can web2py handle that?

Many thanks,

CJ

Massimo Di Pierro

unread,
Apr 24, 2008, 6:25:43 PM4/24/08
to web...@googlegroups.com
The file is saved into the upload folder and its (new) name goes in
the DB. web2py does not of what is in the file, it just streams it in
and writes it in the file.

Massimo

cj

unread,
Apr 24, 2008, 6:47:47 PM4/24/08
to web2py Web Framework
I tried doing that using a normal multi-form and It works fine. But
when I try sending It from my desktop application where It POSTs the
files binary data In the body It doesn't work but I get no
errors......

mstho...@gmail.com

unread,
Apr 24, 2008, 8:31:47 PM4/24/08
to web2py Web Framework
I'm working with CJ on this. Basically what we have is a POST
constructed like this:

POST http://example.com/upload HTTP/1.1
Content-Length: 4202496
Host: example.com
Content-Type: video/mpeg2

<binary data>

How do we access the file object for the post, in cherrypy you simply
read cherrypy.request.rfile, is there something similar in web2py?

mstho...@gmail.com

unread,
Apr 24, 2008, 8:44:51 PM4/24/08
to web2py Web Framework
Looking through the source, the original post body seems to be in
request.body.

So this should work:

from fileutils import copystream
request.body.seek(0)

copystream(request.body, record.file, int(request.env.content_length))

On Apr 24, 7:31 pm, "msthorn...@gmail.com" <msthorn...@gmail.com>
wrote:

Massimo Di Pierro

unread,
Apr 24, 2008, 11:39:05 PM4/24/08
to web...@googlegroups.com
Yes it is in request.body but you cannot write into record.file. You
should open a file into uploads, copystream into the file, store the
filename in the database. for example

> from fileutils import copystream
> request.body.seek(0)

random_name=str(time.time())+str(randint(10000,99999))
filename=os.path.join(request.folder,'uploads',random_name)
copystream(request.body, open(filename,'wb'), int
(request.env.content_length))
db.yourtable.insert(file=filename,.....other fields....)
>

But there is a better way... in a subsequent email...

Massimo Di Pierro

unread,
Apr 24, 2008, 11:47:40 PM4/24/08
to web...@googlegroups.com
Here is the suggested way following http://www.faqs.org/rfcs/rfc1867.html

Build the request as follows:
=========================
POST /path/to/script.php HTTP/1.0
Content-type: multipart/form-data, boundary=AaB03x
Content-Length: $requestlen

--AaB03x
content-disposition: form-data; name="file"; filename="$filename"
Content-Type: $mimetype
Content-Transfer-Encoding: binary

$binarydata
--AaB03x--
==========================
where $filename is irrelevant, $binarydata is the content of the file you are sending, $requestlen is the number of bytes of everything after the \n\n until the end.

Then process it with 

db.define_table('mytable',SQLField('file','upload'))
form=SQFORM(db.mytable)
form.accepts(request.vars,formname=None) ### will do everything for you.

Massimo

mstho...@gmail.com

unread,
Apr 24, 2008, 11:51:53 PM4/24/08
to web2py Web Framework
I disagree that this is a better way. Sure it is the correct way for
form uploads but the data isn't coming from a form. This is for a REST
API. It is more RESTful to just accept the file data in the POST body
since in REST, POST is just the opposite of a GET. When you GET a file
you don't get it in a multipart encode.

On Apr 24, 10:47 pm, Massimo Di Pierro <mdipie...@cs.depaul.edu>
wrote:

Massimo Di Pierro

unread,
Apr 25, 2008, 12:02:35 AM4/25/08
to web...@googlegroups.com
It is better from the point of saving web2py coding. I agree it may
not be the best solution in your case.
You can also mimic this. Do the post as you say then do

class Field:
def __init__(self,file): self.file=file

db.define_table('mytable',SQLField('file','upload'))

request.vars.file=Field(request.body)


form=SQFORM(db.mytable)
form.accepts(request.vars,formname=None) ### will do everything for you

Massimo Di Pierro

unread,
Apr 25, 2008, 12:24:38 AM4/25/08
to web...@googlegroups.com
One more caveat.... If you use SQLFROM every uploaded file will go in
'uploads'. make sure you use a filesystem that does not have
limitations on the number of files per folder. NTFS does not have
limitations. Linux file systems I do not know.
Reply all
Reply to author
Forward
0 new messages