<commit_before>module.exports = HTTPTracker

var bencode = require('bencode')
var compact2string = require('compact2string')
var debug = require('debug')('bittorrent-tracker:http-tracker')
var extend = require('xtend')
var get = require('simple-get')
var inherits = require('inherits')

var common = require('../common')
var Tracker = require('./tracker')

var HTTP_SCRAPE_SUPPORT = /\/(announce)[^\/]*$/

inherits(HTTPTracker, Tracker)

/**
 * HTTP torrent tracker client (for an individual tracker)
 *
 * @param {Client} client       parent bittorrent tracker client
 * @param {string} announceUrl  announce url of tracker
 * @param {Object} opts         options object
 */
function HTTPTracker (client, announceUrl, opts) {
  var self = this
  Tracker.call(self, client, announceUrl)
  debug('new http tracker %s', announceUrl)

  // Determine scrape url (if http tracker supports it)
  self.scrapeUrl = null
  var m
  if ((m = self.announceUrl.match(HTTP_SCRAPE_SUPPORT))) {
    self.scrapeUrl = self.announceUrl.slice(0, m.index) + '/scrape' +
      self.announceUrl.slice(m.index + 9)
  }
}

HTTPTracker.prototype.DEFAULT_ANNOUNCE_INTERVAL = 30 * 60 * 1000 // 30 minutes

HTTPTracker.prototype.announce = function (opts) {
  var self = this
  if (self.destroyed) return

  var params = extend(opts, {
    compact: (opts.compact == null) ? 1 : opts.compact,
    info_hash: self.client._infoHashBinary,
    peer_id: self.client._peerIdBinary,
    port: self.client._port
  })
  if (self._trackerId) params.trackerid = self._trackerId

  self._request(self.announceUrl, params, function (data) {
    self._onAnnounceResponse(data)
  })
}

HTTPTracker.prototype.scrape = function (opts) {
  var self = this
  if (self.destroyed) return

  if (!self.scrapeUrl) {
    self.client.emit('error', new Error('scrape not supported ' + self.announceUrl))
    return
  }

  var infoHashes = (Array.isArray(opts.infoHash) && opts.infoHash.length > 0)
    ? opts.infoHash.map(function (infoHash) {
      return infoHash.toString('binary')
    })
    : (opts.infoHash && opts.infoHash.toString('binary')) || self.client._infoHashBinary
  var params = {
    info_hash: infoHashes
  }
  self._request(self.scrapeUrl, params, function (data) {
    self._onScrapeResponse(data)
  })
}

HTTPTracker.prototype.destroy = function (cb) {
  var self = this
  if (self.destroyed) return cb(null)
  self.destroyed = true
  clearInterval(self.interval)

  cb(null)
}

HTTPTracker.prototype._request = function (requestUrl, params, cb) {
  var self = this
  var u = requestUrl + (requestUrl.indexOf('?') === -1 ? '?' : '&') +
    common.querystringStringify(params)

  get.concat(u, function (err, res, data) {
    if (self.destroyed) return
    if (err) return self.client.emit('warning', err)
    if (res.statusCode !== 200) {
      return self.client.emit('warning', new Error('Non-200 response code ' +
        res.statusCode + ' from ' + self.announceUrl))
    }<commit_msg>add 'user-agent' in HTTP header<commit_after>module.exports = HTTPTracker

var bencode = require('bencode')
var compact2string = require('compact2string')
var debug = require('debug')('bittorrent-tracker:http-tracker')
var extend = require('xtend')
var get = require('simple-get')
var inherits = require('inherits')

var common = require('../common')
var Tracker = require('./tracker')

var HTTP_SCRAPE_SUPPORT = /\/(announce)[^\/]*$/

inherits(HTTPTracker, Tracker)

/**
 * HTTP torrent tracker client (for an individual tracker)
 *
 * @param {Client} client       parent bittorrent tracker client
 * @param {string} announceUrl  announce url of tracker
 * @param {Object} opts         options object
 */
function HTTPTracker (client, announceUrl, opts) {
  var self = this
  Tracker.call(self, client, announceUrl)
  debug('new http tracker %s', announceUrl)

  // Determine scrape url (if http tracker supports it)
  self.scrapeUrl = null
  var m
  if ((m = self.announceUrl.match(HTTP_SCRAPE_SUPPORT))) {
    self.scrapeUrl = self.announceUrl.slice(0, m.index) + '/scrape' +
      self.announceUrl.slice(m.index + 9)
  }
}

HTTPTracker.prototype.DEFAULT_ANNOUNCE_INTERVAL = 30 * 60 * 1000 // 30 minutes

HTTPTracker.prototype.announce = function (opts) {
  var self = this
  if (self.destroyed) return

  var params = extend(opts, {
    compact: (opts.compact == null) ? 1 : opts.compact,
    info_hash: self.client._infoHashBinary,
    peer_id: self.client._peerIdBinary,
    port: self.client._port
  })
  if (self._trackerId) params.trackerid = self._trackerId

  self._request(self.announceUrl, params, function (data) {
    self._onAnnounceResponse(data)
  })
}

HTTPTracker.prototype.scrape = function (opts) {
  var self = this
  if (self.destroyed) return

  if (!self.scrapeUrl) {
    self.client.emit('error', new Error('scrape not supported ' + self.announceUrl))
    return
  }

  var infoHashes = (Array.isArray(opts.infoHash) && opts.infoHash.length > 0)
    ? opts.infoHash.map(function (infoHash) {
      return infoHash.toString('binary')
    })
    : (opts.infoHash && opts.infoHash.toString('binary')) || self.client._infoHashBinary
  var params = {
    info_hash: infoHashes
  }
  self._request(self.scrapeUrl, params, function (data) {
    self._onScrapeResponse(data)
  })
}

HTTPTracker.prototype.destroy = function (cb) {
  var self = this
  if (self.destroyed) return cb(null)
  self.destroyed = true
  clearInterval(self.interval)

  cb(null)
}

HTTPTracker.prototype._request = function (requestUrl, params, cb) {
  var self = this
  var u = requestUrl + (requestUrl.indexOf('?') === -1 ? '?' : '&') +
    common.querystringStringify(params)
  var opts = {
    url: u,
    header: {
      'user-agent': self.client._userAgent || ''
    }
  }

  get.concat(opts, function (err, res, data) {
    if (self.destroyed) return
    if (err) return self.client.emit('warning', err)
    if (res.statusCode !== 200) {
      return self.client.emit('warning', new Error('Non-200 response code ' +
        res.statusCode + ' from ' + self.announceUrl))
    }
{'fraction_non_alphanumeric': 0.13774241670810541, 'fraction_numerical': 0.007624730648102105, 'mean_word_length': 3.7549251379038613, 'pattern_counts': {'":': 0, '<': 3, '<?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': '2820485', 'n_tokens_mistral': 2043, 'n_tokens_neox': 1945, 'n_words': 461}