distribustream 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +18 -0
- data/README +5 -41
- data/bin/dsclient +23 -10
- data/bin/dstream +70 -7
- data/distribustream.gemspec +6 -6
- data/lib/pdtp/client.rb +35 -19
- data/lib/pdtp/client/callbacks.rb +18 -7
- data/lib/pdtp/client/connection.rb +31 -25
- data/lib/pdtp/client/file_buffer.rb +14 -2
- data/lib/pdtp/client/file_service.rb +17 -11
- data/lib/pdtp/client/http_client.rb +18 -19
- data/lib/pdtp/client/http_handler.rb +21 -11
- data/lib/pdtp/client/transfer.rb +29 -29
- data/lib/pdtp/common.rb +19 -4
- data/lib/pdtp/common/file_service.rb +14 -2
- data/lib/pdtp/common/http_server.rb +217 -0
- data/lib/pdtp/common/length_prefix_protocol.rb +14 -2
- data/lib/pdtp/common/protocol.rb +23 -16
- data/lib/pdtp/server.rb +101 -26
- data/lib/pdtp/server/client_info.rb +14 -2
- data/lib/pdtp/server/connection.rb +31 -9
- data/lib/pdtp/server/dispatcher.rb +37 -87
- data/lib/pdtp/server/file_service.rb +17 -2
- data/lib/pdtp/server/file_service_protocol.rb +23 -38
- data/lib/pdtp/server/status_handler.rb +103 -0
- data/lib/pdtp/server/transfer.rb +21 -9
- data/lib/pdtp/server/trust.rb +14 -2
- data/pdtp-specification.xml +831 -0
- metadata +8 -8
- data/bin/dsseed +0 -32
- data/lib/pdtp/common/common_init.rb +0 -122
- data/lib/pdtp/server/stats_handler.rb +0 -23
@@ -1,11 +1,23 @@
|
|
1
1
|
#--
|
2
2
|
# Copyright (C) 2006-07 ClickCaster, Inc. (info@clickcaster.com)
|
3
|
-
#
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
4
16
|
#
|
5
17
|
# This source file is distributed as part of the
|
6
18
|
# DistribuStream file transfer system.
|
7
19
|
#
|
8
|
-
# See http://distribustream.
|
20
|
+
# See http://distribustream.org/
|
9
21
|
#++
|
10
22
|
|
11
23
|
require 'rubygems'
|
data/lib/pdtp/common/protocol.rb
CHANGED
@@ -1,16 +1,27 @@
|
|
1
1
|
#--
|
2
2
|
# Copyright (C) 2006-07 ClickCaster, Inc. (info@clickcaster.com)
|
3
|
-
#
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
4
16
|
#
|
5
17
|
# This source file is distributed as part of the
|
6
18
|
# DistribuStream file transfer system.
|
7
19
|
#
|
8
|
-
# See http://distribustream.
|
20
|
+
# See http://distribustream.org/
|
9
21
|
#++
|
10
22
|
|
11
23
|
require 'rubygems'
|
12
24
|
require 'eventmachine'
|
13
|
-
require 'thread'
|
14
25
|
require 'ipaddr'
|
15
26
|
|
16
27
|
begin
|
@@ -40,9 +51,8 @@ module PDTP
|
|
40
51
|
@connection_open
|
41
52
|
end
|
42
53
|
|
43
|
-
def initialize
|
54
|
+
def initialize(*args)
|
44
55
|
user_data = nil
|
45
|
-
@mutex = Mutex.new
|
46
56
|
super
|
47
57
|
end
|
48
58
|
|
@@ -85,7 +95,7 @@ module PDTP
|
|
85
95
|
def receive_packet(packet)
|
86
96
|
begin
|
87
97
|
packet.chomp!
|
88
|
-
|
98
|
+
#@@log.debug "(#{remote_peer_id}) recv: " + packet
|
89
99
|
message = JSON.parse(packet) rescue nil
|
90
100
|
raise ProtocolError.new("JSON couldn't parse: #{packet}") if message.nil?
|
91
101
|
Protocol.validate_message message
|
@@ -94,14 +104,16 @@ module PDTP
|
|
94
104
|
hash_to_range command, options
|
95
105
|
receive_message(command, options) if respond_to? :receive_message
|
96
106
|
rescue ProtocolError => e
|
97
|
-
|
98
|
-
|
107
|
+
# FIXME Should likely be raised and handled higher
|
108
|
+
STDERR.write "(#{remote_peer_id}) PROTOCOL ERROR: #{e.to_s}\n"
|
109
|
+
STDERR.write e.backtrace.join("\n") + "\n"
|
99
110
|
error_close_connection e.to_s
|
100
111
|
rescue ProtocolWarn => e
|
101
112
|
send_message :protocol_warn, :message => e.to_s
|
102
113
|
rescue Exception => e
|
103
|
-
|
104
|
-
|
114
|
+
# FIXME Should likely be raised and handled higher
|
115
|
+
STDERR.write "(#{remote_peer_id}) UNKNOWN EXCEPTION #{e.to_s}\n"
|
116
|
+
STDERR.write e.backtrace.join("\n") + "\n"
|
105
117
|
end
|
106
118
|
end
|
107
119
|
|
@@ -155,12 +167,7 @@ module PDTP
|
|
155
167
|
# Message format is a JSON array with the command (string) as the first entry
|
156
168
|
# Second entry is an options hash/object
|
157
169
|
message = [command.to_s, opts]
|
158
|
-
|
159
|
-
#@mutex.synchronize do
|
160
|
-
outstr = JSON.unparse(message) + "\n"
|
161
|
-
@@log.debug "(#{remote_peer_id}) send: #{outstr.chomp}"
|
162
|
-
send_packet outstr
|
163
|
-
#end
|
170
|
+
send_packet JSON.unparse(message) + "\n"
|
164
171
|
end
|
165
172
|
|
166
173
|
#called by EventMachine when a connection is closed
|
data/lib/pdtp/server.rb
CHANGED
@@ -1,68 +1,143 @@
|
|
1
1
|
#--
|
2
2
|
# Copyright (C) 2006-07 ClickCaster, Inc. (info@clickcaster.com)
|
3
|
-
#
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
4
16
|
#
|
5
17
|
# This source file is distributed as part of the
|
6
18
|
# DistribuStream file transfer system.
|
7
19
|
#
|
8
|
-
# See http://distribustream.
|
20
|
+
# See http://distribustream.org/
|
9
21
|
#++
|
10
22
|
|
11
23
|
require 'rubygems'
|
12
24
|
require 'eventmachine'
|
13
25
|
require 'mongrel'
|
26
|
+
require 'logger'
|
27
|
+
require 'socket'
|
14
28
|
|
15
29
|
require File.dirname(__FILE__) + '/common'
|
30
|
+
require File.dirname(__FILE__) + '/common/http_server'
|
16
31
|
require File.dirname(__FILE__) + '/server/dispatcher'
|
17
32
|
require File.dirname(__FILE__) + '/server/file_service'
|
33
|
+
require File.dirname(__FILE__) + '/server/file_service_protocol'
|
18
34
|
require File.dirname(__FILE__) + '/server/connection'
|
19
|
-
require File.dirname(__FILE__) + '/server/
|
35
|
+
require File.dirname(__FILE__) + '/server/status_handler'
|
20
36
|
|
21
37
|
module PDTP
|
22
38
|
# PDTP::Server provides an interface for creating a PDTP server
|
23
39
|
class Server
|
40
|
+
attr_reader :addr, :port
|
41
|
+
|
24
42
|
# Create a new PDTP::Server which will listen on the given address and port
|
25
|
-
def initialize(addr,
|
26
|
-
@
|
43
|
+
def initialize(addr, pdtp_port = DEFAULT_PORT, http_port = pdtp_port + 1)
|
44
|
+
@orig_addr, @port, @http_port = addr, pdtp_port, http_port
|
27
45
|
|
28
|
-
@
|
29
|
-
@
|
46
|
+
@addr = IPSocket.getaddress(@orig_addr)
|
47
|
+
@file_service = FileService.new
|
48
|
+
@dispatcher = Dispatcher.new self, @file_service
|
30
49
|
end
|
31
50
|
|
32
51
|
# Run a web server to display statistics on the given address and port
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
@stats_server = Mongrel::HttpServer.new addr, port
|
38
|
-
@@log.info "Mongrel server listening on port: #{port}"
|
39
|
-
@stats_server.register '/', PDTP::Server::StatsHandler.new(@dispatcher)
|
40
|
-
@stats_server.run
|
52
|
+
def enable_status_page(path = '/status')
|
53
|
+
log "status at http://#{@addr}:#{@http_port}#{path}"
|
54
|
+
http_server.register path, StatusHandler.new(@dispatcher)
|
41
55
|
end
|
42
56
|
|
43
57
|
# Serve files from the given directory
|
44
58
|
def enable_file_service(path, options = {})
|
45
|
-
opts = {
|
46
|
-
:chunk_size => 100000
|
59
|
+
opts = {
|
60
|
+
:chunk_size => 100000,
|
61
|
+
:vhost => @orig_addr
|
47
62
|
}.merge(options)
|
48
63
|
|
49
|
-
@
|
50
|
-
@
|
64
|
+
@file_service.root = path
|
65
|
+
@file_service.default_chunk_size = opts[:chunk_size]
|
66
|
+
@vhost = opts[:vhost]
|
67
|
+
@file_service_enabled = true
|
68
|
+
end
|
69
|
+
|
70
|
+
# Is there an internal file service available for this server?
|
71
|
+
def file_service_enabled?
|
72
|
+
@file_service_enabled
|
73
|
+
end
|
74
|
+
|
75
|
+
# Enable logging
|
76
|
+
def enable_logging(logger = nil)
|
77
|
+
@log = logger || default_logger
|
51
78
|
end
|
52
79
|
|
53
80
|
# Run the PDTP server event loop
|
54
81
|
def run
|
55
|
-
EventMachine
|
56
|
-
EventMachine
|
57
|
-
connection.
|
82
|
+
EventMachine.run do
|
83
|
+
EventMachine.start_server(@addr, @port, Connection) do |connection|
|
84
|
+
connection.dispatcher = @dispatcher
|
58
85
|
connection.connection_completed
|
59
86
|
end
|
87
|
+
|
88
|
+
# Enable the file service if #enable_file_service has been called
|
89
|
+
if file_service_enabled?
|
90
|
+
EventMachine.connect(@addr, @port, PDTP::Server::FileService::Protocol) do |c|
|
91
|
+
# In future versions of EventMachine we'll be able to pass these as parameters to EM.connect
|
92
|
+
base_path, listen_port, vhost, server = @file_service.root, @http_port, @vhost, http_server
|
93
|
+
|
94
|
+
c.instance_eval do
|
95
|
+
@base_path, @listen_port, @vhost, @http_server = base_path, listen_port, vhost, server
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
60
99
|
|
61
|
-
|
62
|
-
|
100
|
+
log "accepting connections on #{@addr}:#{@port}"
|
101
|
+
|
102
|
+
# Start Mongrel in Evented mode if it's been requested
|
103
|
+
http_server.run_evented if @http_server
|
63
104
|
|
64
|
-
EventMachine
|
105
|
+
EventMachine.add_periodic_timer(2) { @dispatcher.clear_all_stalled_transfers }
|
65
106
|
end
|
66
107
|
end
|
108
|
+
|
109
|
+
# Write a message to the server log
|
110
|
+
def log(message, type = :info)
|
111
|
+
return unless @log
|
112
|
+
@log.send type, message
|
113
|
+
end
|
114
|
+
|
115
|
+
# Write a debug message to the server log (ignored in quiet mode)
|
116
|
+
def debug(message)
|
117
|
+
log message, :debug
|
118
|
+
end
|
119
|
+
|
120
|
+
#########
|
121
|
+
protected
|
122
|
+
#########
|
123
|
+
|
124
|
+
def default_logger
|
125
|
+
STDERR.sync = true
|
126
|
+
logger = Logger.new STDERR
|
127
|
+
logger.datetime_format = "%H:%M:%S "
|
128
|
+
logger
|
129
|
+
end
|
130
|
+
|
131
|
+
def http_server
|
132
|
+
# Start a mongrel server on the specified port. If it isnt available, keep trying higher ports
|
133
|
+
# FIXME: Evented Mongrel won't throw an exception if the port is unavailable. This needs to
|
134
|
+
# be dealt with through EventMachine
|
135
|
+
# begin
|
136
|
+
@http_server ||= Mongrel::HttpServer.new @addr, @http_port
|
137
|
+
# rescue
|
138
|
+
# @http_port += 1
|
139
|
+
# retry
|
140
|
+
# end
|
141
|
+
end
|
67
142
|
end
|
68
|
-
end
|
143
|
+
end
|
@@ -1,11 +1,23 @@
|
|
1
1
|
#--
|
2
2
|
# Copyright (C) 2006-07 ClickCaster, Inc. (info@clickcaster.com)
|
3
|
-
#
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
4
16
|
#
|
5
17
|
# This source file is distributed as part of the
|
6
18
|
# DistribuStream file transfer system.
|
7
19
|
#
|
8
|
-
# See http://distribustream.
|
20
|
+
# See http://distribustream.org/
|
9
21
|
#++
|
10
22
|
|
11
23
|
require File.dirname(__FILE__) + '/trust'
|
@@ -1,11 +1,23 @@
|
|
1
1
|
#--
|
2
2
|
# Copyright (C) 2006-07 ClickCaster, Inc. (info@clickcaster.com)
|
3
|
-
#
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
4
16
|
#
|
5
17
|
# This source file is distributed as part of the
|
6
18
|
# DistribuStream file transfer system.
|
7
19
|
#
|
8
|
-
# See http://distribustream.
|
20
|
+
# See http://distribustream.org/
|
9
21
|
#++
|
10
22
|
|
11
23
|
require File.dirname(__FILE__) + '/../common/protocol'
|
@@ -13,22 +25,32 @@ require File.dirname(__FILE__) + '/../common/protocol'
|
|
13
25
|
module PDTP
|
14
26
|
class Server
|
15
27
|
class Connection < PDTP::Protocol
|
16
|
-
attr_accessor :
|
28
|
+
attr_accessor :dispatcher
|
17
29
|
attr_accessor :user_data
|
18
30
|
|
31
|
+
# Is this connection the file service?
|
32
|
+
def file_service?
|
33
|
+
@file_service
|
34
|
+
end
|
35
|
+
|
36
|
+
# Mark this connection as being a file service
|
37
|
+
def mark_as_file_service
|
38
|
+
@file_service = true
|
39
|
+
end
|
40
|
+
|
19
41
|
def connection_completed
|
20
|
-
raise(RuntimeError, 'server was never initialized') unless @
|
21
|
-
@
|
42
|
+
raise(RuntimeError, 'server was never initialized') unless @dispatcher
|
43
|
+
@dispatcher.connection_created self
|
22
44
|
end
|
23
45
|
|
24
46
|
def connection_destroyed
|
25
|
-
raise(RuntimeError, 'server was never initialized') unless @
|
26
|
-
@
|
47
|
+
raise(RuntimeError, 'server was never initialized') unless @dispatcher
|
48
|
+
@dispatcher.connection_destroyed self
|
27
49
|
end
|
28
50
|
|
29
51
|
def receive_message(command, message)
|
30
|
-
raise(RuntimeError, 'server was never initialized') unless @
|
31
|
-
@
|
52
|
+
raise(RuntimeError, 'server was never initialized') unless @dispatcher
|
53
|
+
@dispatcher.dispatch_message command, message, self
|
32
54
|
end
|
33
55
|
end
|
34
56
|
end
|
@@ -1,50 +1,66 @@
|
|
1
1
|
#--
|
2
2
|
# Copyright (C) 2006-07 ClickCaster, Inc. (info@clickcaster.com)
|
3
|
-
#
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
4
16
|
#
|
5
17
|
# This source file is distributed as part of the
|
6
18
|
# DistribuStream file transfer system.
|
7
19
|
#
|
8
|
-
# See http://distribustream.
|
20
|
+
# See http://distribustream.org/
|
9
21
|
#++
|
10
22
|
|
11
23
|
require File.dirname(__FILE__) + '/../common/protocol'
|
12
|
-
require File.dirname(__FILE__) + '/../common/common_init'
|
13
24
|
require File.dirname(__FILE__) + '/file_service'
|
14
25
|
require File.dirname(__FILE__) + '/client_info'
|
15
26
|
require File.dirname(__FILE__) + '/transfer'
|
16
27
|
|
17
|
-
require 'thread'
|
18
|
-
require 'erb'
|
19
|
-
|
20
28
|
module PDTP
|
21
29
|
class Server
|
22
30
|
# Core dispatching and control logic for PDTP servers
|
23
31
|
class Dispatcher
|
24
32
|
attr_reader :connections
|
25
|
-
|
26
|
-
def initialize
|
33
|
+
|
34
|
+
def initialize(server, file_service)
|
35
|
+
@server = server
|
36
|
+
@file_service = file_service
|
27
37
|
@connections = []
|
28
38
|
@used_client_ids = {} #keeps a list of client ids in use, they must be unique
|
29
39
|
@updated_clients = {} #a set of clients that have been modified and need transfers spawned
|
30
|
-
@stats_mutex=Mutex.new
|
31
40
|
end
|
32
41
|
|
33
42
|
#called by pdtp_protocol when a connection is created
|
34
43
|
def connection_created(connection)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
44
|
+
addr, port = connection.get_peer_info
|
45
|
+
|
46
|
+
if @server.file_service_enabled? and not @seen_file_service and addr == @server.addr
|
47
|
+
#display file service greeting when we see it connect
|
48
|
+
@server.log "file service running at #{addr}:#{@server.instance_eval { @http_port }}"
|
49
|
+
@seen_file_service = true
|
50
|
+
connection.mark_as_file_service
|
51
|
+
else
|
52
|
+
#display greeting for normal client
|
53
|
+
@server.log "client connected: #{connection.get_peer_info.inspect}"
|
39
54
|
end
|
55
|
+
|
56
|
+
connection.user_data = ClientInfo.new
|
57
|
+
@connections << connection
|
40
58
|
end
|
41
59
|
|
42
60
|
#called by pdtp_protocol when a connection is destroyed
|
43
61
|
def connection_destroyed(connection)
|
44
|
-
@
|
45
|
-
|
46
|
-
@connections.delete connection
|
47
|
-
end
|
62
|
+
@server.log "client disconnected: #{connection.get_peer_info.inspect}"
|
63
|
+
@connections.delete connection
|
48
64
|
end
|
49
65
|
|
50
66
|
# returns the ClientInfo object associated with this connection
|
@@ -80,12 +96,6 @@ module PDTP
|
|
80
96
|
) if send_response
|
81
97
|
end
|
82
98
|
|
83
|
-
#outstr="#{@ids[transfer.giver]}->#{@ids[transfer.taker]} transfer completed: #{transfer}"
|
84
|
-
#outstr=outstr+" t->g=#{c1.trust.weight(c2.trust)} g->t=#{c2.trust.weight(c1.trust)}"
|
85
|
-
#outstr=outstr+"sent_by: "+ ( connection==transfer.taker ? "taker" : "giver" )
|
86
|
-
#outstr=outstr+" success=#{success} "
|
87
|
-
#@@log.debug(outstr)
|
88
|
-
|
89
99
|
#remove this transfer from whoever sent it
|
90
100
|
client_info(connection).transfers.delete(transfer.transfer_id)
|
91
101
|
@updated_clients[connection]=true #flag this client for transfer creation
|
@@ -206,13 +216,6 @@ module PDTP
|
|
206
216
|
false
|
207
217
|
end
|
208
218
|
|
209
|
-
#called by pdtp_protocol for each message that comes in from the wire
|
210
|
-
def dispatch_message(command, message, connection)
|
211
|
-
@stats_mutex.synchronize do
|
212
|
-
dispatch_message_needslock command, message, connection
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
219
|
#creates new transfers for all clients that have been updated
|
217
220
|
def spawn_all_transfers
|
218
221
|
while @updated_clients.size > 0 do
|
@@ -240,7 +243,7 @@ module PDTP
|
|
240
243
|
end
|
241
244
|
|
242
245
|
#handles all incoming messages from clients
|
243
|
-
def
|
246
|
+
def dispatch_message(command, message, connection)
|
244
247
|
# store the command in the message hash
|
245
248
|
message["type"] = command
|
246
249
|
|
@@ -261,7 +264,7 @@ module PDTP
|
|
261
264
|
client_info(connection).listen_port = message["listen_port"]
|
262
265
|
client_info(connection).client_id = cid
|
263
266
|
when "ask_info"
|
264
|
-
info = file_service.get_info(message["url"])
|
267
|
+
info = @file_service.get_info(message["url"])
|
265
268
|
response = { :url => message["url"] }
|
266
269
|
unless info.nil?
|
267
270
|
response[:size] = info.file_size
|
@@ -277,7 +280,7 @@ module PDTP
|
|
277
280
|
transfer_id=Transfer.gen_transfer_id(my_id,message["peer_id"],message["url"],message["range"])
|
278
281
|
ok = !!client_info(connection).transfers[transfer_id]
|
279
282
|
client_info(connection).transfers[transfer_id].verification_asked=true if ok
|
280
|
-
|
283
|
+
@server.debug "AskVerify not ok: id=#{transfer_id}" unless ok
|
281
284
|
connection.send_message(:tell_verify,
|
282
285
|
:url => message["url"],
|
283
286
|
:peer_id => message["peer_id"],
|
@@ -293,7 +296,7 @@ module PDTP
|
|
293
296
|
message["range"]
|
294
297
|
)
|
295
298
|
transfer=client_info(connection).transfers[transfer_id]
|
296
|
-
|
299
|
+
@server.debug("Completed: id=#{transfer_id} ok=#{transfer != nil}" )
|
297
300
|
if transfer
|
298
301
|
transfer_completed(transfer,connection,message["hash"])
|
299
302
|
else
|
@@ -312,59 +315,6 @@ module PDTP
|
|
312
315
|
#return "#{get_id(c)}: #{host}:#{port}"
|
313
316
|
client_info(c).client_id
|
314
317
|
end
|
315
|
-
|
316
|
-
def generate_html_stats
|
317
|
-
@stats_mutex.synchronize { generate_html_stats_needslock }
|
318
|
-
end
|
319
|
-
|
320
|
-
#builds an html page with information about the server's internal workings
|
321
|
-
def generate_html_stats_needslock
|
322
|
-
s = ERB.new <<EOF
|
323
|
-
<html><head><title>DistribuStream Statistics</title></head>
|
324
|
-
<body>
|
325
|
-
<h1>DistribuStream Statistics</h1>
|
326
|
-
Time=<%= Time.new %><br> Connected Clients=<%= @connections.size %>
|
327
|
-
<center><table border=1>
|
328
|
-
<tr><th>Client</th><th>Transfers</th><th>Files</th></tr>
|
329
|
-
<% @connections.each do |c| %>
|
330
|
-
<tr><td>
|
331
|
-
<% host, port = c.get_peer_info %>
|
332
|
-
<%= connection_name(c) %><br><%= host %>:<%= port %>
|
333
|
-
</td>
|
334
|
-
<td>
|
335
|
-
<%
|
336
|
-
client_info(c).transfers.each do |key,t|
|
337
|
-
if c==t.giver
|
338
|
-
type="UP: "
|
339
|
-
peer=t.taker
|
340
|
-
else
|
341
|
-
type="DOWN: "
|
342
|
-
peer=t.giver
|
343
|
-
end
|
344
|
-
%>
|
345
|
-
<%= type %> id=<%= t.transfer_id %><br>
|
346
|
-
<%
|
347
|
-
end
|
348
|
-
%>
|
349
|
-
</td>
|
350
|
-
<td>
|
351
|
-
<%
|
352
|
-
client_info(c).chunk_info.get_file_stats.each do |fs|
|
353
|
-
%>
|
354
|
-
<%= fs.url %> size=<%= fs.file_chunks %> req=<%= fs.chunks_requested %>
|
355
|
-
prov=<%= fs.chunks_provided %> transf=<%= fs.chunks_transferring %><br>
|
356
|
-
<%
|
357
|
-
end
|
358
|
-
%>
|
359
|
-
</td></tr>
|
360
|
-
<%
|
361
|
-
end
|
362
|
-
%>
|
363
|
-
</table>
|
364
|
-
</body></html>
|
365
|
-
EOF
|
366
|
-
s.result binding
|
367
|
-
end
|
368
318
|
end
|
369
319
|
end
|
370
320
|
end
|