Documentation for Multipart parser
authorFelix Geisendörfer <felix@debuggable.com>
Sat, 3 Oct 2009 14:40:06 +0000 (16:40 +0200)
committerRyan Dahl <ry@tinyclouds.org>
Sat, 3 Oct 2009 16:06:24 +0000 (18:06 +0200)
Also added multipart.parse as a convenience function

doc/api.html
doc/api.txt
doc/api.xml
doc/node.1
lib/multipart.js

index 015889e..4c51750 100644 (file)
@@ -1516,6 +1516,116 @@ After emitted no other events will be emitted on the response.</p></td>
 </p>\r
 </dd>\r
 </dl></div>\r
+<h3 id="_multipart_parsing">Multipart Parsing</h3><div style="clear:left"></div>\r
+<div class="paragraph"><p>A library to parse HTTP requests with <tt>multipart/form-data</tt> is included with\r
+Node.  To use it, <tt>require("/multipart.js")</tt>.</p></div>\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+<tt>multipart.parse(options)</tt> \r
+</dt>\r
+<dd>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+on success: Returns an object where each key holds the value of one part of\r
+                the stream. <tt>options</tt> can either be an instance of\r
+                <tt>http.ServerRequest</tt> or an object containing a <em>boundary</em> and a\r
+                <em>data</em> key.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+on error: no parameters.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</dd>\r
+</dl></div>\r
+<h4 id="_tt_multipart_stream_tt"><tt>multipart.Stream</tt></h4>\r
+<div class="paragraph"><p>Here is an example for parsing a <tt>multipart/form-data</tt> request:</p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>var multipart = require('/multipart.js');\r
+var stream = new multipart.Stream(options);\r
+var parts = {};\r
+\r
+stream.addListener('part', function (part) {\r
+  var name = part.headers['Content-Disposition'].name;\r
+  var buffer = '';\r
+\r
+  part.addListener('body', function(chunk) {\r
+    buffer = buffer + chunk;\r
+  });\r
+\r
+  part.addListener('complete', function() {\r
+    parts[name] = buffer;\r
+  });\r
+});\r
+\r
+stream.addListener('complete', function() {\r
+  // The parts object now contains all parts and data\r
+});</tt></pre>\r
+</div></div>\r
+<div class="tableblock">\r
+<table rules="all"\r
+width="100%"\r
+frame="border"\r
+cellspacing="0" cellpadding="4">\r
+<col width="7%" />\r
+<col width="15%" />\r
+<col width="76%" />\r
+<thead>\r
+<tr>\r
+<th align="left" valign="top">Event           </th>\r
+<th align="left" valign="top"> Parameters   </th>\r
+<th align="left" valign="top"> Notes</th>\r
+</tr>\r
+</thead>\r
+<tbody>\r
+<tr>\r
+<td align="left" valign="top"><p class="table"><tt>"part"</tt></p></td>\r
+<td align="left" valign="top"><p class="table"><tt>part</tt></p></td>\r
+<td align="left" valign="top"><p class="table">Emitted when a new part is found in the stream.\r
+                                  <tt>part</tt> is an instance of <tt>multipart.Part</tt>.</p></td>\r
+</tr>\r
+<tr>\r
+<td align="left" valign="top"><p class="table"><tt>"complete"</tt></p></td>\r
+<td align="left" valign="top"><p class="table"></p></td>\r
+<td align="left" valign="top"><p class="table">Emitted when the end of the stream is reached.</p></td>\r
+</tr>\r
+</tbody>\r
+</table>\r
+</div>\r
+<h4 id="_tt_multipart_part_tt"><tt>multipart.Part</tt></h4>\r
+<div class="tableblock">\r
+<table rules="all"\r
+width="100%"\r
+frame="border"\r
+cellspacing="0" cellpadding="4">\r
+<col width="7%" />\r
+<col width="15%" />\r
+<col width="76%" />\r
+<thead>\r
+<tr>\r
+<th align="left" valign="top">Event           </th>\r
+<th align="left" valign="top"> Parameters   </th>\r
+<th align="left" valign="top"> Notes</th>\r
+</tr>\r
+</thead>\r
+<tbody>\r
+<tr>\r
+<td align="left" valign="top"><p class="table"><tt>"body"</tt></p></td>\r
+<td align="left" valign="top"><p class="table"><tt>chunk</tt></p></td>\r
+<td align="left" valign="top"><p class="table">Emitted when a chunk of body is read.</p></td>\r
+</tr>\r
+<tr>\r
+<td align="left" valign="top"><p class="table"><tt>"complete"</tt></p></td>\r
+<td align="left" valign="top"><p class="table"></p></td>\r
+<td align="left" valign="top"><p class="table">Emitted when the end of the part is reached.</p></td>\r
+</tr>\r
+</tbody>\r
+</table>\r
+</div>\r
 <h3 id="_tcp">TCP</h3><div style="clear:left"></div>\r
 <div class="paragraph"><p>To use the TCP server and client one must <tt>require("/tcp.js")</tt> or\r
 <tt>include("/tcp.js")</tt>.</p></div>\r
