Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
4 /**
5 * Tests Curl Utils functionality.
6 */
8 function test() {
9 initNetMonitor(CURL_UTILS_URL).then(([aTab, aDebuggee, aMonitor]) => {
10 info("Starting test... ");
12 let { NetMonitorView, gNetwork } = aMonitor.panelWin;
13 let { RequestsMenu } = NetMonitorView;
15 RequestsMenu.lazyUpdate = false;
17 waitForNetworkEvents(aMonitor, 1, 3).then(() => {
18 let requests = {
19 get: RequestsMenu.getItemAtIndex(0),
20 post: RequestsMenu.getItemAtIndex(1),
21 multipart: RequestsMenu.getItemAtIndex(2),
22 multipartForm: RequestsMenu.getItemAtIndex(3)
23 };
25 Task.spawn(function*() {
26 yield createCurlData(requests.get.attachment, gNetwork).then((aData) => {
27 test_findHeader(aData);
28 });
30 yield createCurlData(requests.post.attachment, gNetwork).then((aData) => {
31 test_isUrlEncodedRequest(aData);
32 test_writePostDataTextParams(aData);
33 });
35 yield createCurlData(requests.multipart.attachment, gNetwork).then((aData) => {
36 test_isMultipartRequest(aData);
37 test_getMultipartBoundary(aData);
38 test_removeBinaryDataFromMultipartText(aData);
39 });
41 yield createCurlData(requests.multipartForm.attachment, gNetwork).then((aData) => {
42 test_getHeadersFromMultipartText(aData);
43 });
45 if (Services.appinfo.OS != "WINNT") {
46 test_escapeStringPosix();
47 } else {
48 test_escapeStringWin();
49 }
51 teardown(aMonitor).then(finish);
52 });
53 });
55 aDebuggee.performRequests(SIMPLE_SJS);
56 });
57 }
59 function test_isUrlEncodedRequest(aData) {
60 let isUrlEncoded = CurlUtils.isUrlEncodedRequest(aData);
61 ok(isUrlEncoded, "Should return true for url encoded requests.");
62 }
64 function test_isMultipartRequest(aData) {
65 let isMultipart = CurlUtils.isMultipartRequest(aData);
66 ok(isMultipart, "Should return true for multipart/form-data requests.");
67 }
69 function test_findHeader(aData) {
70 let headers = aData.headers;
71 let hostName = CurlUtils.findHeader(headers, "Host");
72 let requestedWithLowerCased = CurlUtils.findHeader(headers, "x-requested-with");
73 let doesNotExist = CurlUtils.findHeader(headers, "X-Does-Not-Exist");
75 is(hostName, "example.com",
76 "Header with name 'Host' should be found in the request array.");
77 is(requestedWithLowerCased, "XMLHttpRequest",
78 "The search should be case insensitive.");
79 is(doesNotExist, null,
80 "Should return null when a header is not found.");
81 }
83 function test_writePostDataTextParams(aData) {
84 let params = CurlUtils.writePostDataTextParams(aData.postDataText);
85 is(params, "param1=value1¶m2=value2¶m3=value3",
86 "Should return a serialized representation of the request parameters");
87 }
89 function test_getMultipartBoundary(aData) {
90 let boundary = CurlUtils.getMultipartBoundary(aData);
91 ok(/-{3,}\w+/.test(boundary),
92 "A boundary string should be found in a multipart request.");
93 }
95 function test_removeBinaryDataFromMultipartText(aData) {
96 let generatedBoundary = CurlUtils.getMultipartBoundary(aData);
97 let text = aData.postDataText;
98 let binaryRemoved =
99 CurlUtils.removeBinaryDataFromMultipartText(text, generatedBoundary);
100 let boundary = "--" + generatedBoundary;
102 const EXPECTED_POSIX_RESULT = [
103 "$'",
104 boundary,
105 "\\r\\n\\r\\n",
106 "Content-Disposition: form-data; name=\"param1\"",
107 "\\r\\n\\r\\n",
108 "value1",
109 "\\r\\n",
110 boundary,
111 "\\r\\n\\r\\n",
112 "Content-Disposition: form-data; name=\"file\"; filename=\"filename.png\"",
113 "\\r\\n",
114 "Content-Type: image/png",
115 "\\r\\n\\r\\n",
116 generatedBoundary,
117 "--\\r\\n",
118 "'"
119 ].join("");
121 const EXPECTED_WIN_RESULT = [
122 '"' + boundary + '"^',
123 '\u000d\u000A\u000d\u000A',
124 '"Content-Disposition: form-data; name=""param1"""^',
125 '\u000d\u000A\u000d\u000A',
126 '"value1"^',
127 '\u000d\u000A',
128 '"' + boundary + '"^',
129 '\u000d\u000A\u000d\u000A',
130 '"Content-Disposition: form-data; name=""file""; filename=""filename.png"""^',
131 '\u000d\u000A',
132 '"Content-Type: image/png"^',
133 '\u000d\u000A\u000d\u000A',
134 '"' + generatedBoundary + '--"^',
135 '\u000d\u000A',
136 '""'
137 ].join("");
139 if (Services.appinfo.OS != "WINNT") {
140 is(CurlUtils.escapeStringPosix(binaryRemoved), EXPECTED_POSIX_RESULT,
141 "The mulitpart request payload should not contain binary data.");
142 } else {
143 is(CurlUtils.escapeStringWin(binaryRemoved), EXPECTED_WIN_RESULT,
144 "WinNT: The mulitpart request payload should not contain binary data.");
145 }
146 }
148 function test_getHeadersFromMultipartText(aData) {
149 let headers = CurlUtils.getHeadersFromMultipartText(aData.postDataText);
151 ok(Array.isArray(headers),
152 "Should return an array.");
153 ok(headers.length > 0,
154 "There should exist at least one request header.");
155 is(headers[0].name, "Content-Type",
156 "The first header name should be 'Content-Type'.");
157 }
159 function test_escapeStringPosix() {
160 let surroundedWithQuotes = "A simple string";
161 is(CurlUtils.escapeStringPosix(surroundedWithQuotes), "'A simple string'",
162 "The string should be surrounded with single quotes.");
164 let singleQuotes = "It's unusual to put crickets in your coffee.";
165 is(CurlUtils.escapeStringPosix(singleQuotes),
166 "$'It\\'s unusual to put crickets in your coffee.'",
167 "Single quotes should be escaped.");
169 let newLines = "Line 1\r\nLine 2\u000d\u000ALine3";
170 is(CurlUtils.escapeStringPosix(newLines), "$'Line 1\\r\\nLine 2\\r\\nLine3'",
171 "Newlines should be escaped.");
173 let controlChars = "\u0007 \u0009 \u000C \u001B";
174 is(CurlUtils.escapeStringPosix(controlChars), "$'\\x07 \\x09 \\x0c \\x1b'",
175 "Control characters should be escaped.");
177 let extendedAsciiChars = "æ ø ü ß ö é";
178 is(CurlUtils.escapeStringPosix(extendedAsciiChars),
179 "$'\\xc3\\xa6 \\xc3\\xb8 \\xc3\\xbc \\xc3\\x9f \\xc3\\xb6 \\xc3\\xa9'",
180 "Character codes outside of the decimal range 32 - 126 should be escaped.");
181 }
183 function test_escapeStringWin() {
184 let surroundedWithDoubleQuotes = "A simple string";
185 is(CurlUtils.escapeStringWin(surroundedWithDoubleQuotes), '"A simple string"',
186 "The string should be surrounded with double quotes.");
188 let doubleQuotes = "Quote: \"Time is an illusion. Lunchtime doubly so.\"";
189 is(CurlUtils.escapeStringWin(doubleQuotes),
190 '"Quote: ""Time is an illusion. Lunchtime doubly so."""',
191 "Double quotes should be escaped.");
193 let percentSigns = "%AppData%";
194 is(CurlUtils.escapeStringWin(percentSigns), '""%"AppData"%""',
195 "Percent signs should be escaped.");
197 let backslashes = "\\A simple string\\";
198 is(CurlUtils.escapeStringWin(backslashes), '"\\\\A simple string\\\\"',
199 "Backslashes should be escaped.");
201 let newLines = "line1\r\nline2\r\nline3";
202 is(CurlUtils.escapeStringWin(newLines),
203 '"line1"^\u000d\u000A"line2"^\u000d\u000A"line3"',
204 "Newlines should be escaped.");
205 }
207 function createCurlData(aSelected, aNetwork) {
208 return Task.spawn(function*() {
209 // Create a sanitized object for the Curl command generator.
210 let data = {
211 url: aSelected.url,
212 method: aSelected.method,
213 headers: [],
214 httpVersion: aSelected.httpVersion,
215 postDataText: null
216 };
218 // Fetch header values.
219 for (let { name, value } of aSelected.requestHeaders.headers) {
220 let text = yield aNetwork.getString(value);
221 data.headers.push({ name: name, value: text });
222 }
224 // Fetch the request payload.
225 if (aSelected.requestPostData) {
226 let postData = aSelected.requestPostData.postData.text;
227 data.postDataText = yield aNetwork.getString(postData);
228 }
230 return data;
231 });
232 }