Backed out 3 changesets (bug 965527, bug 859059, bug 812172) for mochitest and xperf orange on a CLOSED TREE

Backed out changeset 18f579c4308e (bug 965527)
Backed out changeset 70ed33107301 (bug 859059)
Backed out changeset 7b59b92580fa (bug 812172)
This commit is contained in:
Ryan VanderMeulen 2014-03-21 10:33:18 -04:00
Родитель cbd250673e
Коммит d269ff5c2a
21 изменённых файлов: 48 добавлений и 1216 удалений

Просмотреть файл

@ -140,9 +140,6 @@ Object.defineProperty(this, "NetworkHelper", {
XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
"@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
XPCOMUtils.defineLazyModuleGetter(this, "Curl",
"resource:///modules/devtools/Curl.jsm");
/**
* Object defining the network monitor controller components.
*/

Просмотреть файл

@ -523,37 +523,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
clipboardHelper.copyString(selected.url, document);
},
/**
* Copy a cURL command from the currently selected item.
*/
copyAsCurl: function() {
let selected = this.selectedItem.attachment;
Task.spawn(function*() {
// Create a sanitized object for the Curl command generator.
let data = {
url: selected.url,
method: selected.method,
headers: [],
httpVersion: selected.httpVersion,
postDataText: null
};
// Fetch header values.
for (let { name, value } of selected.requestHeaders.headers) {
let text = yield gNetwork.getString(value);
data.headers.push({ name: name, value: text });
}
// Fetch the request payload.
if (selected.requestPostData) {
let postData = selected.requestPostData.postData.text;
data.postDataText = yield gNetwork.getString(postData);
}
clipboardHelper.copyString(Curl.generateCommand(data), document);
});
},
/**
* Copy image as data uri.
*/
@ -1591,9 +1560,6 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
let copyUrlElement = $("#request-menu-context-copy-url");
copyUrlElement.hidden = !selectedItem;
let copyAsCurlElement = $("#request-menu-context-copy-as-curl");
copyAsCurlElement.hidden = !selectedItem || !selectedItem.attachment.responseContent;
let copyImageAsDataUriElement = $("#request-menu-context-copy-image-as-data-uri");
copyImageAsDataUriElement.hidden = !selectedItem ||
!selectedItem.attachment.responseContent ||

Просмотреть файл

@ -29,9 +29,6 @@
<menuitem id="request-menu-context-copy-url"
label="&netmonitorUI.context.copyUrl;"
accesskey="&netmonitorUI.context.copyUrl.accesskey;"/>
<menuitem id="request-menu-context-copy-as-curl"
label="&netmonitorUI.context.copyAsCurl;"
oncommand="NetMonitorView.RequestsMenu.copyAsCurl();"/>
<menuitem id="request-menu-context-copy-image-as-data-uri"
label="&netmonitorUI.context.copyImageAsDataUri;"
accesskey="&netmonitorUI.context.copyImageAsDataUri.accesskey;"/>

Просмотреть файл

@ -21,8 +21,6 @@ support-files =
html_sorting-test-page.html
html_statistics-test-page.html
html_status-codes-test-page.html
html_copy-as-curl.html
html_curl-utils.html
sjs_content-type-test-server.sjs
sjs_simple-test-server.sjs
sjs_sorting-test-server.sjs
@ -41,10 +39,8 @@ support-files =
[browser_net_clear.js]
[browser_net_complex-params.js]
[browser_net_content-type.js]
[browser_net_curl-utils.js]
[browser_net_copy_image_as_data_uri.js]
[browser_net_copy_url.js]
[browser_net_copy_as_curl.js]
[browser_net_cyrillic-01.js]
[browser_net_cyrillic-02.js]
[browser_net_filter-01.js]

Просмотреть файл

@ -1,72 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if Copy as cURL works.
*/
function test() {
initNetMonitor(CURL_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
const EXPECTED_POSIX_RESULT = [
"curl",
"'" + SIMPLE_SJS + "'",
"-H 'Host: example.com'",
"-H 'User-Agent: " + aDebuggee.navigator.userAgent + "'",
"-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'",
"-H 'Accept-Language: " + aDebuggee.navigator.language + "'",
"-H 'Accept-Encoding: gzip, deflate'",
"-H 'X-Custom-Header-1: Custom value'",
"-H 'X-Custom-Header-2: 8.8.8.8'",
"-H 'X-Custom-Header-3: Mon, 3 Mar 2014 11:11:11 GMT'",
"-H 'Referer: " + CURL_URL + "'",
"-H 'Connection: keep-alive'"
].join(" ");
const EXPECTED_WIN_RESULT = [
'curl',
'"' + SIMPLE_SJS + '"',
'-H "Host: example.com"',
'-H "User-Agent: ' + aDebuggee.navigator.userAgent + '"',
'-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"',
'-H "Accept-Language: ' + aDebuggee.navigator.language + '"',
'-H "Accept-Encoding: gzip, deflate"',
'-H "X-Custom-Header-1: Custom value"',
'-H "X-Custom-Header-2: 8.8.8.8"',
'-H "X-Custom-Header-3: Mon, 3 Mar 2014 11:11:11 GMT"',
'-H "Referer: ' + CURL_URL + '"',
'-H "Connection: keep-alive"'
].join(" ");
const EXPECTED_RESULT = Services.appinfo.OS == "WINNT" ?
EXPECTED_WIN_RESULT : EXPECTED_POSIX_RESULT;
let { NetMonitorView } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
waitForNetworkEvents(aMonitor, 1).then(() => {
let requestItem = RequestsMenu.getItemAtIndex(0);
RequestsMenu.selectedItem = requestItem;
waitForClipboard(EXPECTED_RESULT, function setup() {
RequestsMenu.copyAsCurl();
}, function onSuccess() {
ok(true, "Clipboard contains a cURL command for the currently selected item's url.");
cleanUp();
}, function onFailure() {
ok(false, "Creating a cURL command for the currently selected item was unsuccessful.");
cleanUp();
});
});
aDebuggee.performRequest(SIMPLE_SJS);
function cleanUp(){
teardown(aMonitor).then(finish);
}
});
}

Просмотреть файл

@ -1,232 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests Curl Utils functionality.
*/
function test() {
initNetMonitor(CURL_UTILS_URL).then(([aTab, aDebuggee, aMonitor]) => {
info("Starting test... ");
let { NetMonitorView, gNetwork } = aMonitor.panelWin;
let { RequestsMenu } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
waitForNetworkEvents(aMonitor, 1, 3).then(() => {
let requests = {
get: RequestsMenu.getItemAtIndex(0),
post: RequestsMenu.getItemAtIndex(1),
multipart: RequestsMenu.getItemAtIndex(2),
multipartForm: RequestsMenu.getItemAtIndex(3)
};
Task.spawn(function*() {
yield createCurlData(requests.get.attachment, gNetwork).then((aData) => {
test_findHeader(aData);
});
yield createCurlData(requests.post.attachment, gNetwork).then((aData) => {
test_isUrlEncodedRequest(aData);
test_writePostDataTextParams(aData);
});
yield createCurlData(requests.multipart.attachment, gNetwork).then((aData) => {
test_isMultipartRequest(aData);
test_getMultipartBoundary(aData);
test_removeBinaryDataFromMultipartText(aData);
});
yield createCurlData(requests.multipartForm.attachment, gNetwork).then((aData) => {
test_getHeadersFromMultipartText(aData);
});
if (Services.appinfo.OS != "WINNT") {
test_escapeStringPosix();
} else {
test_escapeStringWin();
}
teardown(aMonitor).then(finish);
});
});
aDebuggee.performRequests(SIMPLE_SJS);
});
}
function test_isUrlEncodedRequest(aData) {
let isUrlEncoded = CurlUtils.isUrlEncodedRequest(aData);
ok(isUrlEncoded, "Should return true for url encoded requests.");
}
function test_isMultipartRequest(aData) {
let isMultipart = CurlUtils.isMultipartRequest(aData);
ok(isMultipart, "Should return true for multipart/form-data requests.");
}
function test_findHeader(aData) {
let headers = aData.headers;
let hostName = CurlUtils.findHeader(headers, "Host");
let requestedWithLowerCased = CurlUtils.findHeader(headers, "x-requested-with");
let doesNotExist = CurlUtils.findHeader(headers, "X-Does-Not-Exist");
is(hostName, "example.com",
"Header with name 'Host' should be found in the request array.");
is(requestedWithLowerCased, "XMLHttpRequest",
"The search should be case insensitive.");
is(doesNotExist, null,
"Should return null when a header is not found.");
}
function test_writePostDataTextParams(aData) {
let params = CurlUtils.writePostDataTextParams(aData.postDataText);
is(params, "param1=value1&param2=value2&param3=value3",
"Should return a serialized representation of the request parameters");
}
function test_getMultipartBoundary(aData) {
let boundary = CurlUtils.getMultipartBoundary(aData);
ok(/-{3,}\w+/.test(boundary),
"A boundary string should be found in a multipart request.");
}
function test_removeBinaryDataFromMultipartText(aData) {
let generatedBoundary = CurlUtils.getMultipartBoundary(aData);
let text = aData.postDataText;
let binaryRemoved =
CurlUtils.removeBinaryDataFromMultipartText(text, generatedBoundary);
let boundary = "--" + generatedBoundary;
const EXPECTED_POSIX_RESULT = [
"$'",
boundary,
"\\r\\n\\r\\n",
"Content-Disposition: form-data; name=\"param1\"",
"\\r\\n\\r\\n",
"value1",
"\\r\\n",
boundary,
"\\r\\n\\r\\n",
"Content-Disposition: form-data; name=\"file\"; filename=\"filename.png\"",
"\\r\\n",
"Content-Type: image/png",
"\\r\\n\\r\\n",
generatedBoundary,
"--\\r\\n",
"'"
].join("");
const EXPECTED_WIN_RESULT = [
'"' + boundary + '"^',
'\u000d\u000A\u000d\u000A',
'"Content-Disposition: form-data; name=""param1"""^',
'\u000d\u000A\u000d\u000A',
'"value1"^',
'\u000d\u000A',
'"' + boundary + '"^',
'\u000d\u000A\u000d\u000A',
'"Content-Disposition: form-data; name=""file""; filename=""filename.png"""^',
'\u000d\u000A',
'"Content-Type: image/png"^',
'\u000d\u000A\u000d\u000A',
'"' + generatedBoundary + '--"^',
'\u000d\u000A',
'""'
].join("");
if (Services.appinfo.OS != "WINNT") {
is(CurlUtils.escapeStringPosix(binaryRemoved), EXPECTED_POSIX_RESULT,
"The mulitpart request payload should not contain binary data.");
} else {
is(CurlUtils.escapeStringWin(binaryRemoved), EXPECTED_WIN_RESULT,
"WinNT: The mulitpart request payload should not contain binary data.");
}
}
function test_getHeadersFromMultipartText(aData) {
let headers = CurlUtils.getHeadersFromMultipartText(aData.postDataText);
ok(Array.isArray(headers),
"Should return an array.");
ok(headers.length > 0,
"There should exist at least one request header.");
is(headers[0].name, "Content-Type",
"The first header name should be 'Content-Type'.");
}
function test_escapeStringPosix() {
let surroundedWithQuotes = "A simple string";
is(CurlUtils.escapeStringPosix(surroundedWithQuotes), "'A simple string'",
"The string should be surrounded with single quotes.");
let singleQuotes = "It's unusual to put crickets in your coffee.";
is(CurlUtils.escapeStringPosix(singleQuotes),
"$'It\\'s unusual to put crickets in your coffee.'",
"Single quotes should be escaped.");
let newLines = "Line 1\r\nLine 2\u000d\u000ALine3";
is(CurlUtils.escapeStringPosix(newLines), "$'Line 1\\r\\nLine 2\\r\\nLine3'",
"Newlines should be escaped.");
let controlChars = "\u0007 \u0009 \u000C \u001B";
is(CurlUtils.escapeStringPosix(controlChars), "$'\\x07 \\x09 \\x0c \\x1b'",
"Control characters should be escaped.");
let extendedAsciiChars = "æ ø ü ß ö é";
is(CurlUtils.escapeStringPosix(extendedAsciiChars),
"$'\\xc3\\xa6 \\xc3\\xb8 \\xc3\\xbc \\xc3\\x9f \\xc3\\xb6 \\xc3\\xa9'",
"Character codes outside of the decimal range 32 - 126 should be escaped.");
}
function test_escapeStringWin() {
let surroundedWithDoubleQuotes = "A simple string";
is(CurlUtils.escapeStringWin(surroundedWithDoubleQuotes), '"A simple string"',
"The string should be surrounded with double quotes.");
let doubleQuotes = "Quote: \"Time is an illusion. Lunchtime doubly so.\"";
is(CurlUtils.escapeStringWin(doubleQuotes),
'"Quote: ""Time is an illusion. Lunchtime doubly so."""',
"Double quotes should be escaped.");
let percentSigns = "%AppData%";
is(CurlUtils.escapeStringWin(percentSigns), '""%"AppData"%""',
"Percent signs should be escaped.");
let backslashes = "\\A simple string\\";
is(CurlUtils.escapeStringWin(backslashes), '"\\\\A simple string\\\\"',
"Backslashes should be escaped.");
let newLines = "line1\r\nline2\r\nline3";
is(CurlUtils.escapeStringWin(newLines),
'"line1"^\u000d\u000A"line2"^\u000d\u000A"line3"',
"Newlines should be escaped.");
}
function createCurlData(aSelected, aNetwork) {
return Task.spawn(function*() {
// Create a sanitized object for the Curl command generator.
let data = {
url: aSelected.url,
method: aSelected.method,
headers: [],
httpVersion: aSelected.httpVersion,
postDataText: null
};
// Fetch header values.
for (let { name, value } of aSelected.requestHeaders.headers) {
let text = yield aNetwork.getString(value);
data.headers.push({ name: name, value: text });
}
// Fetch the request payload.
if (aSelected.requestPostData) {
let postData = aSelected.requestPostData.postData.text;
data.postDataText = yield aNetwork.getString(postData);
}
return data;
});
}

Просмотреть файл

@ -9,7 +9,6 @@ let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
let { CurlUtils } = Cu.import("resource:///modules/devtools/Curl.jsm", {});
let TargetFactory = devtools.TargetFactory;
let Toolbox = devtools.Toolbox;
@ -35,8 +34,6 @@ const FILTERING_URL = EXAMPLE_URL + "html_filter-test-page.html";
const INFINITE_GET_URL = EXAMPLE_URL + "html_infinite-get-page.html";
const CUSTOM_GET_URL = EXAMPLE_URL + "html_custom-get-page.html";
const STATISTICS_URL = EXAMPLE_URL + "html_statistics-test-page.html";
const CURL_URL = EXAMPLE_URL + "html_copy-as-curl.html";
const CURL_UTILS_URL = EXAMPLE_URL + "html_curl-utils.html";
const SIMPLE_SJS = EXAMPLE_URL + "sjs_simple-test-server.sjs";
const CONTENT_TYPE_SJS = EXAMPLE_URL + "sjs_content-type-test-server.sjs";

Просмотреть файл

@ -1,27 +0,0 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Network Monitor test page</title>
</head>
<body>
<p>Performing a GET request</p>
<script type="text/javascript">
function performRequest(aUrl) {
var xhr = new XMLHttpRequest();
xhr.open("GET", aUrl, true);
xhr.setRequestHeader("Accept-Language", window.navigator.language);
xhr.setRequestHeader("X-Custom-Header-1", "Custom value");
xhr.setRequestHeader("X-Custom-Header-2", "8.8.8.8");
xhr.setRequestHeader("X-Custom-Header-3", "Mon, 3 Mar 2014 11:11:11 GMT");
xhr.send(null);
}
</script>
</body>
</html>

Просмотреть файл

@ -1,99 +0,0 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>Network Monitor test page</title>
</head>
<body>
<p>Performing requests</p>
<p>
<canvas width="100" height="100"></canvas>
</p>
<hr/>
<form method="post" action="#" enctype="multipart/form-data" target="target" id="post-form">
<input type="text" name="param1" value="value1"/>
<input type="text" name="param2" value="value2"/>
<input type="text" name="param3" value="value3"/>
<input type="submit"/>
</form>
<iframe name="target"></iframe>
<script type="text/javascript">
function ajaxGet(aUrl, aCallback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", aUrl + "?param1=value1&param2=value2&param3=value3", true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.onload = function() {
aCallback();
};
xhr.send();
}
function ajaxPost(aUrl, aCallback) {
var xhr = new XMLHttpRequest();
xhr.open("POST", aUrl, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.onload = function() {
aCallback();
};
var params = "param1=value1&param2=value2&param3=value3";
xhr.send(params);
}
function ajaxMultipart(aUrl, aCallback) {
var xhr = new XMLHttpRequest();
xhr.open("POST", aUrl, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.onload = function() {
aCallback();
};
getCanvasElem().toBlob((blob) => {
var formData = new FormData();
formData.append("param1", "value1");
formData.append("file", blob, "filename.png");
xhr.send(formData);
});
}
function submitForm() {
var form = document.querySelector("#post-form");
form.submit();
}
function getCanvasElem() {
return document.querySelector("canvas");
}
function initCanvas() {
var canvas = getCanvasElem();
var ctx = canvas.getContext("2d");
ctx.fillRect(0,0,100,100);
ctx.clearRect(20,20,60,60);
ctx.strokeRect(25,25,50,50);
}
function performRequests(aUrl) {
ajaxGet(aUrl, () => {
ajaxPost(aUrl, () => {
ajaxMultipart(aUrl, () => {
submitForm();
});
});
});
}
initCanvas();
</script>
</body>
</html>

Просмотреть файл

@ -1,396 +0,0 @@
/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
* Copyright (C) 2011 Google Inc. All rights reserved.
* Copyright (C) 2009 Mozilla Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
"use strict";
this.EXPORTED_SYMBOLS = ["Curl", "CurlUtils"];
Components.utils.import("resource://gre/modules/Services.jsm");
const DEFAULT_HTTP_VERSION = "HTTP/1.1";
this.Curl = {
/**
* Generates a cURL command string which can be used from the command line etc.
*
* @param object aData
* Datasource to create the command from.
* The object must contain the following properties:
* - url:string, the URL of the request.
* - method:string, the request method upper cased. HEAD / GET / POST etc.
* - headers:array, an array of request headers {name:x, value:x} tuples.
* - httpVersion:string, http protocol version rfc2616 formatted. Eg. "HTTP/1.1"
* - postDataText:string, optional - the request payload.
*
* @return string
* A cURL command.
*/
generateCommand: function(aData) {
let utils = CurlUtils;
let command = ["curl"];
let ignoredHeaders = new Set();
// The cURL command is expected to run on the same platform that Firefox runs
// (it may be different from the inspected page platform).
let escapeString = Services.appinfo.OS == "WINNT" ?
utils.escapeStringWin : utils.escapeStringPosix;
// Add URL.
command.push(escapeString(aData.url));
let postDataText = null;
let multipartRequest = utils.isMultipartRequest(aData);
// Create post data.
let data = [];
if (utils.isUrlEncodedRequest(aData) || aData.method == "PUT") {
postDataText = aData.postDataText;
data.push("--data");
data.push(escapeString(utils.writePostDataTextParams(postDataText)));
ignoredHeaders.add("Content-Length");
} else if (multipartRequest) {
postDataText = aData.postDataText;
data.push("--data-binary");
let boundary = utils.getMultipartBoundary(aData);
let text = utils.removeBinaryDataFromMultipartText(postDataText, boundary);
data.push(escapeString(text));
ignoredHeaders.add("Content-Length");
}
// Add method.
// For GET and POST requests this is not necessary as GET is the
// default. If --data or --binary is added POST is the default.
if (!(aData.method == "GET" || aData.method == "POST")) {
command.push("-X");
command.push(aData.method);
}
// Add -I (HEAD)
// For servers that supports HEAD.
// This will fetch the header of a document only.
if (aData.method == "HEAD") {
command.push("-I");
}
// Add http version.
if (aData.httpVersion && aData.httpVersion != DEFAULT_HTTP_VERSION) {
command.push("--" + aData.httpVersion.split("/")[1]);
}
// Add request headers.
let headers = aData.headers;
if (multipartRequest) {
let multipartHeaders = utils.getHeadersFromMultipartText(postDataText);
headers = headers.concat(multipartHeaders);
}
for (let i = 0; i < headers.length; i++) {
let header = headers[i];
if (ignoredHeaders.has(header.name)) {
continue;
}
command.push("-H");
command.push(escapeString(header.name + ": " + header.value));
}
// Add post data.
command = command.concat(data);
return command.join(" ");
}
};
/**
* Utility functions for the Curl command generator.
*/
this.CurlUtils = {
/**
* Check if the request is an URL encoded request.
*
* @param object aData
* The data source. See the description in the Curl object.
* @return boolean
* True if the request is URL encoded, false otherwise.
*/
isUrlEncodedRequest: function(aData) {
let postDataText = aData.postDataText;
if (!postDataText) {
return false;
}
postDataText = postDataText.toLowerCase();
if (postDataText.contains("content-type: application/x-www-form-urlencoded")) {
return true;
}
let contentType = this.findHeader(aData.headers, "content-type");
return (contentType &&
contentType.toLowerCase().contains("application/x-www-form-urlencoded"));
},
/**
* Check if the request is a multipart request.
*
* @param object aData
* The data source.
* @return boolean
* True if the request is multipart reqeust, false otherwise.
*/
isMultipartRequest: function(aData) {
let postDataText = aData.postDataText;
if (!postDataText) {
return false;
}
postDataText = postDataText.toLowerCase();
if (postDataText.contains("content-type: multipart/form-data")) {
return true;
}
let contentType = this.findHeader(aData.headers, "content-type");
return (contentType &&
contentType.toLowerCase().contains("multipart/form-data;"));
},
/**
* Write out paramters from post data text.
*
* @param object aPostDataText
* Post data text.
* @return string
* Post data parameters.
*/
writePostDataTextParams: function(aPostDataText) {
let lines = aPostDataText.split("\r\n");
return lines[lines.length - 1];
},
/**
* Finds the header with the given name in the headers array.
*
* @param array aHeaders
* Array of headers info {name:x, value:x}.
* @param string aName
* The header name to find.
* @return string
* The found header value or null if not found.
*/
findHeader: function(aHeaders, aName) {
if (!aHeaders) {
return null;
}
let name = aName.toLowerCase();
for (let header of aHeaders) {
if (name == header.name.toLowerCase()) {
return header.value;
}
}
return null;
},
/**
* Returns the boundary string for a multipart request.
*
* @param string aData
* The data source. See the description in the Curl object.
* @return string
* The boundary string for the request.
*/
getMultipartBoundary: function(aData) {
let boundaryRe = /\bboundary=(-{3,}\w+)/i;
// Get the boundary string from the Content-Type request header.
let contentType = this.findHeader(aData.headers, "Content-Type");
if (boundaryRe.test(contentType)) {
return contentType.match(boundaryRe)[1];
}
// Temporary workaround. As of 2014-03-11 the requestHeaders array does not
// always contain the Content-Type header for mulitpart requests. See bug 978144.
// Find the header from the request payload.
let boundaryString = aData.postDataText.match(boundaryRe)[1];
if (boundaryString) {
return boundaryString;
}
return null;
},
/**
* Removes the binary data from mulitpart text.
*
* @param string aMultipartText
* Multipart form data text.
* @param string aBoundary
* The boundary string.
* @return string
* The mulitpart text without the binary data.
*/
removeBinaryDataFromMultipartText: function(aMultipartText, aBoundary) {
let result = "";
let boundary = "--" + aBoundary;
let parts = aMultipartText.split(boundary);
for (let part of parts) {
// Each part is expected to have a content disposition line.
let contentDispositionLine = part.trimLeft().split("\r\n")[0];
if (!contentDispositionLine) {
continue;
}
contentDispositionLine = contentDispositionLine.toLowerCase();
if (contentDispositionLine.contains("content-disposition: form-data")) {
if (contentDispositionLine.contains("filename=")) {
// The header lines and the binary blob is separated by 2 CRLF's.
// Add only the headers to the result.
let headers = part.split("\r\n\r\n")[0];
result += boundary + "\r\n" + headers + "\r\n\r\n";
}
else {
result += boundary + "\r\n" + part;
}
}
}
result += aBoundary + "--\r\n";
return result;
},
/**
* Get the headers from a multipart post data text.
*
* @param string aMultipartText
* Multipart post text.
* @return array
* An array of header objects {name:x, value:x}
*/
getHeadersFromMultipartText: function(aMultipartText) {
let headers = [];
if (!aMultipartText || aMultipartText.startsWith("---")) {
return headers;
}
// Get the header section.
let index = aMultipartText.indexOf("\r\n\r\n");
if (index == -1) {
return headers;
}
// Parse the header lines.
let headersText = aMultipartText.substring(0, index);
let headerLines = headersText.split("\r\n");
let lastHeaderName = null;
for (let line of headerLines) {
// Create a header for each line in fields that spans across multiple lines.
// Subsquent lines always begins with at least one space or tab character.
// (rfc2616)
if (lastHeaderName && /^\s+/.test(line)) {
headers.push({ name: lastHeaderName, value: line.trim() });
continue;
}
let indexOfColon = line.indexOf(":");
if (indexOfColon == -1) {
continue;
}
let header = [line.slice(0, indexOfColon), line.slice(indexOfColon + 1)];
if (header.length != 2) {
continue;
}
lastHeaderName = header[0].trim();
headers.push({ name: lastHeaderName, value: header[1].trim() });
}
return headers;
},
/**
* Escape util function for POSIX oriented operating systems.
* Credit: Google DevTools
*/
escapeStringPosix: function(str) {
function escapeCharacter(x) {
let code = x.charCodeAt(0);
if (code < 256) {
// Add leading zero when needed to not care about the next character.
return code < 16 ? "\\x0" + code.toString(16) : "\\x" + code.toString(16);
}
code = code.toString(16);
return "\\u" + ("0000" + code).substr(code.length, 4);
}
if (/[^\x20-\x7E]|\'/.test(str)) {
// Use ANSI-C quoting syntax.
return "$\'" + str.replace(/\\/g, "\\\\")
.replace(/\'/g, "\\\'")
.replace(/\n/g, "\\n")
.replace(/\r/g, "\\r")
.replace(/[^\x20-\x7E]/g, escapeCharacter) + "'";
} else {
// Use single quote syntax.
return "'" + str + "'";
}
},
/**
* Escape util function for Windows systems.
* Credit: Google DevTools
*/
escapeStringWin: function(str) {
/* Replace quote by double quote (but not by \") because it is
recognized by both cmd.exe and MS Crt arguments parser.
Replace % by "%" because it could be expanded to an environment
variable value. So %% becomes "%""%". Even if an env variable ""
(2 doublequotes) is declared, the cmd.exe will not
substitute it with its value.
Replace each backslash with double backslash to make sure
MS Crt arguments parser won't collapse them.
Replace new line outside of quotes since cmd.exe doesn't let
to do it inside.
*/
return "\"" + str.replace(/"/g, "\"\"")
.replace(/%/g, "\"%\"")
.replace(/\\/g, "\\\\")
.replace(/[\r\n]+/g, "\"^$&\"") + "\"";
}
};

Просмотреть файл

@ -202,12 +202,6 @@
- on the context menu that copies the selected request's url -->
<!ENTITY netmonitorUI.context.copyUrl "Copy URL">
<!-- LOCALIZATION NOTE (netmonitorUI.context.copyAsCurl): This is the label displayed
- on the context menu that copies the selected request as a cURL command.
- The capitalization is part of the official name and should be used throughout all languages.
- http://en.wikipedia.org/wiki/CURL -->
<!ENTITY netmonitorUI.context.copyAsCurl "Copy as cURL">
<!-- LOCALIZATION NOTE (netmonitorUI.context.copyUrl.accesskey): This is the access key
- for the Copy URL menu item displayed in the context menu for a request -->
<!ENTITY netmonitorUI.context.copyUrl.accesskey "C">

Просмотреть файл

@ -135,47 +135,6 @@ for (let [constProp, dirKey] of [
*/
let clone = SharedAll.clone;
/**
* Extract a shortened version of an object, fit for logging.
*
* This function returns a copy of the original object in which all
* long strings, Arrays, TypedArrays, ArrayBuffers are removed and
* replaced with plceholders. Use this function to sanitize objects
* if you wish to log them or to keep them in memory.
*
* @param {*} obj The obj to shorten.
* @return {*} array A shorter object, fit for logging.
*/
function summarizeObject(obj) {
if (!obj) {
return null;
}
if (typeof obj == "string") {
if (obj.length > 1024) {
return {"Long string": obj.length};
}
return obj;
}
if (typeof obj == "object") {
if (Array.isArray(obj)) {
if (obj.length > 32) {
return {"Long array": obj.length};
}
return [summarizeObject(k) for (k of obj)];
}
if ("byteLength" in obj) {
// Assume TypedArray or ArrayBuffer
return {"Binary Data": obj.byteLength};
}
let result = {};
for (let k of Object.keys(obj)) {
result[k] = summarizeObject(obj[k]);
}
return result;
}
return obj;
}
let worker = null;
let Scheduler = {
/**
@ -198,41 +157,19 @@ let Scheduler = {
queue: Promise.resolve(),
/**
* Miscellaneous debugging information
* The latest message sent and still waiting for a reply. In DEBUG
* builds, the entire message is stored, which may be memory-consuming.
* In non-DEBUG builds, only the method name is stored.
*/
Debugging: {
/**
* The latest message sent and still waiting for a reply. In DEBUG
* builds, the entire message is stored, which may be memory-consuming.
* In non-DEBUG builds, only the method name is stored.
*/
latestSent: undefined,
latestSent: undefined,
/**
* The latest reply received, or null if we are waiting for a reply.
* In DEBUG builds, the entire response is stored, which may be
* memory-consuming. In non-DEBUG builds, only exceptions and
* method names are stored.
*/
latestReceived: undefined,
/**
* Number of messages sent to the worker. This includes the
* initial SET_DEBUG, if applicable.
*/
messagesSent: 0,
/**
* Total number of messages ever queued, including the messages
* sent.
*/
messagesQueued: 0,
/**
* Number of messages received from the worker.
*/
messagesReceived: 0,
},
/**
* The latest reply received, or null if we are waiting for a reply.
* In DEBUG builds, the entire response is stored, which may be
* memory-consuming. In non-DEBUG builds, only exceptions and
* method names are stored.
*/
latestReceived: undefined,
/**
* A timer used to automatically shut down the worker after some time.
@ -297,7 +234,6 @@ let Scheduler = {
if (firstLaunch && SharedAll.Config.DEBUG) {
// If we have delayed sending SET_DEBUG, do it now.
worker.post("SET_DEBUG", [true]);
Scheduler.Debugging.messagesSent++;
}
// By convention, the last argument of any message may be an |options| object.
@ -306,43 +242,41 @@ let Scheduler = {
if (methodArgs) {
options = methodArgs[methodArgs.length - 1];
}
Scheduler.Debugging.messagesQueued++;
return this.push(() => Task.spawn(function*() {
// Update debugging information. As |args| may be quite
// expensive, we only keep a shortened version of it.
Scheduler.Debugging.latestReceived = null;
Scheduler.Debugging.latestSent = [Date.now(), method, summarizeObject(methodArgs)];
Scheduler.latestReceived = null;
if (OS.Constants.Sys.DEBUG) {
// Update possibly memory-expensive debugging information
Scheduler.latestSent = [Date.now(), method, ...args];
} else {
Scheduler.latestSent = [Date.now(), method];
}
let data;
let reply;
let isError = false;
try {
try {
data = yield worker.post(method, ...args);
} finally {
Scheduler.Debugging.messagesReceived++;
}
data = yield worker.post(method, ...args);
reply = data;
} catch (error) {
} catch (error if error instanceof PromiseWorker.WorkerError) {
reply = error;
isError = true;
if (error instanceof PromiseWorker.WorkerError) {
throw EXCEPTION_CONSTRUCTORS[error.data.exn || "OSError"](error.data);
throw EXCEPTION_CONSTRUCTORS[error.data.exn || "OSError"](error.data);
} catch (error if error instanceof ErrorEvent) {
reply = error;
let message = error.message;
if (message == "uncaught exception: [object StopIteration]") {
throw StopIteration;
}
if (error instanceof ErrorEvent) {
let message = error.message;
if (message == "uncaught exception: [object StopIteration]") {
isError = false;
throw StopIteration;
}
throw new Error(message, error.filename, error.lineno);
}
throw ex;
isError = true;
throw new Error(message, error.filename, error.lineno);
} finally {
Scheduler.Debugging.latestSent = Scheduler.Debugging.latestSent.slice(0, 2);
if (isError) {
Scheduler.Debugging.latestReceived = [Date.now(), reply.message, reply.fileName, reply.lineNumber];
Scheduler.latestSent = Scheduler.latestSent.slice(0, 2);
if (OS.Constants.Sys.DEBUG) {
// Update possibly memory-expensive debugging information
Scheduler.latestReceived = [Date.now(), reply];
} else if (isError) {
Scheduler.latestReceived = [Date.now(), reply.message, reply.fileName, reply.lineNumber];
} else {
Scheduler.Debugging.latestReceived = [Date.now(), summarizeObject(reply)];
Scheduler.latestReceived = [Date.now()];
}
if (firstLaunch) {
Scheduler._updateTelemetry();
@ -1429,12 +1363,8 @@ AsyncShutdown.profileBeforeChange.addBlocker(
shutdown: Scheduler.shutdown,
worker: !!worker,
pendingReset: !!Scheduler.resetTimer,
latestSent: Scheduler.Debugging.latestSent,
latestReceived: Scheduler.Debugging.latestReceived,
messagesSent: Scheduler.Debugging.messagesSent,
messagesReceived: Scheduler.Debugging.messagesReceived,
messagesQueued: Scheduler.Debugging.messagesQueued,
DEBUG: SharedAll.Config.DEBUG
latestSent: Scheduler.latestSent,
latestReceived: Scheduler.latestReceived
};
// Convert dates to strings for better readability
for (let key of ["latestSent", "latestReceived"]) {

Просмотреть файл

@ -28,8 +28,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
Cu.import("resource://gre/modules/devtools/Console.jsm");
let promise = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js").Promise;
const { defer, resolve, reject } = promise;
@ -1409,28 +1407,17 @@ ThreadClient.prototype = {
* @param function aOnResponse
* Called with the thread's response.
*/
setBreakpoint: function ({ url, line, column, condition }, aOnResponse) {
setBreakpoint: function (aLocation, aOnResponse) {
// A helper function that sets the breakpoint.
let doSetBreakpoint = function (aCallback) {
const location = {
url: url,
line: line,
column: column
};
let packet = {
to: this._actor,
type: "setBreakpoint",
location: location,
condition: condition
};
let packet = { to: this._actor, type: "setBreakpoint",
location: aLocation };
this.client.request(packet, function (aResponse) {
// Ignoring errors, since the user may be setting a breakpoint in a
// dead script that will reappear on a page reload.
if (aOnResponse) {
let bpClient = new BreakpointClient(this.client,
aResponse.actor,
location);
let bpClient = new BreakpointClient(this.client, aResponse.actor,
aLocation);
if (aCallback) {
aCallback(aOnResponse(aResponse, bpClient));
} else {

Просмотреть файл

@ -187,8 +187,6 @@ RootActor.prototype = {
storageInspector: true,
// Wether storage inspector is read only
storageInspectorReadOnly: true,
// Wether conditional breakpoints are supported
conditionalBreakpoints: true
}
};
},

Просмотреть файл

@ -38,7 +38,7 @@ function BreakpointStore() {
//
// is an object
//
// { url, line, column[, actor] }
// { url, line[, actor] }
//
// where the `actor` property is optional.
this._breakpoints = Object.create(null);
@ -58,7 +58,6 @@ BreakpointStore.prototype = {
* - line
* - column (optional; omission implies that the breakpoint is for
* the whole line)
* - condition (optional)
* - actor (optional)
*/
addBreakpoint: function (aBreakpoint) {
@ -1375,8 +1374,7 @@ ThreadActor.prototype = {
let response = this._createAndStoreBreakpoint({
url: url,
line: line,
column: column,
condition: aRequest.condition
column: column
});
// If the original location of our generated location is different from
// the original location we attempted to set the breakpoint on, we will
@ -1444,13 +1442,11 @@ ThreadActor.prototype = {
let storedBp = this.breakpointStore.getBreakpoint(aLocation);
if (storedBp.actor) {
actor = storedBp.actor;
actor.condition = aLocation.condition;
} else {
storedBp.actor = actor = new BreakpointActor(this, {
url: aLocation.url,
line: aLocation.line,
column: aLocation.column,
condition: aLocation.condition
column: aLocation.column
});
this.threadLifetimePool.addActor(actor);
}
@ -4225,17 +4221,15 @@ FrameActor.prototype.requestTypes = {
* @param object aLocation
* The location of the breakpoint as specified in the protocol.
*/
function BreakpointActor(aThreadActor, { url, line, column, condition })
function BreakpointActor(aThreadActor, aLocation)
{
this.scripts = [];
this.threadActor = aThreadActor;
this.location = { url: url, line: line, column: column };
this.condition = condition;
this.location = aLocation;
}
BreakpointActor.prototype = {
actorPrefix: "breakpoint",
condition: null,
/**
* Called when this same breakpoint is added to another Debugger.Script
@ -4261,14 +4255,6 @@ BreakpointActor.prototype = {
this.scripts = [];
},
isValidCondition: function(aFrame) {
if(!this.condition) {
return true;
}
var res = aFrame.eval(this.condition);
return res.return;
},
/**
* A function that the engine calls when a breakpoint has been hit.
*
@ -4285,9 +4271,7 @@ BreakpointActor.prototype = {
column: this.location.column
}));
if (this.threadActor.sources.isBlackBoxed(url)
|| aFrame.onStep
|| !this.isValidCondition(aFrame)) {
if (this.threadActor.sources.isBlackBoxed(url) || aFrame.onStep) {
return undefined;
}

Просмотреть файл

@ -65,7 +65,6 @@ this.promised = promised;
this.all = all;
Cu.import("resource://gre/modules/devtools/SourceMap.jsm");
Cu.import("resource://gre/modules/devtools/Console.jsm");
function dumpn(str) {
if (wantLogging) {

Просмотреть файл

@ -30,7 +30,6 @@ function tryImport(url) {
tryImport("resource://gre/modules/devtools/dbg-server.jsm");
tryImport("resource://gre/modules/devtools/dbg-client.jsm");
tryImport("resource://gre/modules/devtools/Loader.jsm");
tryImport("resource://gre/modules/devtools/Console.jsm");
function testExceptionHook(ex) {
try {

Просмотреть файл

@ -1,61 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Check conditional breakpoint when condition evaluates to true.
*/
var gDebuggee;
var gClient;
var gThreadClient;
function run_test()
{
initTestDebuggerServer();
gDebuggee = addTestGlobal("test-conditional-breakpoint");
gClient = new DebuggerClient(DebuggerServer.connectPipe());
gClient.connect(function () {
attachTestTabAndResume(gClient, "test-conditional-breakpoint", function (aResponse, aTabClient, aThreadClient) {
gThreadClient = aThreadClient;
test_simple_breakpoint();
});
});
do_test_pending();
}
function test_simple_breakpoint()
{
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
gThreadClient.setBreakpoint({
url: "test.js",
line: 3,
condition: "a === 1"
}, function (aResponse, bpClient) {
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
// Check the return value.
do_check_eq(aPacket.why.type, "breakpoint");
do_check_eq(aPacket.frame.where.line, 3);
// Remove the breakpoint.
bpClient.remove(function (aResponse) {
gThreadClient.resume(function () {
finishClient(gClient);
});
});
});
// Continue until the breakpoint is hit.
gThreadClient.resume();
});
});
Components.utils.evalInSandbox("debugger;\n" + // 1
"var a = 1;\n" + // 2
"var b = 2;\n", // 3
gDebuggee,
"1.8",
"test.js",
1);
}

Просмотреть файл

@ -1,60 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Check conditional breakpoint when condition evaluates to false.
*/
var gDebuggee;
var gClient;
var gThreadClient;
function run_test()
{
initTestDebuggerServer();
gDebuggee = addTestGlobal("test-conditional-breakpoint");
gClient = new DebuggerClient(DebuggerServer.connectPipe());
gClient.connect(function () {
attachTestTabAndResume(gClient, "test-conditional-breakpoint", function (aResponse, aTabClient, aThreadClient) {
gThreadClient = aThreadClient;
test_simple_breakpoint();
});
});
do_test_pending();
}
function test_simple_breakpoint()
{
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
gThreadClient.setBreakpoint({
url: "test.js",
line: 3,
condition: "a === 2"
}, function (aResponse, bpClient) {
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
// Check the return value.
do_check_eq(aPacket.why.type, "debuggerStatement");
do_check_eq(aPacket.frame.where.line, 4);
// Remove the breakpoint.
bpClient.remove(function (aResponse) {
gThreadClient.resume(function () {
finishClient(gClient);
});
});
});
// Continue until the breakpoint is hit.
gThreadClient.resume();
});
});
Components.utils.evalInSandbox("debugger;\n" + // 1
"var a = 1;\n" + // 2
"var b = 2;\n" + // 3
"debugger;", // 4
gDebuggee,
"1.8",
"test.js",
1);
}

Просмотреть файл

@ -1,62 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Check conditional breakpoint when condition throws and make sure it is ignored
*/
var gDebuggee;
var gClient;
var gThreadClient;
function run_test()
{
initTestDebuggerServer();
gDebuggee = addTestGlobal("test-conditional-breakpoint");
gClient = new DebuggerClient(DebuggerServer.connectPipe());
gClient.connect(function () {
attachTestTabAndResume(gClient, "test-conditional-breakpoint", function (aResponse, aTabClient, aThreadClient) {
gThreadClient = aThreadClient;
test_simple_breakpoint();
});
});
do_test_pending();
}
function test_simple_breakpoint()
{
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
gThreadClient.setBreakpoint({
url: "test.js",
line: 3,
condition: "throw new Error()"
}, function (aResponse, bpClient) {
gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket) {
// Check the return value.
do_check_eq(aPacket.why.type, "debuggerStatement");
do_check_eq(aPacket.frame.where.line, 4);
// Remove the breakpoint.
bpClient.remove(function (aResponse) {
gThreadClient.resume(function () {
finishClient(gClient);
});
});
});
// Continue until the breakpoint is hit.
gThreadClient.resume();
});
});
Components.utils.evalInSandbox("debugger;\n" + // 1
"var a = 1;\n" + // 2
"var b = 2;\n" + // 3
"debugger;", // 4
gDebuggee,
"1.8",
"test.js",
1);
}

Просмотреть файл

@ -112,9 +112,6 @@ reason = bug 820380
[test_breakpoint-16.js]
[test_breakpoint-17.js]
[test_breakpoint-18.js]
[test_conditional_breakpoint-01.js]
[test_conditional_breakpoint-02.js]
[test_conditional_breakpoint-03.js]
[test_eventlooplag_actor.js]
run-if = toolkit == "gonk"
[test_listsources-01.js]