rubtella 0.0.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/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ log
data/README ADDED
@@ -0,0 +1,5 @@
1
+ This is (will be) ruby client for gnutella network.
2
+
3
+ I'm doing it as my university project.
4
+
5
+ I haven't found any working ruby library for gnutella yet so I hope this one will be first :)
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
data/config/config.rb ADDED
@@ -0,0 +1,19 @@
1
+ module Rubtella
2
+ module Config
3
+
4
+ # generating guid
5
+ def self.generate_guid
6
+ guid = Array.new
7
+ 16.times { guid << rand(255)}
8
+
9
+ guid
10
+ end
11
+
12
+ IP_ADDRESS = "195.150.93.207"
13
+ PORT = 54321
14
+ GUID = generate_guid
15
+
16
+
17
+
18
+ end
19
+ end
data/lib/errors.rb ADDED
@@ -0,0 +1,4 @@
1
+ module Rubtella
2
+ class UnknownPayload < StandardError;end
3
+ class RubtellaError < StandardError;end
4
+ end
data/lib/http_data.rb ADDED
@@ -0,0 +1,53 @@
1
+ module Rubtella
2
+ module HTTPData
3
+ class Builder
4
+ attr_accessor :status, :headers, :data
5
+
6
+ def initialize status = "", headers = nil, data = ""
7
+ @status = String.new status
8
+ @headers = headers
9
+ @data = String.new data
10
+ end
11
+
12
+ def build
13
+ @http_data = Array.new
14
+ @http_data << @status
15
+ @http_data << "\r\n"
16
+ @headers.each {|k,v| @http_data << "#{k}: #{v}\r\n"}
17
+ @http_data << "\r\n"
18
+ @http_data << @data
19
+ @http_data.to_s
20
+ end
21
+ end
22
+
23
+ class Parser
24
+
25
+
26
+ attr_accessor :status, :headers, :data, :http_data, :peers
27
+
28
+ def initialize http_data
29
+ @http_data = http_data
30
+ parse
31
+ end
32
+
33
+ def parse
34
+ @headers = Hash.new
35
+ @peers = Array.new
36
+
37
+ headers, @data = @http_data.split("\r\n\r\n")
38
+ headers = headers.split("\r\n")
39
+ @status = headers.shift
40
+ headers.each {|h| k,v = h.split(": "); @headers[k] = v}
41
+ if up = @headers["X-Try-Ultrapeers"]
42
+ up.split(",").each {|u| ip,port = u.split(":"); @peers << Peer.new(ip,port)}
43
+
44
+ end
45
+
46
+ end
47
+
48
+ def ok?
49
+ @status =~ /200 OK/
50
+ end
51
+ end
52
+ end
53
+ end
data/lib/logger.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'ruby-growl'
3
+ require 'logger'
4
+
5
+ class RubtellaLogger
6
+
7
+ def initialize
8
+ @rubylogger = init_logger
9
+ @growl = init_growl
10
+ end
11
+
12
+ def init_logger
13
+ log = Logger.new('log/rubtella.log')
14
+ log.level = Logger::INFO
15
+ log.formatter = proc{|s,t,p,m|"%5s [%s] (%s) %s :: %s\n" % [s, t.strftime("%Y-%m-%d %H:%M:%S"), $$, p, m]}
16
+ return log
17
+ end
18
+
19
+ def init_growl
20
+ g = Growl.new "localhost", "rubtela",
21
+ ["rubtella log"]
22
+ return g
23
+ end
24
+
25
+ def info(message)
26
+ begin
27
+ @rubylogger.info message
28
+ @growl.notify "rubtella log", "Rubtella", message
29
+ rescue
30
+ puts 'logger error'
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ @@logger = RubtellaLogger.new
data/lib/peer.rb ADDED
@@ -0,0 +1,11 @@
1
+ module Rubtella
2
+ class Peer
3
+ attr_accessor :ip, :port
4
+
5
+ def initialize(ip, port)
6
+ @ip = ip
7
+ @port = port.to_i
8
+ end
9
+
10
+ end
11
+ end
data/lib/rubtella.rb ADDED
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/ruby
2
+ # ruby gnutella client
3
+
4
+ require 'socket'
5
+ require 'timeout'
6
+ require 'lib/logger'
7
+ require 'rubygems'
8
+ require 'ruby-debug'
9
+
10
+
11
+
12
+ module Rubtella
13
+
14
+ GNUTELLA_REQUEST = "GNUTELLA CONNECT/0.6"
15
+ GNUTELLA_RESPONSE_OK = "GNUTELLA/0.6 200 OK"
16
+
17
+
18
+
19
+ class Listener
20
+
21
+ include Socket::Constants
22
+
23
+ #listen for connection
24
+ def listen
25
+ server = TCPServer.new("0.0.0.0", PORT)
26
+
27
+
28
+ while (session = server.accept)
29
+
30
+
31
+ Thread.start do
32
+
33
+ begin
34
+ parse_request session
35
+ rescue => e
36
+ session.puts "Rubtella Server Error: " + e.to_s
37
+ puts "Rubtella Server Error: " + e.to_s
38
+ ensure
39
+ session.close
40
+ end
41
+
42
+ end
43
+ end #end loop
44
+
45
+ end
46
+
47
+ def parse_request request
48
+ req = request.recv 1000
49
+
50
+ puts req
51
+ request.send Sender.pong, 0
52
+ puts 'response send!'
53
+ req = request.recv 1000
54
+ puts 'received content:'
55
+
56
+ puts req
57
+ puts 'received!'
58
+ end
59
+
60
+ end
61
+
62
+ class Sender
63
+
64
+
65
+ attr_accessor :peer, :connected
66
+
67
+ def initialize peer
68
+ @peer = peer
69
+ @standard_headers = {"User-Agent" => "Rubtella",
70
+ "X-Ultrapeer" => "False",
71
+ "X-Query-Routing" => "0.1"}
72
+ end
73
+
74
+ def connect
75
+ begin
76
+ puts "connecting to: #{@peer.ip}:#{@peer.port}"
77
+ stream = TCPSocket.new @peer.ip, @peer.port
78
+ timeout(5) do
79
+ stream.send handshake_req, 0
80
+ end
81
+ @response = stream.recv 1000
82
+
83
+ resp = HTTPData::Parser.new @response
84
+ stream.send handshake_resp, 0
85
+
86
+ if resp.ok?
87
+ #connection established
88
+ puts 'connection established'
89
+ @connected = @peer
90
+ puts "Connected with #{@connected.ip} #{@connected.port}"
91
+ @@logger.info "Connected with #{@connected.ip} #{@connected.port}"
92
+
93
+ manage_connection stream
94
+ else
95
+ puts 'failed to connect'
96
+ @peer = resp.peers.shift
97
+ connect
98
+ end
99
+ rescue Timeout::Error
100
+ @peer = resp.peers.shift
101
+ connect
102
+ rescue => e
103
+ @@logger.info e.to_s
104
+ end
105
+ end
106
+
107
+ def handshake_req
108
+ req = HTTPData::Builder.new GNUTELLA_REQUEST, @standard_headers
109
+ req.build
110
+ end
111
+
112
+ def handshake_resp
113
+ resp = HTTPData::Builder.new GNUTELLA_RESPONSE_OK, @standard_headers
114
+ resp.build
115
+ end
116
+
117
+ def manage_connection stream
118
+ loop do
119
+ puts 'we\'re listening..'
120
+ resp = stream.recv 1000
121
+ if parse(resp) == "ping"
122
+ pong = TCPData::Builder::Pong.new
123
+ stream.send pong.build , 0
124
+ puts 'pong send..'
125
+ stream.close
126
+ puts 'connection closed'
127
+ break
128
+ end
129
+ end
130
+
131
+
132
+
133
+ end
134
+
135
+ def parse message
136
+ parsed = TCPData::Parser.new message
137
+ puts parsed.message
138
+
139
+ parsed.message
140
+
141
+ end
142
+
143
+ def send_query(text)
144
+ stream = TCPSocket.new @connected.ip, @connected.port
145
+ query = TCPData::Builder::Query.new(:criteria => text)
146
+ @@logger.info "sending query - #{text}"
147
+ stream.send query.build, 0
148
+ puts 'we\'re listening..'
149
+ resp = stream.recv 1000
150
+ parse(resp)
151
+ end
152
+ end
153
+
154
+ end
data/lib/tcp_data.rb ADDED
@@ -0,0 +1,155 @@
1
+ require 'config/config'
2
+
3
+ module Rubtella
4
+ module TCPData
5
+ class Base
6
+ include Rubtella::Config
7
+ attr_accessor :guid, :payload_type, :ttl, :hops, :payload_lenght, :binary_data, :messages, :messages_codes, :rest
8
+
9
+ @messages ={"\000" => "ping",
10
+ "\001" => "pong",
11
+ "\100" => "push",
12
+ "\200" => "query",
13
+ "\201" => "query_hit"}
14
+
15
+ @messages.default = "Unknown Payload Type"
16
+
17
+ @messages_codes = {"ping" => 0,
18
+ "pong" => 1,
19
+ "push" => 64,
20
+ "query" => 128,
21
+ "query_hit" =>129}
22
+
23
+ @messages_codes.default = "Unknown Payload Type"
24
+ end
25
+
26
+ class Builder < Base
27
+ def init_messages_codes
28
+ @messages_codes = {"ping" => 0,
29
+ "pong" => 1,
30
+ "push" => 64,
31
+ "query" => 128,
32
+ "query_hit" =>129}
33
+
34
+ @messages_codes.default = "Unknown Payload Type"
35
+ end
36
+
37
+
38
+ def initialize
39
+ #initailze all stuff
40
+ init_messages_codes
41
+
42
+ @guid = GUID
43
+ @ttl = 5
44
+ @hops = 0
45
+ @payload_length = 0
46
+ end
47
+
48
+ def build
49
+ @data = Array.new
50
+ @guid = GUID
51
+
52
+ build_message
53
+
54
+ @data = [@guid, @payload_type, @ttl, @hops, @payload_length, @payload]
55
+
56
+ @binary_data = @data.flatten.pack("C*")
57
+ @binary_data
58
+ end
59
+
60
+ def build_message
61
+ # this method needs to be implemented by a child class
62
+ @payload = []
63
+ end
64
+
65
+
66
+ class Ping < Builder
67
+ def initialize args = nil
68
+ super()
69
+
70
+ @payload_type = @messages_codes["ping"]
71
+ end
72
+ end
73
+
74
+ class Pong < Builder
75
+
76
+ attr_accessor :ip_address , :port
77
+
78
+ def initialize args = nil
79
+ super()
80
+
81
+ @payload_type = @messages_codes["pong"]
82
+ @port = build_port PORT
83
+ @ip_address = build_ip IP_ADDRESS
84
+ @files_amount = [0,0,0]
85
+ @files_size = [0,0,0]
86
+
87
+ end
88
+
89
+ def build_message
90
+ @payload = [@port, @ip_address, @files_amount, @files_size]
91
+ end
92
+
93
+ def build_port(port)
94
+ [port%256, port/256]# .pack("C*")
95
+ end
96
+
97
+ def build_ip(ip_address)
98
+ ip_address.split(".").collect {|b| b.to_i} # .pack("C*")
99
+ end
100
+ end
101
+
102
+ class Query < Builder
103
+
104
+ def initialize args = nil
105
+
106
+ super()
107
+
108
+ @payload_type = @messages_codes["query"]
109
+ @speed = 0
110
+ @criteria = args.is_a?(Hash) ? args[:criteria] : ""
111
+
112
+ end
113
+
114
+ def build_message
115
+ @payload = [@speed, @criteria.unpack("C*")]
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+ class Parser < Base
122
+
123
+ def initialize data
124
+ @binary_data = data
125
+ parse
126
+ end
127
+
128
+ def parse
129
+ @guid = @binary_data[0..15]
130
+ @payload_type = @binary_data[16..16]
131
+ @ttl = @binary_data[17..17]
132
+ @hops = @binary_data[18..18]
133
+ @payload_lenght = @binary_data[19..22]
134
+ @payload = @binary_data[23..-1]
135
+ end
136
+
137
+ def message
138
+ case @payload_type
139
+ when "\000"
140
+ "ping"
141
+ when "\001"
142
+ "pong"
143
+ when "\100"
144
+ "push"
145
+ when "\200"
146
+ "query"
147
+ when "\201"
148
+ "query"
149
+ else
150
+ raise "Unknown Payload Type"
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
data/rubtella.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'config/config'
2
+ require 'lib/errors'
3
+ require 'lib/peer'
4
+ require 'lib/tcp_data'
5
+ require 'lib/http_data'
6
+ require 'lib/rubtella'
data/rubtellad.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'rubtella'
2
+
3
+ $0 = 'rubtella-base'
4
+
5
+ @p = fork do
6
+ $0 = 'rubtella'
7
+ Thread.new do
8
+ server = Rubtella::Listener.new
9
+ server.listen
10
+ end
11
+
12
+ Thread.new do
13
+ gnutella = Rubtella::Sender.new Rubtella::Peer.new("70.188.16.73",38093)
14
+ gnutella.connect
15
+ gnutella.send_query("doors")
16
+ end
17
+
18
+ while true
19
+ sleep 100
20
+ end
21
+ end
22
+
23
+ Process.detach(@p)
24
+
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubtella
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mateusz Zawisza
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-10 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Library for Gnuttale in Ruby
17
+ email: mateusz.zawisza@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - .gitignore
26
+ - README
27
+ - VERSION
28
+ - config/config.rb
29
+ - lib/errors.rb
30
+ - lib/http_data.rb
31
+ - lib/logger.rb
32
+ - lib/peer.rb
33
+ - lib/rubtella.rb
34
+ - lib/tcp_data.rb
35
+ - rubtella.rb
36
+ - rubtellad.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/mateuszzawisza/rubtella/
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Library for Gnuttale in Ruby
65
+ test_files: []
66
+