@@ -2029,7 +2139,7 @@ init (Handle&lt;Object&gt; target)
 <div id="footer">\r
 <div id="footer-text">\r
 Version 0.1.13<br />\r
-Last updated 2009-09-30 23:15:59 CEST\r
+Last updated 2009-10-03 18:02:36 CEST\r
 </div>\r
 </div>\r
 </body>\r
index 46c806c..0983643 100644 (file)
@@ -565,8 +565,6 @@ Objects returned from +node.fs.stat()+ are of this type.
 
 +stats.isSocket()+:: ...
 
-
-
 === HTTP
 
 To use the HTTP server and client one must +require("/http.js")+ or
@@ -942,6 +940,62 @@ After emitted no other events will be emitted on the response.
 +response.client+ ::
   A reference to the +http.Client+ that this response belongs to.
 
+=== Multipart Parsing
+
+A library to parse HTTP requests with +multipart/form-data+ is included with
+Node.  To use it, +require("/multipart.js")+.
+
++multipart.parse(options)+ ::
+  - on success: Returns an object where each key holds the value of one part of
+                the stream. +options+ can either be an instance of
+                +http.ServerRequest+ or an object containing a 'boundary' and a
+                'data' key.
+  - on error: no parameters.
+
+==== +multipart.Stream+
+
+Here is an example for parsing a +multipart/form-data+ request:
+
+----------------------------------------
+var multipart = require('/multipart.js');
+var stream = new multipart.Stream(options);
+var parts = {};
+
+stream.addListener('part', function (part) {
+  var name = part.headers['Content-Disposition'].name;
+  var buffer = '';
+
+  part.addListener('body', function(chunk) {
+    buffer = buffer + chunk;
+  });
+
+  part.addListener('complete', function() {
+    parts[name] = buffer;
+  });
+});
+
+stream.addListener('complete', function() {
+  // The parts object now contains all parts and data
+});
+----------------------------------------
+
+
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event           | Parameters   | Notes
+|+"part"+        | +part+       | Emitted when a new part is found in the stream.
+                                  +part+ is an instance of +multipart.Part+.
+|+"complete"+    |              | Emitted when the end of the stream is reached.
+|=========================================================
+
+==== +multipart.Part+
+
+[cols="1,2,10",options="header"]
+|=========================================================
+|Event           | Parameters   | Notes
+|+"body"+        | +chunk+      | Emitted when a chunk of body is read.
+|+"complete"+    |              | Emitted when the end of the part is reached.
+|=========================================================
 
 
 === TCP
index 9dc8793..8a542c3 100644 (file)
@@ -1609,6 +1609,121 @@ After emitted no other events will be emitted on the response.</simpara></entry>
 </variablelist>\r
 </refsect3>\r
 </refsect2>\r
