<commit_before>var express = require('express');
var http = require('http');
var WebSocketServer = require('ws').Server;
var EventEmitter = require('events').EventEmitter;
var util = require('./util');
var url = require('url');

function PeerKitServer(options) {
  if (!(this instanceof PeerKitServer)) return new PeerKitServer(options);
  EventEmitter.call(this);

  this._app = express();
  this._httpServer = http.createServer(this._app);

  this._options = util.extend({
    port: 8080,
    debug: true,
    multiplicity: 5
  }, options);

  util.debug = this._options.debug;

  // Connected clients
  /**
   * A mapping of client id to client information object and ws information
   */
  this._clients = {};

  /**
   * A mapping of resource url to a mapping of clients and boolean if they have it or not
   */
  this._resources = {};

  /**
   * A mapping of a given resource url to its size
   */
  this._resourceSizes = {};

  this._initializeWSS();

  this._initializeHTTP();
  this._httpServer.listen(this._options.port);


};

util.inherits(PeerKitServer, EventEmitter);

PeerKitServer.prototype._initializeWSS = function(){

  var self = this;

  // Create WebSocket server as well.
  this._wss = new WebSocketServer({ path: '/ws', server: this._httpServer });

  this._wss.on('connection', function(socket) {
    //var query = url.parse(socket.upgradeReq.url, true).query;
    var client = {
      id: self._generateId(),
      socket: socket,
      resources: {},
      conns: []
    };
    self._clients[client.id] = client;
    socket.on('message', function(data){
      util.log(data);
      var message;
      try {
        message = JSON.parse(data);
        if (!message.type) {
          throw new Error('Invalid message format: missing type');
        }
      } catch(e) {
        if (self.debug) {
          throw e;
        }
        util.log('Invalid message', data);
        return;
      }
      switch (message.type) {
        case 'RESPONSE':
          // Response to offer with ICE and answer
          //
          // message.id   (String, id of destination)
          // message.data (String, JSON of ice and answer)
          //
          var resp = self._forward(message.id, message.data);
          /*if (resp.error) {
            socket.send(JSON.stringify(
              type: 'ERROR-CLIENT-DEAD',

            ));
          }*/
          break;
        case 'REPORT':
          // New resource available
          //
          // message.url (String, resource absolute url)
          //
          self._reportResource(client, message.resource);
          break;
        case 'REQUEST':
          // Asking for resource
          //
          // message.url (String, resource absolute url)
          //
          var conns = self._requestResource(message.url);
          socket.send(JSON.stringify(conns));
          break;
        case 'CONN':
          // Connection information to store
          //
          // message.conn (mixed data)
          //
          client.conns.push(message.conn);
          break;
        case 'SERVED':
          // Served a file, increment analytics
          break;
        default:
          util.log('Message unrecognized');
      }
    });
    socket.on('close', function() {
      util.log('Socket closed:', client.id);
      var resources = client.resources;
      var hashes = Object.keys(resources);
      var ii = hashes.length;
      for (var i = 0; i < ii; i++) {
        delete self._resources[hashes[i]][client.id];
      }
      delete self._clients[client.id];
    });
  });
};

PeerKitServer.prototype._initializeHTTP = function(){
  var self = this;

  /*this._app.post('/response', function(req, res){
    // Responding to an offer with ICE and answer
    //
    // params.id    (String, id of destination)
    // body.data    (String, JSON of ice and answer
    //
    var resp = self._forward(req.params.id, req.body.data);
    res.send(resp);
  });*/
  this._app.enable("jsonp callback");

  this._app.get('/requestResource', function(req, res) {
    var urls = req.query.urls;
    if (!Array.isArray(urls)) {
        res.send("need array", 401);
    }
    var data = {};
    var ii = urls.length;
    for (var i = 0; i < ii; i++) {
      data[urls[i]] = self._requestResource(urls[i]);
    }
    res.jsonp(data);
    // Get Javascript library along with necessary data
  });
};

/**
 * Tells the server that we have the resource at given url
 * @param client the ws client
 * @param resource object with both the url and size of resource
 */
PeerKitServer.prototype._reportResource = function(client, resource) {
  var self = this;
  if (!client.resources[resource.url]) {
    client.resources[resource.url] = true;
    if (!self._resources[resource.url]) {
      self._resources[resource.url] = {};
    }
    self._resources[resource.url][client.id] = true;
    self._resourceSizes[resource.url] = resource.size;
    console.log(self._resources);
  }
};

/**
 * Returns a list of connections that the server has for the given url
 */
