123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
- /* 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/. */
- "use strict";
- const {Ci} = require("chrome");
- const Services = require("Services");
- const {makeInfallible} = require("devtools/shared/DevToolsUtils");
- loader.lazyGetter(this, "NetworkHelper", () => require("devtools/shared/webconsole/network-helper"));
- // Helper tracer. Should be generic sharable by other modules (bug 1171927)
- const trace = {
- log: function (...args) {
- }
- };
- const acceptableHeaders = ["x-chromelogger-data"];
- /**
- * This object represents HTTP events observer. It's intended to be
- * used in e10s enabled browser only.
- *
- * Since child processes can't register HTTP event observer they use
- * this module to do the observing in the parent process. This monitor
- * is loaded through DebuggerServerConnection.setupInParent() that is
- * executed from within the child process. The execution is done by
- * {@ServerLoggingListener}. The monitor listens to HTTP events and
- * forwards it into the right child process.
- *
- * Read more about the architecture:
- * https://github.com/mozilla/gecko-dev/blob/fx-team/devtools/server/docs/actor-e10s-handling.md
- */
- var ServerLoggerMonitor = {
- // Initialization
- initialize: function () {
- this.onChildMessage = this.onChildMessage.bind(this);
- this.onExamineResponse = this.onExamineResponse.bind(this);
- // Set of registered child frames (loggers).
- this.targets = new Set();
- },
- // Parent Child Relationship
- attach: makeInfallible(function ({ mm, prefix }) {
- trace.log("ServerLoggerMonitor.attach; ", arguments);
- let setMessageManager = newMM => {
- if (mm) {
- mm.removeMessageListener("debug:server-logger", this.onChildMessage);
- }
- mm = newMM;
- if (mm) {
- mm.addMessageListener("debug:server-logger", this.onChildMessage);
- }
- };
- // Start listening for messages from the {@ServerLogger} actor
- // living in the child process.
- setMessageManager(mm);
- return {
- onBrowserSwap: setMessageManager,
- onDisconnected: () => {
- trace.log("ServerLoggerMonitor.onDisconnectChild; ", arguments);
- setMessageManager(null);
- }
- };
- }),
- // Child Message Handling
- onChildMessage: function (msg) {
- let method = msg.data.method;
- trace.log("ServerLoggerMonitor.onChildMessage; ", method, msg);
- switch (method) {
- case "attachChild":
- return this.onAttachChild(msg);
- case "detachChild":
- return this.onDetachChild(msg);
- default:
- trace.log("Unknown method name: ", method);
- return undefined;
- }
- },
- onAttachChild: function (event) {
- let target = event.target;
- let size = this.targets.size;
- trace.log("ServerLoggerMonitor.onAttachChild; size: ", size, target);
- // If this is the first child attached, register global HTTP observer.
- if (!size) {
- trace.log("ServerLoggerMonitor.onAttatchChild; Add HTTP Observer");
- Services.obs.addObserver(this.onExamineResponse,
- "http-on-examine-response", false);
- }
- // Collect child loggers. The frame element where the
- // window/document lives.
- this.targets.add(target);
- },
- onDetachChild: function (event) {
- let target = event.target;
- this.targets.delete(target);
- let size = this.targets.size;
- trace.log("ServerLoggerMonitor.onDetachChild; size: ", size, target);
- // If this is the last child process attached, unregister
- // the global HTTP observer.
- if (!size) {
- trace.log("ServerLoggerMonitor.onDetachChild; Remove HTTP Observer");
- Services.obs.removeObserver(this.onExamineResponse,
- "http-on-examine-response", false);
- }
- },
- // HTTP Observer
- onExamineResponse: makeInfallible(function (subject, topic) {
- let httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
- trace.log("ServerLoggerMonitor.onExamineResponse; ", httpChannel.name,
- this.targets);
- // Ignore requests from chrome or add-on code when we are monitoring
- // content.
- if (!httpChannel.loadInfo &&
- httpChannel.loadInfo.loadingDocument === null &&
- httpChannel.loadInfo.loadingPrincipal ===
- Services.scriptSecurityManager.getSystemPrincipal()) {
- return;
- }
- let requestFrame = NetworkHelper.getTopFrameForRequest(httpChannel);
- if (!requestFrame) {
- return;
- }
- // Ignore requests from parent frames that aren't registered.
- if (!this.targets.has(requestFrame)) {
- return;
- }
- let headers = [];
- httpChannel.visitResponseHeaders((header, value) => {
- header = header.toLowerCase();
- if (acceptableHeaders.indexOf(header) !== -1) {
- headers.push({header: header, value: value});
- }
- });
- if (!headers.length) {
- return;
- }
- let { messageManager } = requestFrame;
- messageManager.sendAsyncMessage("debug:server-logger", {
- method: "examineHeaders",
- headers: headers,
- });
- trace.log("ServerLoggerMonitor.onExamineResponse; headers ",
- headers.length, ", ", headers);
- }),
- };
- /**
- * Executed automatically by the framework.
- */
- function setupParentProcess(event) {
- return ServerLoggerMonitor.attach(event);
- }
- // Monitor initialization.
- ServerLoggerMonitor.initialize();
- // Exports from this module
- exports.setupParentProcess = setupParentProcess;
|