Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/netwerk/test/unit/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  test_proxyconnect.js   Sprache: JAVA

 
/* -*- 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/. */


// test_connectonly tests happy path of proxy connect
// 1. CONNECT to localhost:socketserver_port
// 2. Write 200 Connection established
// 3. Write data to the tunnel (and read server-side)
// 4. Read data from the tunnel (and write server-side)
// 5. done
// test_connectonly_noproxy tests an http channel with only connect set but
// no proxy configured.
// 1. OnTransportAvailable callback NOT called (checked in step 2)
// 2. StopRequest callback called
// 3. done
// test_connectonly_nonhttp tests an http channel with only connect set with a
// non-http proxy.
// 1. OnTransportAvailable callback NOT called (checked in step 2)
// 2. StopRequest callback called
// 3. done

// -1 then initialized with an actual port from the serversocket
"use strict";

var socketserver_port = -1;

const CC = Components.Constructor;
const ServerSocket = CC(
  "@mozilla.org/network/server-socket;1",
  "nsIServerSocket",
  "init"
);
const BinaryInputStream = CC(
  "@mozilla.org/binaryinputstream;1",
  "nsIBinaryInputStream",
  "setInputStream"
);
const BinaryOutputStream = CC(
  "@mozilla.org/binaryoutputstream;1",
  "nsIBinaryOutputStream",
  "setOutputStream"
);

const STATE_NONE = 0;
const STATE_READ_CONNECT_REQUEST = 1;
const STATE_WRITE_CONNECTION_ESTABLISHED = 2;
const STATE_CHECK_WRITE = 3; // write to the tunnel
const STATE_CHECK_WRITE_READ = 4; // wrote to the tunnel, check connection data
const STATE_CHECK_READ = 5; // read from the tunnel
const STATE_CHECK_READ_WROTE = 6; // wrote to connection, check tunnel data
const STATE_COMPLETED = 100;

const CONNECT_RESPONSE_STRING = "HTTP/1.1 200 Connection established\r\n\r\n";
const CHECK_WRITE_STRING = "hello";
const CHECK_READ_STRING = "world";
const ALPN = "webrtc";

var connectRequest = "";
var checkWriteData = "";
var checkReadData = "";

var threadManager;
var socket;
var streamIn;
var streamOut;
var accepted = false;
var acceptedSocket;
var state = STATE_NONE;
var transportAvailable = false;
var proxiedChannel;
var listener = {
  expectedCode: -1, // uninitialized

  onStartRequest: function test_onStartR() {},

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

  onStopRequest: function test_onStopR(request, status) {
    if (state === STATE_COMPLETED) {
      Assert.equal(transportAvailable, false"transport available not called");
      Assert.equal(status, 0x80004005, "error code matches");
      Assert.equal(proxiedChannel.httpProxyConnectResponseCode, 200);
      nextTest();
      return;
    }

    Assert.equal(accepted, true"socket accepted");
    accepted = false;
  },
};

var upgradeListener = {
  onTransportAvailable: (transport, socketIn, socketOut) => {
    if (!transport || !socketIn || !socketOut) {
      do_throw("on transport available failed");
    }

    if (state !== STATE_CHECK_WRITE) {
      do_throw("bad state");
    }

    transportAvailable = true;

    socketIn.asyncWait(connectHandler, 0, 0, threadManager.mainThread);
    socketOut.asyncWait(connectHandler, 0, 0, threadManager.mainThread);
  },
  QueryInterface: ChromeUtils.generateQI(["nsIHttpUpgradeListener"]),
};

var connectHandler = {
  onInputStreamReady: input => {
    try {
      const bis = new BinaryInputStream(input);
      var data = bis.readByteArray(input.available());

      dataAvailable(data);

      if (state !== STATE_COMPLETED) {
        input.asyncWait(connectHandler, 0, 0, threadManager.mainThread);
      }
    } catch (e) {
      do_throw(e);
    }
  },
  onOutputStreamReady: output => {
    writeData(output);
  },
  QueryInterface: iid => {
    if (
      iid.equals(Ci.nsISupports) ||
      iid.equals(Ci.nsIInputStreamCallback) ||
      iid.equals(Ci.nsIOutputStreamCallback)
    ) {
      return this;
    }
    throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
  },
};

function dataAvailable(data) {
  switch (state) {
    case STATE_READ_CONNECT_REQUEST:
      connectRequest += String.fromCharCode.apply(String, data);
      const headerEnding = connectRequest.indexOf("\r\n\r\n");
      const alpnHeaderIndex = connectRequest.indexOf(`ALPN: ${ALPN}`);

      if (headerEnding != -1) {
        const requestLine = `CONNECT localhost:${socketserver_port} HTTP/1.1`;
        Assert.equal(connectRequest.indexOf(requestLine), 0, "connect request");
        Assert.equal(headerEnding, connectRequest.length - 4, "req head only");
        Assert.notEqual(alpnHeaderIndex, -1, "alpn header found");

        state = STATE_WRITE_CONNECTION_ESTABLISHED;
        streamOut.asyncWait(connectHandler, 0, 0, threadManager.mainThread);
      }

      break;
    case STATE_CHECK_WRITE_READ:
      checkWriteData += String.fromCharCode.apply(String, data);

      if (checkWriteData.length >= CHECK_WRITE_STRING.length) {
        Assert.equal(checkWriteData, CHECK_WRITE_STRING, "correct write data");

        state = STATE_CHECK_READ;
        streamOut.asyncWait(connectHandler, 0, 0, threadManager.mainThread);
      }

      break;
    case STATE_CHECK_READ_WROTE:
      checkReadData += String.fromCharCode.apply(String, data);

      if (checkReadData.length >= CHECK_READ_STRING.length) {
        Assert.equal(checkReadData, CHECK_READ_STRING, "correct read data");

        state = STATE_COMPLETED;

        streamIn.asyncWait(null, 0, 0, null);
        acceptedSocket.close(0);

        nextTest();
      }

      break;
    default:
      do_throw("bad state: " + state);
  }
}

function writeData(output) {
  let bos = new BinaryOutputStream(output);

  switch (state) {
    case STATE_WRITE_CONNECTION_ESTABLISHED:
      bos.write(CONNECT_RESPONSE_STRING, CONNECT_RESPONSE_STRING.length);
      state = STATE_CHECK_WRITE;
      break;
    case STATE_CHECK_READ:
      bos.write(CHECK_READ_STRING, CHECK_READ_STRING.length);
      state = STATE_CHECK_READ_WROTE;
      break;
    case STATE_CHECK_WRITE:
      bos.write(CHECK_WRITE_STRING, CHECK_WRITE_STRING.length);
      state = STATE_CHECK_WRITE_READ;
      break;
    default:
      do_throw("bad state: " + state);
  }
}

function makeChan(url) {
  if (!url) {
    url = "https://localhost:" + socketserver_port + "/";
  }

  var flags =
    Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL |
    Ci.nsILoadInfo.SEC_DONT_FOLLOW_REDIRECTS |
    Ci.nsILoadInfo.SEC_COOKIES_OMIT;

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

  var internal = chan.QueryInterface(Ci.nsIHttpChannelInternal);
  internal.HTTPUpgrade(ALPN, upgradeListener);
  internal.setConnectOnly(false);

  return chan;
}

function socketAccepted(socket1, transport) {
  accepted = true;

  // copied from httpd.js
  const SEGMENT_SIZE = 8192;
  const SEGMENT_COUNT = 1024;

  switch (state) {
    case STATE_NONE:
      state = STATE_READ_CONNECT_REQUEST;
      break;
    default:
      return;
  }

  acceptedSocket = transport;

  try {
    streamIn = transport
      .openInputStream(0, SEGMENT_SIZE, SEGMENT_COUNT)
      .QueryInterface(Ci.nsIAsyncInputStream);
    streamOut = transport
      .openOutputStream(0, 0, 0)
      .QueryInterface(Ci.nsIAsyncOutputStream);

    streamIn.asyncWait(connectHandler, 0, 0, threadManager.mainThread);
  } catch (e) {
    transport.close(Cr.NS_BINDING_ABORTED);
    do_throw(e);
  }
}

function stopListening() {
  if (tests && tests.length !== 0 && do_throw) {
    do_throw("should never stop");
  }
}

function createProxy() {
  try {
    threadManager = Cc["@mozilla.org/thread-manager;1"].getService();

    socket = new ServerSocket(-1, true, 1);
    socketserver_port = socket.port;

    socket.asyncListen({
      onSocketAccepted: socketAccepted,
      onStopListening: stopListening,
    });
  } catch (e) {
    do_throw(e);
  }
}

function test_connectonly() {
  Services.prefs.setCharPref("network.proxy.ssl""localhost");
  Services.prefs.setIntPref("network.proxy.ssl_port", socketserver_port);
  Services.prefs.setBoolPref("network.proxy.allow_hijacking_localhost"true);
  Services.prefs.setIntPref("network.proxy.type", 1);

  var chan = makeChan();
  proxiedChannel = chan.QueryInterface(Ci.nsIProxiedChannel);
  chan.asyncOpen(listener);

  do_test_pending();
}

function test_connectonly_noproxy() {
  clearPrefs();
  var chan = makeChan();
  chan.asyncOpen(listener);

  do_test_pending();
}

function test_connectonly_nonhttp() {
  clearPrefs();

  Services.prefs.setCharPref("network.proxy.socks""localhost");
  Services.prefs.setIntPref("network.proxy.socks_port", socketserver_port);
  Services.prefs.setBoolPref("network.proxy.allow_hijacking_localhost"true);
  Services.prefs.setIntPref("network.proxy.type", 1);

  var chan = makeChan();
  chan.asyncOpen(listener);

  do_test_pending();
}

function nextTest() {
  transportAvailable = false;

  if (!tests.length) {
    do_test_finished();
    return;
  }

  tests.shift()();
  do_test_finished();
}

var tests = [
  test_connectonly,
  test_connectonly_noproxy,
  test_connectonly_nonhttp,
];

function clearPrefs() {
  Services.prefs.clearUserPref("network.proxy.ssl");
  Services.prefs.clearUserPref("network.proxy.ssl_port");
  Services.prefs.clearUserPref("network.proxy.socks");
  Services.prefs.clearUserPref("network.proxy.socks_port");
  Services.prefs.clearUserPref("network.proxy.allow_hijacking_localhost");
  Services.prefs.clearUserPref("network.proxy.type");
}

function run_test() {
  createProxy();

  registerCleanupFunction(clearPrefs);

  nextTest();
  do_test_pending();
}

Messung V0.5
C=93 H=90 G=91

¤ Dauer der Verarbeitung: 0.12 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.