11module . exports = Server
2- module . exports . parseHttpRequest = parseHttpRequest
32
43var bencode = require ( 'bencode' )
5- var bufferEqual = require ( 'buffer-equal' )
64var common = require ( './lib/common' )
75var debug = require ( 'debug' ) ( 'bittorrent-tracker' )
86var dgram = require ( 'dgram' )
@@ -13,12 +11,12 @@ var ipLib = require('ip')
1311var portfinder = require ( 'portfinder' )
1412var string2compact = require ( 'string2compact' )
1513
14+ var parseHttpRequest = require ( './lib/parse_http' )
15+ var parseUdpRequest = require ( './lib/parse_udp' )
16+
1617// Use random port above 1024
1718portfinder . basePort = Math . floor ( Math . random ( ) * 60000 ) + 1025
1819
19- var NUM_ANNOUNCE_PEERS = 50
20- var MAX_ANNOUNCE_PEERS = 82
21- var REMOVE_IPV6_RE = / ^ : : f f f f : /
2220
2321inherits ( Server , EventEmitter )
2422
@@ -369,119 +367,6 @@ Server.prototype._getPeersCompact = function (swarm, numwant) {
369367}
370368
371369
372- function parseHttpRequest ( req , options ) {
373- var s = req . url . split ( '?' )
374- var params = common . querystringParse ( s [ 1 ] )
375-
376- if ( s [ 0 ] === '/announce' ) {
377- params . action = common . ACTIONS . ANNOUNCE
378-
379- params . peer_id = typeof params . peer_id === 'string' && common . binaryToUtf8 ( params . peer_id )
380- params . port = Number ( params . port )
381-
382- if ( typeof params . info_hash !== 'string' ) throw new Error ( 'invalid info_hash' )
383- if ( params . info_hash . length !== 20 ) throw new Error ( 'invalid info_hash length' )
384- if ( typeof params . peer_id !== 'string' ) throw new Error ( 'invalid peer_id' )
385- if ( params . peer_id . length !== 20 ) throw new Error ( 'invalid peer_id length' )
386- if ( ! params . port ) throw new Error ( 'invalid port' )
387-
388- params . left = Number ( params . left )
389- params . compact = Number ( params . compact )
390-
391- params . ip = options . trustProxy
392- ? req . headers [ 'x-forwarded-for' ] || req . connection . remoteAddress
393- : req . connection . remoteAddress . replace ( REMOVE_IPV6_RE , '' ) // force ipv4
394- params . addr = params . ip + ':' + params . port // TODO: ipv6 brackets?
395-
396- params . numwant = Math . min (
397- Number ( params . numwant ) || NUM_ANNOUNCE_PEERS ,
398- MAX_ANNOUNCE_PEERS
399- )
400-
401- return params
402- } else if ( s [ 0 ] === '/scrape' ) { // unofficial scrape message
403- params . action = common . ACTIONS . SCRAPE
404-
405- if ( typeof params . info_hash === 'string' ) {
406- params . info_hash = [ params . info_hash ]
407- }
408-
409- if ( params . info_hash ) {
410- if ( ! Array . isArray ( params . info_hash ) ) throw new Error ( 'invalid info_hash array' )
411-
412- params . info_hash = params . info_hash . map ( function ( infoHash ) {
413- if ( infoHash . length !== 20 ) {
414- throw new Error ( 'invalid info_hash' )
415- }
416-
417- return infoHash
418- } )
419- }
420-
421- return params
422- } else {
423- return null
424- }
425- }
426-
427- function parseUdpRequest ( msg , rinfo ) {
428- if ( msg . length < 16 ) {
429- throw new Error ( 'received packet is too short' )
430- }
431-
432- if ( rinfo . family !== 'IPv4' ) {
433- throw new Error ( 'udp tracker does not support IPv6' )
434- }
435-
436- var params = {
437- connectionId : msg . slice ( 0 , 8 ) , // 64-bit
438- action : msg . readUInt32BE ( 8 ) ,
439- transactionId : msg . readUInt32BE ( 12 )
440- }
441-
442- // TODO: randomize:
443- if ( ! bufferEqual ( params . connectionId , common . CONNECTION_ID ) ) {
444- throw new Error ( 'received packet with invalid connection id' )
445- }
446-
447- if ( params . action === common . ACTIONS . CONNECT ) {
448- // No further params
449- } else if ( params . action === common . ACTIONS . ANNOUNCE ) {
450- params . info_hash = msg . slice ( 16 , 36 ) . toString ( 'binary' ) // 20 bytes
451- params . peer_id = msg . slice ( 36 , 56 ) . toString ( 'utf8' ) // 20 bytes
452- params . downloaded = fromUInt64 ( msg . slice ( 56 , 64 ) ) // TODO: track this?
453- params . left = fromUInt64 ( msg . slice ( 64 , 72 ) )
454- params . uploaded = fromUInt64 ( msg . slice ( 72 , 80 ) ) // TODO: track this?
455- params . event = msg . readUInt32BE ( 80 )
456- params . event = common . EVENT_IDS [ params . event ]
457- if ( ! params . event ) throw new Error ( 'invalid event' ) // early return
458- params . ip = msg . readUInt32BE ( 84 ) // optional
459- params . ip = params . ip ?
460- ipLib . toString ( params . ip ) :
461- params . ip = rinfo . address
462- params . key = msg . readUInt32BE ( 88 ) // TODO: what is this for?
463- params . numwant = msg . readUInt32BE ( 92 ) // optional
464- // never send more than MAX_ANNOUNCE_PEERS or else the UDP packet will get bigger than
465- // 512 bytes which is not safe
466- params . numwant = Math . min ( params . numwant || NUM_ANNOUNCE_PEERS , MAX_ANNOUNCE_PEERS )
467- params . port = msg . readUInt16BE ( 96 ) || rinfo . port // optional
468- params . addr = params . ip + ':' + params . port // TODO: ipv6 brackets
469- params . compact = 1 // udp is always compact
470-
471- } else if ( params . action === common . ACTIONS . SCRAPE ) { // scrape message
472- params . info_hash = msg . slice ( 16 , 36 ) . toString ( 'binary' ) // 20 bytes
473-
474- // TODO: support multiple info_hash scrape
475- if ( msg . length > 36 ) {
476- throw new Error ( 'multiple info_hash scrape not supported' )
477- }
478- } else {
479- return null
480- }
481-
482- return params
483- }
484-
485370function makeUdpPacket ( params ) {
486371 switch ( params . action ) {
487372 case common . ACTIONS . CONNECT :
@@ -523,19 +408,3 @@ function makeUdpPacket (params) {
523408 throw new Error ( 'Action not implemented: ' + params . action )
524409 }
525410}
526-
527- // HELPER FUNCTIONS
528-
529- var TWO_PWR_32 = ( 1 << 16 ) * 2
530-
531- /**
532- * Return the closest floating-point representation to the buffer value. Precision will be
533- * lost for big numbers.
534- */
535- function fromUInt64 ( buf ) {
536- var high = buf . readUInt32BE ( 0 ) | 0 // force
537- var low = buf . readUInt32BE ( 4 ) | 0
538- var lowUnsigned = ( low >= 0 ) ? low : TWO_PWR_32 + low
539-
540- return high * TWO_PWR_32 + lowUnsigned
541- }
0 commit comments