PeerKitServer.prototype._requestResource = function(url) {
  var resources = this._resources[url];
  if (!resources) {
    return [];
  }
  var clients = Object.keys(resources);
  var conns = [];
  if (clients.length <= this._options.multiplicity) {
    // Add each client
    console.log(this._clients);
    for (var i = 0; i < clients.length; i++) {
      if (this._clients[clients[i]].conns.length > 0) {
        conns.push(this._clients[clients[i]].conns.pop());
      }
    }<commit_msg>fixed some bugs<commit_after>var express = require('express');
var http = require('http');
var WebSocketServer = require('ws').Server;
var EventEmitter = require('events').EventEmitter;
var util = require('./util');
var url = require('url');

function PeerKitServer(options) {
  if (!(this instanceof PeerKitServer)) return new PeerKitServer(options);
  EventEmitter.call(this);

  this._app = express();
  this._httpServer = http.createServer(this._app);

  this._options = util.extend({
    port: 8080,
    debug: true,
    multiplicity: 5
  }, options);

  util.debug = this._options.debug;

  // Connected clients
  /**
   * A mapping of client id to client information object and ws information
   */
  this._clients = {};

  /**
   * A mapping of resource url to a mapping of clients and boolean if they have it or not
   */
  this._resources = {};

  /**
   * A mapping of a given resource url to its size
   */
  this._resourceSizes = {};

  this._initializeWSS();

  this._initializeHTTP();
  this._httpServer.listen(this._options.port);


};

util.inherits(PeerKitServer, EventEmitter);

PeerKitServer.prototype._initializeWSS = function(){

  var self = this;

  // Create WebSocket server as well.
  this._wss = new WebSocketServer({ path: '/ws', server: this._httpServer });

  this._wss.on('connection', function(socket) {
    //var query = url.parse(socket.upgradeReq.url, true).query;
    var client = {
      id: self._generateId(),
      socket: socket,
      resources: {},
      conns: []
    };
    self._clients[client.id] = client;
    socket.on('message', function(data){
      util.log(data);
      var message;
      try {
        message = JSON.parse(data);
        if (!message.type) {
          throw new Error('Invalid message format: missing type');
        }
      } catch(e) {
        if (self.debug) {
          throw e;
        }
        util.log('Invalid message', data);
        return;
      }
      switch (message.type) {
        case 'RESPONSE':
          // Response to offer with ICE and answer
          //
          // message.id   (String, id of destination)
          // message.data (String, JSON of ice and answer)
          //
          var resp = self._forward(message.id, message.data);
          /*if (resp.error) {
            socket.send(JSON.stringify(
              type: 'ERROR-CLIENT-DEAD',

            ));
          }*/
          break;
        case 'REPORT':
          // New resource available
          //
          // message.url (String, resource absolute url)
          //
          self._reportResource(client, message.resource);
          break;
        case 'REQUEST':
          // Asking for resource
          //
          // message.url (String, resource absolute url)
          //
          var conns = self._requestResource(message.url);
          socket.send(JSON.stringify(conns));
          break;
        case 'CONN':
          // Connection information to store
          //
          // message.conn (mixed data)
          //
          client.conns.push(message.conn);
          break;
        case 'SERVED':
          // Served a file, increment analytics
          break;
        default:
          util.log('Message unrecognized');
      }
    });
    socket.on('close', function() {
      util.log('Socket closed:', client.id);
      var resources = client.resources;
      var hashes = Object.keys(resources);
      var ii = hashes.length;
      for (var i = 0; i < ii; i++) {
        delete self._resources[hashes[i]][client.id];
      }
      delete self._clients[client.id];
    });
  });
};

PeerKitServer.prototype._initializeHTTP = function(){
  var self = this;

  /*this._app.post('/response', function(req, res){
    // Responding to an offer with ICE and answer
    //
    // params.id    (String, id of destination)
    // body.data    (String, JSON of ice and answer
    //
    var resp = self._forward(req.params.id, req.body.data);
    res.send(resp);
  });*/
  this._app.enable("jsonp callback");

  this._app.get('/requestResource', function(req, res) {
    var urls = req.query.urls;
    if (!Array.isArray(urls)) {
        res.send("need array", 401);
    }
    var data = {};
    var ii = urls.length;
    for (var i = 0; i < ii; i++) {
      data[urls[i]] = self._requestResource(urls[i]);
    }
    res.jsonp(data);
    // Get Javascript library along with necessary data
  });
};

/**
 * Tells the server that we have the resource at given url
 * @param client the ws client
 * @param resource object with both the url and size of resource
 */
PeerKitServer.prototype._reportResource = function(client, resource) {
  var self = this;
  if (!client.resources[resource.url]) {
    client.resources[resource.url] = true;
    if (!self._resources[resource.url]) {
      self._resources[resource.url] = {};
    }
    self._resources[resource.url][client.id] = true;
    self._resourceSizes[resource.url] = resource.size;
    console.log(self._resources);
  }
};

/**
 * Returns a list of connections that the server has for the given url
 */
PeerKitServer.prototype._requestResource = function(url) {
  var resources = this._resources[url];
  if (!resources) {
    return [];
  }
  var clients = Object.keys(resources);
  var conns = [];
  if (clients.length <= this._options.multiplicity) {
    // Add each client
    for (var i = 0; i < clients.length; i++) {
      if (this._clients[clients[i]].conns.length > 0) {
        conns.push(this._clients[clients[i]].conns.pop());
      }
    }
{'fraction_non_alphanumeric': 0.1380718954248366, 'fraction_numerical': 0.002178649237472767, 'mean_word_length': 2.2730243612596555, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 5, 'https://': 0, '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': '1819392', 'n_tokens_mistral': 3284, 'n_tokens_neox': 3228, 'n_words': 835}