I wonder what's the best way to handle the case when a user tries to upload a very large file. Basically we need to stop execution before it gets to the parse-rfc2388-form-data and report the problem to the user.
I can think of placing some function call inside request's constructor (defmethod initialize-instance :after ((request request) &rest init-args) Something like: (let* ((check (find-symbol "CHECK-FILE-SIZE" :your-package)) (header-value (find-symbol "HEADER-VALUE" :drakma)) (length (parse-integer (funcall header-value :content-length headers-in)))) (funcall check length))
Inside function check-file-size you would raise an error if the file is too big. The problem is that this error gets handled by the lisp debugger and I can't propagate it to the user. Another thing, it's a dirty hack, what's the better way of doing this?
Thank you, Andrew
On Sun, Sep 14, 2008 at 00:55, Andrei Stebakov lispercat@gmail.com wrote:
I wonder what's the best way to handle the case when a user tries to upload a very large file. Basically we need to stop execution before it gets to the parse-rfc2388-form-data and report the problem to the user. [...] Another thing, it's a dirty hack, what's the better way of doing this?
I would fix the problem in RFC2388:READ-UNTIL-NEXT-BOUNDARY. This function should read the data directly to the stream provided, and it should have a special variable (in the RFC2388 package) that can be set to limit the maximum number of bytes read.
-Hans
The problem is that RFC2388:READ-UNTIL-NEXT-BOUNDARY doesn't know about the content-length as hunchentoot package doesn't pass this parameter to the rfc2388:parse-mime function. So again it should be changed in two different packages. When I implemented file upload progress bar, I had to modify the hunchentoot and rfc2388 since only hunchentoot knows about content-length and only rfc2388 knows how many bytes was read from the stream. Using these two parameters we can calculate the percentage of the data that was uploaded to the server. I could retrieve the content-length to the client via ajax and do something in javascript to disrupt the upload, but I doesn't look like a good solution to me. So, my question is where and how in hunchentoot I can raise an error so that it would get propagated to the handler of the file upload request so that I can show it to the user. In the request constructor (defmethod initialize-instance ...) the body is wrapped into handler-case so any error which occurs in it should be trapped by (error (cond) ...), right? For some reason the error that I raise when the content-length is greater than some number, this error gets trapped by the lisp debugger, not by (error (cond) ...). Anyway, time for me to go back study lisp manuals! :)
Andrew
On Sun, Sep 14, 2008 at 3:14 AM, Hans Hübner hans@huebner.org wrote:
On Sun, Sep 14, 2008 at 00:55, Andrei Stebakov lispercat@gmail.com wrote:
I wonder what's the best way to handle the case when a user tries to
upload
a very large file. Basically we need to stop execution before it gets to the parse-rfc2388-form-data and report the problem to the user. [...] Another thing, it's a dirty hack, what's the better way of doing this?
I would fix the problem in RFC2388:READ-UNTIL-NEXT-BOUNDARY. This function should read the data directly to the stream provided, and it should have a special variable (in the RFC2388 package) that can be set to limit the maximum number of bytes read.
-Hans _______________________________________________ tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
After some internal discussion, I would recommend against hacking RFC2388 - It will most likely be replaced by something which is more extensible in the future.
For the time being, your easiest solution might be to use the position counter of the flexi-stream that the upload is being read from. At the beginning of the request, you would make this stream accessible to your status handler (for example by putting it into the session), and the status handler would use the start and current position to measure request progress.
Hope this still helps. Let us know if it works or if you have found another, better solution.
-Hans
On Sun, Sep 14, 2008 at 15:21, Andrei Stebakov lispercat@gmail.com wrote:
The problem is that RFC2388:READ-UNTIL-NEXT-BOUNDARY doesn't know about the content-length as hunchentoot package doesn't pass this parameter to the rfc2388:parse-mime function. So again it should be changed in two different packages. When I implemented file upload progress bar, I had to modify the hunchentoot and rfc2388 since only hunchentoot knows about content-length and only rfc2388 knows how many bytes was read from the stream. Using these two parameters we can calculate the percentage of the data that was uploaded to the server. I could retrieve the content-length to the client via ajax and do something in javascript to disrupt the upload, but I doesn't look like a good solution to me. So, my question is where and how in hunchentoot I can raise an error so that it would get propagated to the handler of the file upload request so that I can show it to the user. In the request constructor (defmethod initialize-instance ...) the body is wrapped into handler-case so any error which occurs in it should be trapped by (error (cond) ...), right? For some reason the error that I raise when the content-length is greater than some number, this error gets trapped by the lisp debugger, not by (error (cond) ...). Anyway, time for me to go back study lisp manuals! :)
Andrew
On Sun, Sep 14, 2008 at 3:14 AM, Hans Hübner hans@huebner.org wrote:
On Sun, Sep 14, 2008 at 00:55, Andrei Stebakov lispercat@gmail.com wrote:
I wonder what's the best way to handle the case when a user tries to upload a very large file. Basically we need to stop execution before it gets to the parse-rfc2388-form-data and report the problem to the user. [...] Another thing, it's a dirty hack, what's the better way of doing this?
I would fix the problem in RFC2388:READ-UNTIL-NEXT-BOUNDARY. This function should read the data directly to the stream provided, and it should have a special variable (in the RFC2388 package) that can be set to limit the maximum number of bytes read.
-Hans _______________________________________________ tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
Still, I have to put some hack inside the request constructor as it knows the content-length of the file being uploaded. Also the flexi-stream could be obtained from the constructor of request via (content-stream *request*). So, yes, this task could be minimized to hacking only one place in initialize-instance of request class. I'll try it.
Thank you, Andrew
On Fri, Sep 19, 2008 at 4:53 AM, Hans Hübner hans@huebner.org wrote:
After some internal discussion, I would recommend against hacking RFC2388 - It will most likely be replaced by something which is more extensible in the future.
For the time being, your easiest solution might be to use the position counter of the flexi-stream that the upload is being read from. At the beginning of the request, you would make this stream accessible to your status handler (for example by putting it into the session), and the status handler would use the start and current position to measure request progress.
Hope this still helps. Let us know if it works or if you have found another, better solution.
-Hans
On Sun, Sep 14, 2008 at 15:21, Andrei Stebakov lispercat@gmail.com wrote:
The problem is that RFC2388:READ-UNTIL-NEXT-BOUNDARY doesn't know about
the
content-length as hunchentoot package doesn't pass this parameter to the rfc2388:parse-mime function. So again it should be changed in two
different
packages. When I implemented file upload progress bar, I had to modify the
hunchentoot
and rfc2388 since only hunchentoot knows about content-length and only rfc2388 knows how many bytes was read from the stream. Using these two parameters we can calculate the percentage of the data that was uploaded
to
the server. I could retrieve the content-length to the client via ajax and do
something
in javascript to disrupt the upload, but I doesn't look like a good
solution
to me. So, my question is where and how in hunchentoot I can raise an error so
that
it would get propagated to the handler of the file upload request so that
I
can show it to the user. In the request constructor (defmethod initialize-instance ...) the body is wrapped into handler-case so any
error
which occurs in it should be trapped by (error (cond) ...), right? For
some
reason the error that I raise when the content-length is greater than
some
number, this error gets trapped by the lisp debugger, not by (error
(cond)
...). Anyway, time for me to go back study lisp manuals! :)
Andrew
On Sun, Sep 14, 2008 at 3:14 AM, Hans Hübner hans@huebner.org wrote:
On Sun, Sep 14, 2008 at 00:55, Andrei Stebakov lispercat@gmail.com wrote:
I wonder what's the best way to handle the case when a user tries to upload a very large file. Basically we need to stop execution before it gets to the parse-rfc2388-form-data and report the problem to the user. [...] Another thing, it's a dirty hack, what's the better way of doing this?
I would fix the problem in RFC2388:READ-UNTIL-NEXT-BOUNDARY. This function should read the data directly to the stream provided, and it should have a special variable (in the RFC2388 package) that can be set to limit the maximum number of bytes read.
-Hans _______________________________________________ tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel