Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  test_httpcancel.js   Sprache: JAVA

 
// This file ensures that canceling a channel early does not
// send the request to the server (bug 350790)
//
// I've also shoehorned in a test that ENSURE_CALLED_BEFORE_CONNECT works as
// expected: see comments that start with ENSURE_CALLED_BEFORE_CONNECT:
//
// This test also checks that cancelling a channel before asyncOpen, after
// onStopRequest, or during onDataAvailable works as expected.

"use strict";

const { HttpServer } = ChromeUtils.importESModule(
  "resource://testing-common/httpd.sys.mjs"
);
const reason = "testing";

function inChildProcess() {
  return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
}

var ios = Services.io;
var ReferrerInfo = Components.Constructor(
  "@mozilla.org/referrer-info;1",
  "nsIReferrerInfo",
  "init"
);
var observer = {
  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),

  observe(subject) {
    subject = subject.QueryInterface(Ci.nsIRequest);
    subject.cancelWithReason(Cr.NS_BINDING_ABORTED, reason);

    // ENSURE_CALLED_BEFORE_CONNECT: setting values should still work
    try {
      subject.QueryInterface(Ci.nsIHttpChannel);
      let currentReferrer = subject.getRequestHeader("Referer");
      Assert.equal(currentReferrer, "http://site1.com/");
      var uri = ios.newURI("http://site2.com");
      subject.referrerInfo = new ReferrerInfo(
        Ci.nsIReferrerInfo.EMPTY,
        true,
        uri
      );
    } catch (ex) {
      do_throw("Exception: " + ex);
    }
  },
};

let cancelDuringOnStartListener = {
  onStartRequest: function test_onStartR(request) {
    Assert.equal(request.status, Cr.NS_BINDING_ABORTED);
    // We didn't sync the reason to child process.
    if (!inChildProcess()) {
      Assert.equal(request.canceledReason, reason);
    }

    // ENSURE_CALLED_BEFORE_CONNECT: setting referrer should now fail
    try {
      request.QueryInterface(Ci.nsIHttpChannel);
      let currentReferrer = request.getRequestHeader("Referer");
      Assert.equal(currentReferrer, "http://site2.com/");
      var uri = ios.newURI("http://site3.com/");

      // Need to set NECKO_ERRORS_ARE_FATAL=0 else we'll abort process
      Services.env.set("NECKO_ERRORS_ARE_FATAL""0");
      // we expect setting referrer to fail
      try {
        request.referrerInfo = new ReferrerInfo(
          Ci.nsIReferrerInfo.EMPTY,
          true,
          uri
        );
        do_throw("Error should have been thrown before getting here");
      } catch (ex) {}
    } catch (ex) {
      do_throw("Exception: " + ex);
    }
  },

  onDataAvailable: function test_ODA() {
    do_throw("Should not get any data!");
  },

  onStopRequest: function test_onStopR() {
    this.resolved();
  },
};

var cancelDuringOnDataListener = {
  data: "",
  channel: null,
  receivedSomeData: null,
  onStartRequest: function test_onStartR(request) {
    Assert.equal(request.status, Cr.NS_OK);
  },

  onDataAvailable: function test_ODA(request, stream, offset, count) {
    let string = NetUtil.readInputStreamToString(stream, count);
    Assert.ok(!string.includes("b"));
    this.data += string;
    this.channel.cancel(Cr.NS_BINDING_ABORTED);
    if (this.receivedSomeData) {
      this.receivedSomeData();
    }
  },

  onStopRequest: function test_onStopR(request) {
    Assert.ok(this.data.includes("a"), `data: ${this.data}`);
    Assert.equal(request.status, Cr.NS_BINDING_ABORTED);
    this.resolved();
  },
};

function makeChan(url) {
  var chan = NetUtil.newChannel({
    uri: url,
    loadUsingSystemPrincipal: true,
  }).QueryInterface(Ci.nsIHttpChannel);

  // ENSURE_CALLED_BEFORE_CONNECT: set original value
  var uri = ios.newURI("http://site1.com");
  chan.referrerInfo = new ReferrerInfo(Ci.nsIReferrerInfo.EMPTY, true, uri);
  return chan;
}

