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 15 kB image not shown  

Quelle  test_range_requests.js   Sprache: JAVA

 
//
// This test makes sure range-requests are sent and treated the way we want
// See bug #612135 for a thorough discussion on the subject
//
// Necko does a range-request for a partial cache-entry iff
//
//   1) size of the cached entry < value of the cached Content-Length header
//      (not tested here - see bug #612135 comments 108-110)
//   2) the size of the cached entry is > 0  (see bug #628607)
//   3) the cached entry does not have a "no-store" Cache-Control header
//   4) the cached entry does not have a Content-Encoding (see bug #613159)
//   5) the request does not have a conditional-request header set by client
//   6) nsHttpResponseHead::IsResumable() is true for the cached entry
//   7) a basic positive test that makes sure byte ranges work
//   8) ensure NS_ERROR_CORRUPTED_CONTENT is thrown when total entity size
//      of 206 does not match content-length of 200
//
//  The test has one handler for each case and run_tests() fires one request
//  for each. None of the handlers should see a Range-header.

"use strict";

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

var httpserver = null;

const clearTextBody = "This is a slightly longer test\n";
const encodedBody = [
  0x1f, 0x8b, 0x08, 0x08, 0xef, 0x70, 0xe6, 0x4c, 0x00, 0x03, 0x74, 0x65, 0x78,
  0x74, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x74, 0x78, 0x74, 0x00, 0x0b, 0xc9, 0xc8,
  0x2c, 0x56, 0x00, 0xa2, 0x44, 0x85, 0xe2, 0x9c, 0xcc, 0xf4, 0x8c, 0x92, 0x9c,
  0x4a, 0x85, 0x9c, 0xfc, 0xbc, 0xf4, 0xd4, 0x22, 0x85, 0x92, 0xd4, 0xe2, 0x12,
  0x2e, 0x2e, 0x00, 0x00, 0xe5, 0xe6, 0xf0, 0x20, 0x00, 0x00, 0x00,
];

const partial_data_length = 4;
var port = null// set in run_test

function make_channel(url) {
  return NetUtil.newChannel({
    uri: url,
    loadUsingSystemPrincipal: true,
  }).QueryInterface(Ci.nsIHttpChannel);
}

// StreamListener which cancels its request on first data available
function Canceler(continueFn) {
  this.continueFn = continueFn;
}
Canceler.prototype = {
  QueryInterface: ChromeUtils.generateQI([
    "nsIStreamListener",
    "nsIRequestObserver",
  ]),
  onStartRequest() {},

  onDataAvailable(request, stream, offset, count) {
    // Read stream so we don't assert for not reading from the stream
    // if cancelling the channel is slow.
    read_stream(stream, count);

    request.QueryInterface(Ci.nsIChannel).cancel(Cr.NS_BINDING_ABORTED);
  },
  onStopRequest(request, status) {
    Assert.equal(status, Cr.NS_BINDING_ABORTED);
    this.continueFn(request, null);
  },
};
// Simple StreamListener which performs no validations
function MyListener(continueFn) {
  this.continueFn = continueFn;
  this._buffer = null;
}
MyListener.prototype = {
  QueryInterface: ChromeUtils.generateQI([
    "nsIStreamListener",
    "nsIRequestObserver",
  ]),
  onStartRequest() {
    this._buffer = "";
  },

  onDataAvailable(request, stream, offset, count) {
    this._buffer = this._buffer.concat(read_stream(stream, count));
  },
  onStopRequest(request) {
    this.continueFn(request, this._buffer);
  },
};

var case_8_range_request = false;
function FailedChannelListener(continueFn) {
  this.continueFn = continueFn;
}
FailedChannelListener.prototype = {
  QueryInterface: ChromeUtils.generateQI([
    "nsIStreamListener",
    "nsIRequestObserver",
  ]),
  onStartRequest() {},

  onDataAvailable(request, stream, offset, count) {
    read_stream(stream, count);
  },

  onStopRequest(request, status) {
    if (case_8_range_request) {
      Assert.equal(status, Cr.NS_ERROR_CORRUPTED_CONTENT);
    }
    this.continueFn(request, null);
  },
};

function received_cleartext(request, data) {
  Assert.equal(clearTextBody, data);
  testFinished();
}

function setStdHeaders(response, length) {
  response.setHeader("Content-Type""text/plain"false);
  response.setHeader("ETag""Just testing");
  response.setHeader("Cache-Control""max-age: 360000");
  response.setHeader("Accept-Ranges""bytes");
  response.setHeader("Content-Length""" + length);
}

function handler_2(metadata, response) {
  setStdHeaders(response, clearTextBody.length);
  Assert.ok(!metadata.hasHeader("Range"));
  response.bodyOutputStream.write(clearTextBody, clearTextBody.length);
}
function received_partial_2(request, data) {
  Assert.equal(data, undefined);
  var chan = make_channel("http://localhost:" + port + "/test_2");
  chan.asyncOpen(new ChannelListener(received_cleartext, null));
}

var case_3_request_no = 0;
function handler_3(metadata, response) {
  var body = clearTextBody;
  setStdHeaders(response, body.length);
  response.setHeader("Cache-Control""no-store"false);
  switch (case_3_request_no) {
    case 0:
      Assert.ok(!metadata.hasHeader("Range"));
      body = body.slice(0, partial_data_length);
      response.processAsync();
      response.bodyOutputStream.write(body, body.length);
      response.finish();
      break;
    case 1:
      Assert.ok(!metadata.hasHeader("Range"));
      response.bodyOutputStream.write(body, body.length);
      break;
    default:
      response.setStatusLine(metadata.httpVersion, 404, "Not Found");
  }
  case_3_request_no++;
}
function received_partial_3(request, data) {
  Assert.equal(partial_data_length, data.length);
  var chan = make_channel("http://localhost:" + port + "/test_3");
  chan.asyncOpen(new ChannelListener(received_cleartext, null));
}

var case_4_request_no = 0;
function handler_4(metadata, response) {
  switch (case_4_request_no) {
    case 0:
      Assert.ok(!metadata.hasHeader("Range"));
      var body = encodedBody;
      setStdHeaders(response, body.length);
      response.setHeader("Content-Encoding""gzip"false);
      body = body.slice(0, partial_data_length);
      var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(
        Ci.nsIBinaryOutputStream
      );
      bos.setOutputStream(response.bodyOutputStream);
      response.processAsync();
      bos.writeByteArray(body);
      response.finish();
      break;
    case 1:
      Assert.ok(!metadata.hasHeader("Range"));
      setStdHeaders(response, clearTextBody.length);
      response.bodyOutputStream.write(clearTextBody, clearTextBody.length);
      break;
    default:
      response.setStatusLine(metadata.httpVersion, 404, "Not Found");
  }
  case_4_request_no++;
}
function received_partial_4() {
  // checking length does not work with encoded data
  //  do_check_eq(partial_data_length, data.length);
  var chan = make_channel("http://localhost:" + port + "/test_4");
  chan.asyncOpen(new MyListener(received_cleartext));
}

var case_5_request_no = 0;
function handler_5(metadata, response) {
  var body = clearTextBody;
  setStdHeaders(response, body.length);
  switch (case_5_request_no) {
    case 0:
      Assert.ok(!metadata.hasHeader("Range"));
      body = body.slice(0, partial_data_length);
      response.processAsync();
      response.bodyOutputStream.write(body, body.length);
      response.finish();
      break;
    case 1:
      Assert.ok(!metadata.hasHeader("Range"));
      response.bodyOutputStream.write(body, body.length);
      break;
    default:
      response.setStatusLine(metadata.httpVersion, 404, "Not Found");
  }
  case_5_request_no++;
}
function received_partial_5(request, data) {
  Assert.equal(partial_data_length, data.length);
  var chan = make_channel("http://localhost:" + port + "/test_5");
  chan.setRequestHeader("If-Match""Some eTag"false);
  chan.asyncOpen(new ChannelListener(received_cleartext, null));
}

var case_6_request_no = 0;
function handler_6(metadata, response) {
  switch (case_6_request_no) {
    case 0:
      Assert.ok(!metadata.hasHeader("Range"));
      var body = clearTextBody;
      setStdHeaders(response, body.length);
      response.setHeader("Accept-Ranges"""false);
      body = body.slice(0, partial_data_length);
      response.processAsync();
      response.bodyOutputStream.write(body, body.length);
      response.finish();
      break;
    case 1:
      Assert.ok(!metadata.hasHeader("Range"));
      setStdHeaders(response, clearTextBody.length);
      response.bodyOutputStream.write(clearTextBody, clearTextBody.length);
      break;
    default:
      response.setStatusLine(metadata.httpVersion, 404, "Not Found");
  }
  case_6_request_no++;
}
function received_partial_6(request, data) {
  // would like to verify that the response does not have Accept-Ranges
  Assert.equal(partial_data_length, data.length);
  var chan = make_channel("http://localhost:" + port + "/test_6");
  chan.asyncOpen(new ChannelListener(received_cleartext, null));
}

const simpleBody = "0123456789";

function received_simple(request, data) {
  Assert.equal(simpleBody, data);
  testFinished();
}

var case_7_request_no = 0;
function handler_7(metadata, response) {
  switch (case_7_request_no) {
    case 0:
      Assert.ok(!metadata.hasHeader("Range"));
      response.setHeader("Content-Type""text/plain"false);
      response.setHeader("ETag""test7Etag");
      response.setHeader("Accept-Ranges""bytes");
      response.setHeader("Cache-Control""max-age=360000");
      response.setHeader("Content-Length""10");
      response.processAsync();
      response.bodyOutputStream.write(simpleBody.slice(0, 4), 4);
      response.finish();
      break;
    case 1:
      response.setHeader("Content-Type""text/plain"false);
      response.setHeader("ETag""test7Etag");
      if (metadata.hasHeader("Range")) {
        Assert.ok(metadata.hasHeader("If-Range"));
        response.setStatusLine(metadata.httpVersion, 206, "Partial Content");
        response.setHeader("Content-Range""4-9/10");
        response.setHeader("Content-Length""6");
        response.bodyOutputStream.write(simpleBody.slice(4), 6);
      } else {
        response.setHeader("Content-Length""10");
        response.bodyOutputStream.write(simpleBody, 10);
      }
      break;
    default:
      response.setStatusLine(metadata.httpVersion, 404, "Not Found");
  }
  case_7_request_no++;
}
function received_partial_7(request, data) {
  // make sure we get the first 4 bytes
  Assert.equal(4, data.length);
  // do it again to get the rest
  var chan = make_channel("http://localhost:" + port + "/test_7");
  chan.asyncOpen(new ChannelListener(received_simple, null));
}

var case_8_request_no = 0;
function handler_8(metadata, response) {
  switch (case_8_request_no) {
    case 0:
      Assert.ok(!metadata.hasHeader("Range"));
      response.setHeader("Content-Type""text/plain"false);
      response.setHeader("ETag""test8Etag");
      response.setHeader("Accept-Ranges""bytes");
      response.setHeader("Cache-Control""max-age=360000");
      response.setHeader("Content-Length""10");
      response.processAsync();
      response.bodyOutputStream.write(simpleBody.slice(0, 4), 4);
      response.finish();
      break;
    case 1:
      if (metadata.hasHeader("Range")) {
        Assert.ok(metadata.hasHeader("If-Range"));
        case_8_range_request = true;
      }
      response.setStatusLine(metadata.httpVersion, 206, "Partial Content");
      response.setHeader("Content-Type""text/plain"false);
      response.setHeader("ETag""test8Etag");
      response.setHeader("Content-Range""4-8/9"); // intentionally broken
      response.setHeader("Content-Length""5");
      response.bodyOutputStream.write(simpleBody.slice(4), 5);
      break;
    default:
      response.setStatusLine(metadata.httpVersion, 404, "Not Found");
  }
  case_8_request_no++;
}
function received_partial_8(request, data) {
  // make sure we get the first 4 bytes
  Assert.equal(4, data.length);
  // do it again to get the rest
  var chan = make_channel("http://localhost:" + port + "/test_8");
  chan.asyncOpen(
    new FailedChannelListener(testFinished, null, CL_EXPECT_LATE_FAILURE)
  );
}

var case_9_request_no = 0;
function handler_9(metadata, response) {
  switch (case_9_request_no) {
    case 0:
      Assert.ok(!metadata.hasHeader("Range"));
      response.setHeader("Content-Type""text/plain"false);
      response.setHeader("ETag""W/test9WeakEtag");
      response.setHeader("Accept-Ranges""bytes");
      response.setHeader("Cache-Control""max-age=360000");
      response.setHeader("Content-Length""10");
      response.processAsync();
      response.bodyOutputStream.write(simpleBody.slice(0, 4), 4);
      response.finish(); // truncated response
      break;
    case 1:
      Assert.ok(!metadata.hasHeader("Range"));
      response.setHeader("Content-Type""text/plain"false);
      response.setHeader("ETag""W/test9WeakEtag");
      response.setHeader("Accept-Ranges""bytes");
      response.setHeader("Cache-Control""max-age=360000");
      response.setHeader("Content-Length""10");
      response.processAsync();
      response.bodyOutputStream.write(simpleBody, 10);
      response.finish(); // full response
      break;
    default:
      response.setStatusLine(metadata.httpVersion, 404, "Not Found");
  }
  case_9_request_no++;
}
function received_partial_9(request, data) {
  Assert.equal(partial_data_length, data.length);
  var chan = make_channel("http://localhost:" + port + "/test_9");
  chan.asyncOpen(new ChannelListener(received_simple, null));
}

// Simple mechanism to keep track of tests and stop the server
var numTestsFinished = 0;
function testFinished() {
  if (++numTestsFinished == 7) {
    httpserver.stop(do_test_finished);
  }
}

function run_test() {
  httpserver = new HttpServer();
  httpserver.registerPathHandler("/test_2", handler_2);
  httpserver.registerPathHandler("/test_3", handler_3);
  httpserver.registerPathHandler("/test_4", handler_4);
  httpserver.registerPathHandler("/test_5", handler_5);
  httpserver.registerPathHandler("/test_6", handler_6);
  httpserver.registerPathHandler("/test_7", handler_7);
  httpserver.registerPathHandler("/test_8", handler_8);
  httpserver.registerPathHandler("/test_9", handler_9);
  httpserver.start(-1);

  port = httpserver.identity.primaryPort;

  // wipe out cached content
  evict_cache_entries();

  // Case 2: zero-length partial entry must not trigger range-request
  let chan = make_channel("http://localhost:" + port + "/test_2");
  chan.asyncOpen(new Canceler(received_partial_2));

  // Case 3: no-store response must not trigger range-request
  chan = make_channel("http://localhost:" + port + "/test_3");
  chan.asyncOpen(new MyListener(received_partial_3));

  // Case 4: response with content-encoding must not trigger range-request
  chan = make_channel("http://localhost:" + port + "/test_4");
  chan.asyncOpen(new MyListener(received_partial_4));

  // Case 5: conditional request-header set by client
  chan = make_channel("http://localhost:" + port + "/test_5");
  chan.asyncOpen(new MyListener(received_partial_5));

  // Case 6: response is not resumable (drop the Accept-Ranges header)
  chan = make_channel("http://localhost:" + port + "/test_6");
  chan.asyncOpen(new MyListener(received_partial_6));

  // Case 7: a basic positive test
  chan = make_channel("http://localhost:" + port + "/test_7");
  chan.asyncOpen(new MyListener(received_partial_7));

  // Case 8: check that mismatched 206 and 200 sizes throw error
  chan = make_channel("http://localhost:" + port + "/test_8");
  chan.asyncOpen(new MyListener(received_partial_8));

  // Case 9: check that weak etag is not used for a range request
  chan = make_channel("http://localhost:" + port + "/test_9");
  chan.asyncOpen(new MyListener(received_partial_9));

  do_test_pending();
}

Messung V0.5
C=89 H=88 G=88

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

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