[Aversa-commits] aversa/lib/aversa track.rb
teamikl at rubyforge.org
teamikl at rubyforge.org
Tue Sep 28 21:02:58 EDT 2004
Update of /var/cvs/aversa/aversa/lib/aversa
In directory rubyforge.org:/tmp/cvs-serv27871/lib/aversa
Modified Files:
track.rb
Log Message:
Added/Fixed some checking input data were missing in AnnounceHandler.
Index: track.rb
===================================================================
RCS file: /var/cvs/aversa/aversa/lib/aversa/track.rb,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** track.rb 28 Sep 2004 03:36:17 -0000 1.12
--- track.rb 29 Sep 2004 01:02:56 -0000 1.13
***************
*** 35,38 ****
--- 35,39 ----
require 'pstore'
require 'thread'
+ require 'ipaddr'
require 'net/bittorrent/bencoding'
***************
*** 65,71 ****
class BTTrackerServlet < WEBrick::HTTPServlet::AbstractServlet
! def do_GET(req, res)
! res.body = encode(res.body)
res['Content-length'] = res.body.length
end
end
--- 66,87 ----
class BTTrackerServlet < WEBrick::HTTPServlet::AbstractServlet
! ##
! # === Param
! # - req ... Request
! # - res ... Response
! # - ret ... Return Value, which will be bencoded response body.
! #
! # === NOTES
! #
! # - TODO I may need to return 400 Bad request error sometime.
! # Body is not only bencoded data.
! #
! def do_GET(req, res, ret)
! res.body = encode(ret)
res['Content-length'] = res.body.length
+ res['Content-Type'] = 'text/plain'
+ res['Connection'] = 'close'
+ res['Pragma'] = 'no-cache'
+ res['Server'] = SERVER_NAME
end
end
***************
*** 73,77 ****
class AnnounceHandler < BTTrackerServlet
#
! # Announce Request sample
#
# info_hash=R%5B%8CwD3%27%F9%12%948%EF%E3%D1%F8%BF%B3%C3H%07
--- 89,93 ----
class AnnounceHandler < BTTrackerServlet
#
! # === Announce Request sample query data
#
# info_hash=R%5B%8CwD3%27%F9%12%948%EF%E3%D1%F8%BF%B3%C3H%07
***************
*** 85,88 ****
--- 101,133 ----
# event= started | stopped
# numwant
+ #
+ #
+ # === Announce Response
+ #
+ # success:
+ # ret['interval'] = integer
+ # ret['peers'] = array of peer hashes, or string(when compact=1)
+ #
+ # failure:
+ # ret['failure reason'] = string
+ #
+ #
+ # === Data
+ #
+ # - db ... dstate data (pstore)
+ #
+ # db['completed'][info_hash] = integer (numbers of complated download)
+ # db['peers'][peer_id] = { 'peer id' => }
+ #
+ # - @@cache[info_hash] = hashes of peers
+ #
+ # - @@times[info_hash][peer_id] = Time object
+ #
+
+ # :stopdoc:
+ # XXX Thise should be global in file or application's instance variable.
+ @@cache = Hash.new
+ @@times = Hash.new
+ # :startdoc:
##
***************
*** 93,111 ****
# - TODO There are 'failure reason' and 'warning message' for error/warm,
# Make sure the manner which should I use, for the case.
#
def do_GET(req, res)
query_data = req.query
! # TODO check input values. (How to use Taint mode)
! # TODO how to catch errror, and what error message return
! unless query_data.has_key? 'downloaded' or
! query_data.has_key? 'uploaded' or
! query_data.has_key? 'left' or
! query_data.has_key? 'info_hash' or
! query_data.has_key? 'peer_id' or
! query_data.has_key? 'event' or
! query_data.has_key? 'port'
raise TrackerFailure, 'Bad request'
end
--- 138,161 ----
# - TODO There are 'failure reason' and 'warning message' for error/warm,
# Make sure the manner which should I use, for the case.
+ # - TODO make class for dstate data
+ # = TODO check input values. (How to use Taint mode and safe level)
#
def do_GET(req, res)
+ ret = Hash.new
+ ret['interval'] = REREQUEST_INTERVAL
+
query_data = req.query
! unless query_data.has_key? 'downloaded' and
! query_data.has_key? 'uploaded' and
! query_data.has_key? 'left' and
! query_data.has_key? 'info_hash' and
! query_data.has_key? 'peer_id' and
! query_data.has_key? 'event' and
! query_data.has_key? 'port' and
! query_data.has_key? 'key'
+ # TODO Response should be 400 Bad request.
raise TrackerFailure, 'Bad request'
end
***************
*** 119,127 ****
end
! unless query_data['peer_id'].length == 8
raise TrackerFailure, 'Bad length of peer id'
end
! # Expect GC early collects the query hash and request object, -> .dup
downloaded = query_data['downloaded'].to_i
uploaded = query_data['uploaded'].to_i
--- 169,180 ----
end
! unless query_data['peer_id'].length == 20
raise TrackerFailure, 'Bad length of peer id'
end
! unless query_data['key'].length == 8
! raise TrackerFailure, 'Bad length of key'
! end
!
downloaded = query_data['downloaded'].to_i
uploaded = query_data['uploaded'].to_i
***************
*** 131,178 ****
event = query_data['event'].dup
port = query_data['port'].to_i
ip = (query_data.has_key? 'ip') ? query_data['ip'].dup \
: req.peeraddr.last.dup
! # peer = { 'ip' => ip, 'port' => port.to_i, 'peer id' => peer_id }
! peer = Hash.new
! peer['ip'] = ip
! peer['port'] = port.to_i
! peer['peer id'] = peer_id
!
! # Set return value
! ret = Hash.new
! ret['peers'] = Array.new
! ret['interval'] = REREQUEST_INTERVAL
- # Read/Write dstate data
- # TODO cache
- # TODO make class for dstate data
db = PStore.new(DSTATE_FILE)
db.transaction do
! db['completed'][info_hash] ||= 0
! db['peers'][info_hash] ||= {}
db['peers'][info_hash][peer_id] = peer
! # Event (started|stopped|completed)
! case event
when 'started'
! if db['peers'].has_key? info_hash
! ret['peers'] = db['peers'][info_hash].values.dup
! end
when 'completed'
! raise NotImplementedError
when 'stopped'
raise NotImplementedError
else
raise "Not come here"
end
!
! end # of db.transaction.
rescue NotImplementedError
! ret = { 'failure reason' => 'This feature was not implemented, yet' }
! rescue TrackerFailure => e
! ret = { 'failure reason' => e.reason }
## Don't catch while debug.
--- 184,255 ----
event = query_data['event'].dup
port = query_data['port'].to_i
+ key = query_data['key'].dup
ip = (query_data.has_key? 'ip') ? query_data['ip'].dup \
: req.peeraddr.last.dup
+ # override ip should be option.
! begin
! unless IPAddr.new(ip).ipv4?
! raise TrackerFailure, 'This tracker can accept IPv4 address only.'
! end
! rescue ArgumentError
! raise TrackerFailure, 'Invalid IP address'
! end
!
! peer = {
! 'ip' => ip,
! 'key' => key,
! 'nat' => 0,
! 'port' => port.to_i,
! 'left' => left.to_i,
! }
db = PStore.new(DSTATE_FILE)
db.transaction do
!
! db['peers'][info_hash] ||= {}
!
! #if db['peers'][info_hash].has_key? peer_id and
! # db['peers'][info_hash][peer_id].has_key 'key'
! # unless db['peers'][info_hash][peer_id]['key'] == key
! # raise TrackerFailure, 'key did not match'
! # end
! #end
!
! @@times[peer_id] = Time.now
! @@cache[info_hash] ||= {}
! @@cache[info_hash][peer_id] = { 'ip' => ip,
! 'port' => port.to_i,
! 'peer_id' => peer_id }
db['peers'][info_hash][peer_id] = peer
! p "-" * 50
! p @@cache
!
! case event
when 'started'
! ret['peers'] = @@cache[info_hash].values.dup
!
when 'completed'
! db['completed'][info_hash] ||= 0
! db['completed'][info_hash] += 1
!
when 'stopped'
raise NotImplementedError
+
else
raise "Not come here"
end
! end
!
!
! rescue RuntimeError => e
! ret['failure reason'] = e.to_s
rescue NotImplementedError
! ret['failure reason'] = 'This feature was not implemented, yet'
! rescue TrackerFailure => failure
! ret['failure reason'] = failure.reason
## Don't catch while debug.
***************
*** 182,193 ****
ensure
! res['Server'] = SERVER_NAME
! res['Connection'] = 'close'
! res['Content-Type'] = 'text/plain'
! res.body = ret
!
! # Call super for Encode res.body and Set Content-length field.
! super(req, res)
end
end
--- 259,265 ----
ensure
! super(req, res, ret)
end
+
end
***************
*** 335,346 ****
end
- res.body = ret
-
rescue NotImplementedError => err
! res.body = { 'failure reason' => "#{err}" }
ensure
! res['Content-Type'] = 'text/plain'
! super(req, res)
end
end
--- 407,415 ----
end
rescue NotImplementedError => err
! ret = { 'failure reason' => "#{err}" }
ensure
! super(req, res, ret)
end
end
More information about the Aversa-commits
mailing list