var httpserv = null;

add_task(async function setup() {
  httpserv = new HttpServer();
  httpserv.registerPathHandler("/failtest", failtest);
  httpserv.registerPathHandler("/cancel_middle", cancel_middle);
  httpserv.registerPathHandler("/normal_response", normal_response);
  httpserv.start(-1);

  registerCleanupFunction(async () => {
    await new Promise(resolve => httpserv.stop(resolve));
  });
});

add_task(async function test_cancel_during_onModifyRequest() {
  var chan = makeChan(
    "http://localhost:" + httpserv.identity.primaryPort + "/failtest"
  );

  if (!inChildProcess()) {
    Services.obs.addObserver(observer, "http-on-modify-request");
  } else {
    do_send_remote_message("register-observer");
    await do_await_remote_message("register-observer-done");
  }

  await new Promise(resolve => {
    cancelDuringOnStartListener.resolved = resolve;
    chan.asyncOpen(cancelDuringOnStartListener);
  });

  if (!inChildProcess()) {
    Services.obs.removeObserver(observer, "http-on-modify-request");
  } else {
    do_send_remote_message("unregister-observer");
    await do_await_remote_message("unregister-observer-done");
  }
});

add_task(async function test_cancel_before_asyncOpen() {
  var chan = makeChan(
    "http://localhost:" + httpserv.identity.primaryPort + "/failtest"
  );

  chan.cancel(Cr.NS_BINDING_ABORTED);

  Assert.throws(
    () => {
      chan.asyncOpen(cancelDuringOnStartListener);
    },
    /NS_BINDING_ABORTED/,
    "cannot open if already cancelled"
  );
});

add_task(async function test_cancel_during_onData() {
  var chan = makeChan(
    "http://localhost:" + httpserv.identity.primaryPort + "/cancel_middle"
  );

  await new Promise(resolve => {
    cancelDuringOnDataListener.resolved = resolve;
    cancelDuringOnDataListener.channel = chan;
    chan.asyncOpen(cancelDuringOnDataListener);
  });
});

var cancelAfterOnStopListener = {
  data: "",
  channel: null,
  onStartRequest: function test_onStartR(request) {
    Assert.equal(request.status, Cr.NS_OK);
  },

  onDataAvailable: function test_ODA(request, stream, offset, count) {
    let string = NetUtil.readInputStreamToString(stream, count);
    this.data += string;
  },

  onStopRequest: function test_onStopR(request) {
    info("onStopRequest");
    Assert.equal(request.status, Cr.NS_OK);
    this.resolved();
  },
};

add_task(async function test_cancel_after_onStop() {
  var chan = makeChan(
    "http://localhost:" + httpserv.identity.primaryPort + "/normal_response"
  );

  await new Promise(resolve => {
    cancelAfterOnStopListener.resolved = resolve;
    cancelAfterOnStopListener.channel = chan;
    chan.asyncOpen(cancelAfterOnStopListener);
  });
  Assert.equal(chan.status, Cr.NS_OK);

  // For now it's unclear if cancelling after onStop should throw,
  // silently fail, or overwrite the channel's status as we currently do.
  // See discussion in bug 1553083
  chan.cancel(Cr.NS_BINDING_ABORTED);
  Assert.equal(chan.status, Cr.NS_BINDING_ABORTED);
});

// PATHS

// /failtest
function failtest() {
  do_throw("This should not be reached");
}

function cancel_middle(metadata, response) {
  response.processAsync();
  response.setStatusLine(metadata.httpVersion, 200, "OK");
  let str1 = "a".repeat(128 * 1024);
  response.write(str1, str1.length);
  response.bodyOutputStream.flush();

  let p = new Promise(resolve => {
    cancelDuringOnDataListener.receivedSomeData = resolve;
  });
  p.then(() => {
    let str2 = "b".repeat(128 * 1024);
    response.write(str2, str2.length);
    response.finish();
  });
}

function normal_response(metadata, response) {
  response.setStatusLine(metadata.httpVersion, 200, "OK");
  let str1 = "Is this normal?";
  response.write(str1, str1.length);
}

Messung V0.5
C=92 H=97 G=94

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge