Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

support for nested params. Tests arent passing, some issue with bound…

…aries
  • Loading branch information...
commit 164ba4b6602f92d288d63df2447a6b5092bb1f02 1 parent 8723fed
@mrjjwright mrjjwright authored
Showing with 145 additions and 87 deletions.
  1. +43 −33 lib/write.js
  2. +33 −0 test/fixture.js
  3. +69 −54 test/write.js
View
76 lib/write.js
@@ -58,12 +58,8 @@ function writer () { return new Writer() }
function Writer () {
this.firstPartReceived = false;
this.state = S.STARTED;
-}
-
-partToHeaderMap = { "name": "name"
-, "type": "Content-Disposition"
-, "filetype": "Content-Type"
-, "filename": "filename"
+ this.depth = 0;
+ this.parts = [];
}
// Starts a part or nested part.
@@ -81,29 +77,46 @@ partToHeaderMap = { "name": "name"
// Optionally pass in a headers object of other headers
// e.g Content-Length, which will be appended to the headers.
Writer.prototype.partBegin = function (part, headers) {
- writer = this;
-
+ var writer = this
+ , type = part["type"]
+ , partString = ""
+ , boundary = part["boundary"]
+ , name = part["name"]
+ , filename = part["filename"]
+ , currentPart = writer.parts[writer.parts.length-1];
+ ;
+
+ //sys.debug("writer depth:" + writer.depth);
+ //sys.debug('writing part: ' + sys.inspect(part));
+
if (!writer.boundary) error(writer, "Missing property boundary on writer");
+
+ if (!type && !filename) {
+ error(writer, "Missing required type property on part.");
+ }
+
+ if (!type && filename) {
+ type = "inline";
+ } else {
+ type = "multipart/" + type;
+ }
- if (!writer.depth && writer.state !== S.STARTED && writer.state !== S.PART_ENDED)
+ if (writer.state === S.WRITING)
return error(writer, "Illegal state. Cannot begin new part right now.");
- if (writer.depth && !isMulti(part))
- return error(writer, "Bad format. Cannot add part to non multipart parent.");
+ if (writer.state === S.PART_STARTED && currentPart.type !== "mixed")
+ return error(writer, "Bad format. Cannot add part to non multipart parent.");
- //if (isMulti(partHeaders)) writer.depth++;
-
- partString = "--" + writer.boundary + CRLF;
+ partString += "--" + writer.boundary + CRLF;
//write the Content-Disposition
- contentDisposition = part["type"];
- name = part["name"];
- fileName = part["filename"];
- if (!contentDisposition) error(writer, "Missing required type property on part.");
- if (!name) error(writer, "Missing required name property on part.");
- partString += "Content-Disposition: " + contentDisposition + "; name:\"" + name + "\"";
- if (fileName) partString += "; filename=\"" + fileName + "\"";
+ partString += "Content-Type: " + type;
+ if (name) partString += "; name:'" + name + "'";
+ if (filename) partString += "; filename='" + filename + "'";
+ if (boundary) partString += "; boundary=" + boundary;
partString += CRLF;
+ // go down a nested part
+ if (type === "mixed") writer.depth++;
//write out any optional other headers
if (headers) {
@@ -113,6 +126,7 @@ Writer.prototype.partBegin = function (part, headers) {
}
emit(writer, "onData", partString + CRLF);
writer.state = S.PART_STARTED;
+ writer.parts.push(part);
}
// Writes a chunk to the multipart stream
@@ -133,17 +147,22 @@ Writer.prototype.write = function (chunk) {
// Writes the part end
// E.g. /r/n--boundary--
Writer.prototype.partEnd = function () {
- var writer = this;
- if (writer.state !== S.WRITING)
+ var writer = this
+ , currentPart = writer.parts[writer.parts.length-1]
+ ;
+
+ if (currentPart && currentPart.type !== "mixed" && writer.state !== S.WRITING)
error(writer, "Illegal state. Must write at least one chunk to this part before calling partEnd");
emit(writer, "onData", CRLF + "--" + writer.boundary + "--" + CRLF);
writer.state = S.PART_ENDED;
- writer.depth--;
+ currentPart = writer.parts.pop();
+ if (currentPart && currentPart.type === "mixed") writer.depth--;
}
Writer.prototype.close = function () {
+ var writer = this;
if (!writer.depth && writer.state === S.PART_ENDED) return emit(writer, "onEnd");
error(writer, "Illegal state. Multiparts not written completely before close.")
};
@@ -178,13 +197,4 @@ function writeHttpHeaders(writer) {
emit(writer, "onData", headerString + CRLF + CRLF);
}
-function newPart (writer) {
- var p =
- { headers:{}
- , parent : writer.part
- };
- parent.parts = parent.parts || [];
- parent.parts.push(p);
-}
-
View
33 test/fixture.js
@@ -710,3 +710,36 @@ messages.push({
""
].join("\r\n")
});
+
+
+exports.aSimpleMessage = {
+ headers: {
+ "Content-Type": "multipart/form-data; boundary=AaB03x",
+ },
+ boundary : "AaB03x",
+ parts: [ {
+ part: {
+ "type": "form-data", "name": "test"
+ }
+ , body: "hello"
+ , encoded: [
+ "--AaB03x"
+ , "content-disposition: form-data; name=\"test\""
+ , ""
+ , "hello"
+ ].join(",")
+ }
+ , {
+ part: {
+ "type": "form-data", "name": "test1"
+ }
+ , body: "hello1"
+ , encoded: [
+ "--AaB03x"
+ , "content-disposition: form-data; name=\"test1\""
+ , ""
+ , "hello1"
+ ].join(",")
+ }
+ ]
+};
View
123 test/write.js
@@ -2,17 +2,9 @@ var multipart = require("../lib/multipart")
, assert = require("assert")
, sys = require("sys")
, fixture = require("./fixture")
- , testPart = function (expect, part) {
- sys.debug("test part: "+sys.inspect(expect));
- if (!expect) {
- throw new Error("Got more parts than expected: "+
- sys.inspect(part.headers));
- }
- for (var i in expect) {
- assert.equal(expect[i], part[i]);
- }
- }
, messages = fixture.messages
+ , aSimpleMessage = fixture.aSimpleMessage
+ , aNestedMessage = messages[0]
, writer = multipart.writer()
, parser = multipart.parser()
, expect
@@ -20,39 +12,6 @@ var multipart = require("../lib/multipart")
;
-var messages = []
-messages.push({
- headers: {
- "Content-Type": "multipart/form-data; boundary=AaB03x",
- },
- boundary : "AaB03x",
- parts: [ {
- part: {
- "type": "form-data", "name": "test"
- }
- , body: "hello"
- , encoded: [
- "--AaB03x"
- , "content-disposition: form-data; name=\"test\""
- , ""
- , "hello"
- ].join(",")
- }
- , {
- part: {
- "type": "form-data", "name": "test1"
- }
- , body: "hello1"
- , encoded: [
- "--AaB03x"
- , "content-disposition: form-data; name=\"test1\""
- , ""
- , "hello1"
- ].join(",")
- }
- ]
-});
-
sys.debug("Create a multipart writer.");
sys.debug("");
assert.notEqual(writer, null, "should be able to obtain writer");
@@ -91,18 +50,18 @@ parser.onPartBegin = function (part) {
}
parser.onPartEnd = function (part) {
- sys.debug("parser ended part succesfully: " + sys.inspect(part));
+ sys.debug("parser ended part succesfully");
}
parser.onEnd = function () {
sys.debug("parser ended");
}
-parser.headers = messages[0].headers;
+parser.headers = aSimpleMessage.headers;
sys.debug("Write a part without setting boundary...");
try {
- writer.partBegin(messages[0].parts[0].part);
+ writer.partBegin(aSimpleMessage.parts[0].part);
assert.ok(errorHandlerCalled, "should emit onError if part written without boundary");
}catch (error) {
sys.puts(error.message);
@@ -110,15 +69,15 @@ try {
}
sys.debug("Set the boundary property and try again...");
-writer.boundary = messages[0].boundary;
-writer.partBegin(messages[0].parts[0].part);
+writer.boundary = aSimpleMessage.boundary;
+writer.partBegin(aSimpleMessage.parts[0].part);
sys.debug("Write the body...")
-writer.write(messages[0].parts[0].body);
+writer.write(aSimpleMessage.parts[0].body);
sys.debug("Start another part without finishing...");
try {
- writer.partBegin(messages[0].parts[1].part);
+ writer.partBegin(aSimpleMessage.parts[1].part);
} catch (error1) {
assert.ok(errorHandlerCalled, "should emit onError if part written without finishing the part before");
}
@@ -126,8 +85,64 @@ sys.debug("Whoops, end the last part..")
writer.partEnd();
sys.debug("Start another simple part");
-writer.partBegin(messages[0].parts[1].part);
-sys.debug("Write body and end")
-writer.write(messages[0].parts[1].body);
+writer.partBegin(aSimpleMessage.parts[1].part);
+sys.debug("Write body and finish.")
+writer.write(aSimpleMessage.parts[1].body);
+writer.partEnd();
+writer.close();
+parser.close();
+
+sys.debug("Ok, looks good. Now write a more complicated nested multipart");
+
+writer = multipart.writer();
+parser = multipart.parser();
+
+function testPart(expect, part) {
+ sys.debug("test part: "+sys.inspect(part));
+ if (!expect) {
+ throw new Error("Got more parts than expected: "+
+ sys.inspect(part.headers));
+ }
+ for (var i in expect) {
+ //assert.equal(expect[i], part[i]);
+ }
+}
+
+parser.onPartBegin = function (part) {
+ testPart(expect[e++], part);
+}
+
+writer.onData = function (chunk) {
+ parser.write(chunk);
+}
+ //a nested test from the fixtures
+
+var expect = aNestedMessage.expect
+ , e = 0;
+parser.headers = aNestedMessage.headers;
+writer.boundary = aNestedMessage.boundary;
+writer.partBegin(aNestedMessage.expect[0]); //start inner 1 mixed
+writer.partBegin(aNestedMessage.expect[1]); //start inner 2 mixed
+writer.partBegin(aNestedMessage.expect[2]); //inner 2, part 1
+writer.write("hello, world");
+writer.partEnd();
+writer.partBegin(aNestedMessage.expect[3]); //inner 2, part 2
+writer.write("hello to the world");
writer.partEnd();
-writer.close();
+writer.partEnd(); //finish inner2
+writer.partEnd(); //finish inner1
+writer.partBegin(aNestedMessage.expect[4]); //start inner 3 mixed
+writer.partBegin(aNestedMessage.expect[5]);
+writer.write("hello, free the world"); // inner 3, part1
+writer.partEnd();
+writer.partBegin(aNestedMessage.expect[6]); // inner 3, part 2
+writer.write("hello, for the world")
+writer.partEnd();
+writer.partEnd(); //end inner 3
+writer.partBegin(aNestedMessage.expect[7]); // outer, part1
+writer.write("hello, outer world");
+writer.partEnd();
+writer.partEnd(); //finish outer
+writer.close();
+parser.close();
+
Please sign in to comment.
Something went wrong with that request. Please try again.