+<refsect2 id="_multipart_parsing">\r
+<title>Multipart Parsing</title>\r
+<simpara>A library to parse HTTP requests with <literal>multipart/form-data</literal> is included with\r
+Node.  To use it, <literal>require("/multipart.js")</literal>.</simpara>\r
+<variablelist>\r
+<varlistentry>\r
+<term>\r
+<literal>multipart.parse(options)</literal> \r
+</term>\r
+<listitem>\r
+<itemizedlist>\r
+<listitem>\r
+<simpara>\r
+on success: Returns an object where each key holds the value of one part of\r
+                the stream. <literal>options</literal> can either be an instance of\r
+                <literal>http.ServerRequest</literal> or an object containing a <emphasis>boundary</emphasis> and a\r
+                <emphasis>data</emphasis> key.\r
+</simpara>\r
+</listitem>\r
+<listitem>\r
+<simpara>\r
+on error: no parameters.\r
+</simpara>\r
+</listitem>\r
+</itemizedlist>\r
+</listitem>\r
+</varlistentry>\r
+</variablelist>\r
+<refsect3 id="_literal_multipart_stream_literal">\r
+<title><literal>multipart.Stream</literal></title>\r
+<simpara>Here is an example for parsing a <literal>multipart/form-data</literal> request:</simpara>\r
+<screen>var multipart = require('/multipart.js');\r
+var stream = new multipart.Stream(options);\r
+var parts = {};\r
+\r
+stream.addListener('part', function (part) {\r
+  var name = part.headers['Content-Disposition'].name;\r
+  var buffer = '';\r
+\r
+  part.addListener('body', function(chunk) {\r
+    buffer = buffer + chunk;\r
+  });\r
+\r
+  part.addListener('complete', function() {\r
+    parts[name] = buffer;\r
+  });\r
+});\r
+\r
+stream.addListener('complete', function() {\r
+  // The parts object now contains all parts and data\r
+});</screen>\r
+<informaltable\r
+frame="all"\r
+rowsep="1" colsep="1"\r
+>\r
+<tgroup cols="3">\r
+<colspec colname="col_1" colwidth="7*"/>\r
+<colspec colname="col_2" colwidth="15*"/>\r
+<colspec colname="col_3" colwidth="76*"/>\r
+<thead>\r
+<row>\r
+<entry align="left" valign="top">Event           </entry>\r
+<entry align="left" valign="top"> Parameters   </entry>\r
+<entry align="left" valign="top"> Notes</entry>\r
+</row>\r
+</thead>\r
+<tbody>\r
+<row>\r
+<entry align="left" valign="top"><simpara><literal>"part"</literal></simpara></entry>\r
+<entry align="left" valign="top"><simpara><literal>part</literal></simpara></entry>\r
+<entry align="left" valign="top"><simpara>Emitted when a new part is found in the stream.\r
+                                  <literal>part</literal> is an instance of <literal>multipart.Part</literal>.</simpara></entry>\r
+</row>\r
+<row>\r
+<entry align="left" valign="top"><simpara><literal>"complete"</literal></simpara></entry>\r
+<entry align="left" valign="top"><simpara></simpara></entry>\r
+<entry align="left" valign="top"><simpara>Emitted when the end of the stream is reached.</simpara></entry>\r
+</row>\r
+</tbody>\r
+</tgroup>\r
+</informaltable>\r
+</refsect3>\r
+<refsect3 id="_literal_multipart_part_literal">\r
+<title><literal>multipart.Part</literal></title>\r
+<informaltable\r
+frame="all"\r
+rowsep="1" colsep="1"\r
+>\r
+<tgroup cols="3">\r
+<colspec colname="col_1" colwidth="7*"/>\r
+<colspec colname="col_2" colwidth="15*"/>\r
+<colspec colname="col_3" colwidth="76*"/>\r
+<thead>\r
+<row>\r
+<entry align="left" valign="top">Event           </entry>\r
+<entry align="left" valign="top"> Parameters   </entry>\r
+<entry align="left" valign="top"> Notes</entry>\r
+</row>\r
+</thead>\r
+<tbody>\r
+<row>\r
+<entry align="left" valign="top"><simpara><literal>"body"</literal></simpara></entry>\r
+<entry align="left" valign="top"><simpara><literal>chunk</literal></simpara></entry>\r
+<entry align="left" valign="top"><simpara>Emitted when a chunk of body is read.</simpara></entry>\r
+</row>\r
+<row>\r
+<entry align="left" valign="top"><simpara><literal>"complete"</literal></simpara></entry>\r
+<entry align="left" valign="top"><simpara></simpara></entry>\r
+<entry align="left" valign="top"><simpara>Emitted when the end of the part is reached.</simpara></entry>\r
+</row>\r
+</tbody>\r
+</tgroup>\r
+</informaltable>\r
+</refsect3>\r
+</refsect2>\r
 <refsect2 id="_tcp">\r
 <title>TCP</title>\r
 <simpara>To use the TCP server and client one must <literal>require("/tcp.js")</literal> or\r
index 7d2c7a4..656982f 100644 (file)
@@ -1,11 +1,11 @@
 .\"     Title: node
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets v1.73.2 <http://docbook.sf.net/>
-.\"      Date: 09/30/2009
+.\"      Date: 10/03/2009
 .\"    Manual: 
 .\"    Source: 
 .\"
-.TH "NODE" "1" "09/30/2009" "" ""
+.TH "NODE" "1" "10/03/2009" "" ""
 .\" disable hyphenation
 .nh
 .\" disable justification (adjust text to left margin only)
@@ -1374,6 +1374,139 @@ http\.Client
 that this response belongs to\.
 .RE
 .RE
+.SS "Multipart Parsing"
+A library to parse HTTP requests with multipart/form\-data is included with Node\. To use it, require("/multipart\.js")\.
+.PP
+multipart\.parse(options)
+.RS 4
+.sp
+.RS 4
+\h'-04'\(bu\h'+03'on success: Returns an object where each key holds the value of one part of the stream\.
+options
+can either be an instance of
+http\.ServerRequest
+or an object containing a
+\fIboundary\fR
+and a
+\fIdata\fR
+key\.
+.RE
+.sp
+.RS 4
+\h'-04'\(bu\h'+03'on error: no parameters\.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+multipart.Stream
+.RS
+Here is an example for parsing a multipart/form\-data request:
+.sp
+.sp
+.RS 4
+.nf
+var multipart = require(\'/multipart\.js\');
+var stream = new multipart\.Stream(options);
+var parts = {};
+
+stream\.addListener(\'part\', function (part) {
+  var name = part\.headers[\'Content\-Disposition\']\.name;
+  var buffer = \'\';
+
+  part\.addListener(\'body\', function(chunk) {
+    buffer = buffer + chunk;
+  });
+
+  part\.addListener(\'complete\', function() {
+    parts[name] = buffer;
+  });
+});
+
+stream\.addListener(\'complete\', function() {
+  // The parts object now contains all parts and data
+});
+.fi
+.RE
+.TS
+allbox tab(:);
+ltB ltB ltB.
+T{
+Event
+T}:T{
+Parameters
+T}:T{
+Notes
+T}
+.T&
+lt lt lt
+lt lt lt.
+T{
+"part"
+.sp
+T}:T{
+part
+.sp
+T}:T{
+Emitted when a new part is found in the stream\. part is an instance of multipart\.Part\.
+.sp
+T}
+T{
+"complete"
+.sp
+T}:T{
+.sp
+T}:T{
+Emitted when the end of the stream is reached\.
+.sp
+T}
+.TE
+.sp
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+multipart.Part
+.RS
+.TS
+allbox tab(:);
+ltB ltB ltB.
+T{
+Event
+T}:T{
+Parameters
+T}:T{
+Notes
+T}
+.T&
+lt lt lt
+lt lt lt.
+T{
+"body"
+.sp
+T}:T{
+chunk
+.sp
+T}:T{
+Emitted when a chunk of body is read\.
+.sp
+T}
+T{
+"complete"
+.sp
+T}:T{
+.sp
+T}:T{
+Emitted when the end of the part is reached\.
+.sp
+T}
+.TE
+.sp
+.RE
 .SS "TCP"
 To use the TCP server and client one must require("/tcp\.js") or include("/tcp\.js")\.
 .sp
index ddcd48a..5bf8cc1 100644 (file)
@@ -1,5 +1,30 @@
+exports.parse = function(options) {
+  var stream = new exports.Stream(options);
+  var promise = new node.Promise();
+
+  var parts = {};
+  stream.addListener('part', function(part) {
+    var name = part.headers['Content-Disposition'].name;
+    var buffer = '';
+
+    part.addListener('body', function(chunk) {
+      buffer = buffer + chunk;
+    });
+
+    part.addListener('complete', function() {
+      parts[name] = buffer;
+    });
+  });
+
+  stream.addListener('complete', function() {
+    promise.emitSuccess(parts);
+  });
+
+  return promise;
+};
+
 exports.Stream = function(options) {
- node.EventEmitter.call(this);
 node.EventEmitter.call(this);
 
   this.init(options);
 };
@@ -37,6 +62,7 @@ proto.init = function(options) {
       });
   } else {
     this.boundary = options.boundary;
+    this.write(options.data || '');
   }
 };