mtproto 0.0.1 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c498fa937d08bb1896de2e69cfa96130b5d4fb6b1dae44761f8251ef426a03b5
4
- data.tar.gz: ffc71857dcdf59248a9fd41750110a632db075558a8362780439fba2fc751d56
3
+ metadata.gz: fa11aaca7c34af33346fa59458bf300211785023ff833336738b0988deeafc32
4
+ data.tar.gz: 417cef055fd9d042956880f8e0214a10669759d7881e3af67e15e3bd2018de6c
5
5
  SHA512:
6
- metadata.gz: 88b02a01b90bbfe65077bf9b0318ad95559a3933cd735f4e9bb11eee254864479f20cb15edb52b3f3ba6b972e779f4367318742b2d165498161779628ec64643
7
- data.tar.gz: 30c8ea708f0b32d17c0a621cb7251a7eb1ea34450ceb3036340bd9989a86dc294aedab892030b72def482e3690fc16669457233b60471d2c4a6eb325d15b1b4f
6
+ metadata.gz: 630dadd58d377ed2342abddf659385e8864fbfca3e6c4e1e9fa5a861b29a7a4fcb7628f9e3c7341c716588c5b37c18944d14e954cf0304ced52fa8482dcf859b
7
+ data.tar.gz: 796286ff4a5b9b9a42d7b0c14616040f3b8e0b310c2afece12943f49c14622d1f82f5b4479ef23b47fa6cabd3216b95aa16d0eb1ba4459cddab039042b94dd2a
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module Transport
5
+ class AbridgedPacketCodec
6
+ TAG = "\xef".b
7
+ OBFUSCATE_TAG = "\xef\xef\xef\xef".b
8
+
9
+ def encode_packet(data)
10
+ length = data.bytesize >> 2
11
+
12
+ length_prefix = if length < 127
13
+ [length].pack('C')
14
+ else
15
+ "\x7f".b + [length].pack('L<')[0, 3]
16
+ end
17
+
18
+ length_prefix + data
19
+ end
20
+
21
+ def decode_packet(data)
22
+ length = data.unpack1('C')
23
+ offset = 1
24
+
25
+ if length >= 127
26
+ length = (data[1, 3] + "\x00").unpack1('L<')
27
+ offset = 4
28
+ end
29
+
30
+ actual_length = length << 2
31
+ data[offset, actual_length]
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'socket'
4
+ require 'timeout'
5
+
6
+ module MTProto
7
+ module Transport
8
+ class ConnectionError < StandardError; end
9
+
10
+ class TCPConnection
11
+ attr_reader :host, :port, :codec
12
+
13
+ def initialize(host, port, codec)
14
+ @host = host
15
+ @port = port
16
+ @codec = codec
17
+ @socket = nil
18
+ end
19
+
20
+ def connect
21
+ return if connected?
22
+
23
+ @socket = TCPSocket.new(@host, @port)
24
+
25
+ send_init_tag if @codec.class.const_defined?(:TAG)
26
+ end
27
+
28
+ def connected?
29
+ !@socket.nil? && !@socket.closed?
30
+ end
31
+
32
+ def send(data)
33
+ raise ConnectionError, 'Not connected' unless connected?
34
+
35
+ encoded = @codec.encode_packet(data)
36
+ @socket.write(encoded)
37
+ end
38
+
39
+ def recv(timeout: 60)
40
+ raise ConnectionError, 'Not connected' unless connected?
41
+
42
+ Timeout.timeout(timeout) do
43
+ read_packet
44
+ end
45
+ rescue Timeout::Error
46
+ raise ConnectionError, 'Receive timeout'
47
+ end
48
+
49
+ def close
50
+ return unless @socket
51
+
52
+ @socket.close
53
+ rescue StandardError
54
+ nil
55
+ ensure
56
+ @socket = nil
57
+ end
58
+
59
+ private
60
+
61
+ def send_init_tag
62
+ tag = @codec.class.const_get(:TAG)
63
+ @socket.write(tag) if tag
64
+ end
65
+
66
+ def read_packet
67
+ first_byte = read_exactly(1)
68
+ length = first_byte.unpack1('C')
69
+
70
+ if length >= 127
71
+ length_bytes = read_exactly(3)
72
+ length = (length_bytes + "\x00").unpack1('L<')
73
+ end
74
+
75
+ actual_length = length << 2
76
+ read_exactly(actual_length)
77
+ end
78
+
79
+ def read_exactly(bytes_needed)
80
+ result = ''.b
81
+ while result.bytesize < bytes_needed
82
+ chunk = @socket.read(bytes_needed - result.bytesize)
83
+ raise ConnectionError, 'EOF while reading' if chunk.nil? || chunk.empty?
84
+
85
+ result += chunk
86
+ end
87
+ result
88
+ end
89
+ end
90
+ end
91
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MTProto
4
- VERSION = '0.0.1'
5
- end
4
+ VERSION = '0.0.3'
5
+ end
data/lib/mtproto.rb ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'mtproto/version'
4
+ require_relative 'mtproto/transport/abridged_packet_codec'
5
+ require_relative 'mtproto/transport/tcp_connection'
6
+
7
+ module MTProto
8
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mtproto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Levenkov
@@ -19,6 +19,9 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - ".ruby-version"
21
21
  - Rakefile
22
+ - lib/mtproto.rb
23
+ - lib/mtproto/transport/abridged_packet_codec.rb
24
+ - lib/mtproto/transport/tcp_connection.rb
22
25
  - lib/mtproto/version.rb
23
26
  homepage: https://github.com/alev-pro/mtproto-ruby
24
27
  licenses: