<commit_before>'use strict';

var EventEmitter = require('eventemitter3')
  , listeners = require('loads')
  , send = require('xhr-send')
  , hang = require('hang')
  , AXO = require('axo');

/**
 * Optionally get a configuration value somewhere.
 *
 * @param {Object} options Optional configuration that needs default properties.
 * @api private
 */
function optional(options) {
  for (var key in Requests.defaults) {
    options[key] = key in options ? options[key] : Requests.defaults[key];
  }

  return options;
}

/**
 * RequestS(tream).
 *
 * Options:
 *
 * - streaming: Should the request be streaming.
 * - method: Which HTTP method should be used.
 * - headers: Additional request headers.
 * - mode: Enable CORS mode.
 * - body: The payload for the request.
 *
 * @constructor
 * @param {String} url The URL we want to request.
 * @param {Object} options Various of request options.
 * @api public
 */
function Requests(url, options) {
  if (!(this instanceof Requests)) return new Requests(url, options);
  options = optional(options || {});

  this.offset = 0;
  this.id = ++Requests.requested;
  this.streaming = options.streaming;
  this.socket = Requests[Requests.method](options);

  //
  // Open the socket BEFORE adding any properties to the instance as this might
  // trigger a thrown `InvalidStateError: An attempt was made to use an object
  // that is not, or is no longer, usable` error in FireFox:
  //
  // @see https://bugzilla.mozilla.org/show_bug.cgi?id=707484
  //
  this.socket.open(options.method.toUpperCase(), url, true);

  //
  // We want to implement a stream like interface on top of this module so it
  // can be used to read streaming data in node as well as through browserify.
  //
  this.readable = true;
  this.writable = false;

  //
  // Register this as an active HTTP request.
  //
  Requests.active[this.id] = this;
  if (!options.manual) this.open(options);
}

Requests.prototype = new EventEmitter();
Requests.prototype.constructor = Requests;

/**
 * Initialize and start requesting the supplied resource.
 *
 * @param {Object} options Passed in defaults.
 * @api private
 */
Requests.prototype.open = function open(options) {
  var what
    , requests = this
    , socket = requests.socket;

  requests.on('stream', function stream(data) {
    if (socket.multipart) return requests.emit('data', data);

    //
    // Please note that we need to use a method here that works on both string
    // as well as ArrayBuffer's as we have no certainty that we're receiving
    // text.
    //
    var chunk = data.slice(requests.offset);
    requests.offset = data.length;

    requests.emit('data', chunk);
  });

  requests.on('end', function cleanup() {
    delete Requests.active[requests.id];
  });

  if (options.timeout) {
    socket.timeout = +options.time;
  }

  if ('cors' === options.mode.toLowerCase() && 'withCredentials' in socket) {
    socket.withCredentials = true;
  }

  //
  // We want to prevent pre-flight requests by default for CORS requests so we
  // need to force the content-type to text/plain.
  //
  requests.header('Content-Type', 'text/plain');
  for (what in options.headers) {
    requests.header(what, options.headers[what]);
  }

  //
  // Set the correct responseType method.
  //
  if (requests.streaming) {
    if ('string' === typeof options.body) {
      if ('multipart' in socket) {
        socket.multipart = true;
      } else if (Requests.type.mozchunkedtext) {
        socket.responseType = 'moz-chunked-text';
      } else if (Requests.type.msstream) {<commit_msg>[fix] Force string mode if we're not sending data<commit_after>'use strict';

var EventEmitter = require('eventemitter3')
  , listeners = require('loads')
  , send = require('xhr-send')
  , hang = require('hang')
  , AXO = require('axo');

/**
 * Optionally get a configuration value somewhere.
 *
 * @param {Object} options Optional configuration that needs default properties.
 * @api private
 */
function optional(options) {
  for (var key in Requests.defaults) {
    options[key] = key in options ? options[key] : Requests.defaults[key];
  }

  return options;
}

/**
 * RequestS(tream).
 *
 * Options:
 *
 * - streaming: Should the request be streaming.
 * - method: Which HTTP method should be used.
 * - headers: Additional request headers.
 * - mode: Enable CORS mode.
 * - body: The payload for the request.
 *
 * @constructor
 * @param {String} url The URL we want to request.
 * @param {Object} options Various of request options.
 * @api public
 */
function Requests(url, options) {
  if (!(this instanceof Requests)) return new Requests(url, options);
  options = optional(options || {});

  this.offset = 0;
  this.id = ++Requests.requested;
  this.streaming = options.streaming;
  this.socket = Requests[Requests.method](options);

  //
  // Open the socket BEFORE adding any properties to the instance as this might
  // trigger a thrown `InvalidStateError: An attempt was made to use an object
  // that is not, or is no longer, usable` error in FireFox:
  //
  // @see https://bugzilla.mozilla.org/show_bug.cgi?id=707484
  //
  this.socket.open(options.method.toUpperCase(), url, true);

  //
  // We want to implement a stream like interface on top of this module so it
  // can be used to read streaming data in node as well as through browserify.
  //
  this.readable = true;
  this.writable = false;

  //
  // Register this as an active HTTP request.
  //
  Requests.active[this.id] = this;
  if (!options.manual) this.open(options);
}

Requests.prototype = new EventEmitter();
Requests.prototype.constructor = Requests;

/**
 * Initialize and start requesting the supplied resource.
 *
 * @param {Object} options Passed in defaults.
 * @api private
 */
Requests.prototype.open = function open(options) {
  var what
    , requests = this
    , socket = requests.socket;

  requests.on('stream', function stream(data) {
    if (socket.multipart) return requests.emit('data', data);

    //
    // Please note that we need to use a method here that works on both string
    // as well as ArrayBuffer's as we have no certainty that we're receiving
    // text.
    //
    var chunk = data.slice(requests.offset);
    requests.offset = data.length;

    requests.emit('data', chunk);
  });

  requests.on('end', function cleanup() {
    delete Requests.active[requests.id];
  });

  if (options.timeout) {
    socket.timeout = +options.time;
  }

  if ('cors' === options.mode.toLowerCase() && 'withCredentials' in socket) {
    socket.withCredentials = true;
  }

  //
  // We want to prevent pre-flight requests by default for CORS requests so we
  // need to force the content-type to text/plain.
  //
  requests.header('Content-Type', 'text/plain');
  for (what in options.headers) {
    requests.header(what, options.headers[what]);
  }

  //
  // Set the correct responseType method.
  //
  if (requests.streaming) {
    if (!options.body || 'string' === typeof options.body) {
      if ('multipart' in socket) {
        socket.multipart = true;
      } else if (Requests.type.mozchunkedtext) {
        socket.responseType = 'moz-chunked-text';
      } else if (Requests.type.msstream) {
{'fraction_non_alphanumeric': 0.12843397015757912, 'fraction_numerical': 0.0022312090363965976, 'mean_word_length': 3.145664739884393, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2578522', 'n_tokens_mistral': 2166, 'n_tokens_neox': 2125, 'n_words': 693}