<br><br><div class="gmail_quote">On Fri, Feb 5, 2010 at 8:56 PM, Tomas Doran <span dir="ltr">&lt;<a href="mailto:bobtfish@bobtfish.net" target="_blank">bobtfish@bobtfish.net</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div><br>
On 5 Feb 2010, at 20:54, Bill Moseley wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
AFAIK, there&#39;s no way to stream parse JSON (so that only part is in memory at any given time).  What would be the recommended serialization for uploaded files -- just use multipart/form-data for the uploads?<br>
</blockquote>
<br></div>
Don&#39;t? </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Why not just do a PUT request with all the data as unmangled binary?</blockquote><div><br></div><div>As in don&#39;t provide a way to upload meta data along with the file (name, date, description, author, title, reference id) like the web upload allows with multipart/form-data?  Or invent some new serialization where the meta data is embedded in the upload?  Or do a POST with the file, then flag the new upload as incomplete until a PUT is done to set associated meta data?</div>


<div><br></div><div>The API is suppose to offer much of the same functionality as the web interface.  JSON is somewhat nice because, well, customers have requested it, and also that it lends itself to more complex (not flat) data representations.  Of course, urlencoded doesn&#39;t have to be flat -- we have some YUI-based AJAX code that sends json in $c-&gt;req-&gt;params-&gt;{data}.  But I digress.</div>


<div><br></div><div>The &#39;multipart/form-data&#39; is nice because if the client is well behaved uploads are chunked to disk.  XML can also do this, too (I have an HTTP::Body subclass for XML-RPC that chunks base64 elements to disk).</div>


<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
BTW -- I don&#39;t see any code in HTTP::Body to limit body size.  Doesn&#39;t that seem like a pretty easy DoS for Catalyst apps?  I do set a request size limit in the web server, but if I need to allow 1/2GB uploads or so then could kill the machine pretty easily, no?<br>



</blockquote>
<br></div>
Well, you set it at the web server.. That stops both overlarge content-length requests, and when the body exceeds the specified content length.<br></blockquote><div><br></div><div><div>Yes, for example in Apache LimitRequestBody can be set and if you send a content-length header larger than that value the request is rejected right away.  And, IIRC, Apache will just discard any data over the what is specified in the content-length header (i.e. Catalyst won&#39;t see any data past the content length from Apache).</div>


<div><br></div></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
But yes, you have to provision temp file space for n files in flight x max file size...<br></blockquote><div><br></div><div>You are making an assumption that the request body actually makes it to a temp file. </div><div>


<br></div><div>Imagine you allow uploads of CD iso files, so say 700MB.  So, you set the webserver&#39;s limit to that.  Normally, when someone uploads HTTP::Body you expect OctetStream or form-data posts which ends up buffering to disk.</div>

<div><br></div><div>Now, if someone sets their content type to Urlencoded then HTTP::Body just gathers up that 700MB in memory.   MaxClients is 50, so do that math.</div><div><br></div><div>Granted someone would have to work very hard to get enough data at once all to the same web server, and if an attacker is that determined they could find other equally damaging attacks.  And a good load balancer can monitor memory on disk space on the web servers and stop sending requests to a server low on resources.</div>


<div><br></div><div><br></div><div>Most applications don&#39;t have this problem since uploading that large of a file is likely rare.  Well, that assumes that everyone is using something in front of Catalyst that limits upload size (like Apache&#39;s LimitRequestBody).</div>


<div><br></div><div>It&#39;s unusual to have a very large valid Urlencoded (or non-upload form-data) body in a normal request (that&#39;s a lot of radio buttons and text to type!) so, it would is not be wise for HTTP::Body to limit the size of $self-&gt;{buffer} to something sane?  I suppose it could flush to disk after getting too big, but that doesn&#39;t really help because some serializations require reading the entire thing into memory to parse.</div>

<div><br></div><div><br></div></div><br>-- <br>Bill Moseley<br><a href="mailto:moseley@hank.org" target="_blank">moseley@hank.org</a><br>