kinetic_sdk 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. checksums.yaml +7 -0
  2. data/GettingStarted.md +64 -0
  3. data/README.md +383 -0
  4. data/bin/console +12 -0
  5. data/bin/setup +8 -0
  6. data/gems/kontena-websocket-client-0.1.1/Gemfile +4 -0
  7. data/gems/kontena-websocket-client-0.1.1/LICENSE +190 -0
  8. data/gems/kontena-websocket-client-0.1.1/README.md +138 -0
  9. data/gems/kontena-websocket-client-0.1.1/Rakefile +6 -0
  10. data/gems/kontena-websocket-client-0.1.1/benchmark/benchmark-client.rb +45 -0
  11. data/gems/kontena-websocket-client-0.1.1/benchmark/benchmark-em.rb +66 -0
  12. data/gems/kontena-websocket-client-0.1.1/benchmark/benchmark.rb +161 -0
  13. data/gems/kontena-websocket-client-0.1.1/benchmark/benchmark.sh +17 -0
  14. data/gems/kontena-websocket-client-0.1.1/benchmark/websocket-echo-server.go +207 -0
  15. data/gems/kontena-websocket-client-0.1.1/examples/websocket-echo-client.rb +80 -0
  16. data/gems/kontena-websocket-client-0.1.1/kontena-websocket-client.gemspec +24 -0
  17. data/gems/kontena-websocket-client-0.1.1/lib/kontena/websocket/client/connection.rb +119 -0
  18. data/gems/kontena-websocket-client-0.1.1/lib/kontena/websocket/client/version.rb +13 -0
  19. data/gems/kontena-websocket-client-0.1.1/lib/kontena/websocket/client.rb +848 -0
  20. data/gems/kontena-websocket-client-0.1.1/lib/kontena/websocket/error.rb +81 -0
  21. data/gems/kontena-websocket-client-0.1.1/lib/kontena/websocket/logging.rb +55 -0
  22. data/gems/kontena-websocket-client-0.1.1/lib/kontena/websocket/openssl_patch.rb +10 -0
  23. data/gems/kontena-websocket-client-0.1.1/lib/kontena-websocket-client.rb +15 -0
  24. data/gems/mime-types-3.1/Code-of-Conduct.rdoc +74 -0
  25. data/gems/mime-types-3.1/Contributing.rdoc +130 -0
  26. data/gems/mime-types-3.1/History.rdoc +658 -0
  27. data/gems/mime-types-3.1/Licence.rdoc +25 -0
  28. data/gems/mime-types-3.1/Manifest.txt +31 -0
  29. data/gems/mime-types-3.1/README.rdoc +202 -0
  30. data/gems/mime-types-3.1/Rakefile +254 -0
  31. data/gems/mime-types-3.1/lib/mime/type/columnar.rb +55 -0
  32. data/gems/mime-types-3.1/lib/mime/type.rb +573 -0
  33. data/gems/mime-types-3.1/lib/mime/types/_columnar.rb +135 -0
  34. data/gems/mime-types-3.1/lib/mime/types/cache.rb +56 -0
  35. data/gems/mime-types-3.1/lib/mime/types/columnar.rb +1 -0
  36. data/gems/mime-types-3.1/lib/mime/types/container.rb +30 -0
  37. data/gems/mime-types-3.1/lib/mime/types/deprecations.rb +32 -0
  38. data/gems/mime-types-3.1/lib/mime/types/full.rb +17 -0
  39. data/gems/mime-types-3.1/lib/mime/types/loader.rb +148 -0
  40. data/gems/mime-types-3.1/lib/mime/types/logger.rb +37 -0
  41. data/gems/mime-types-3.1/lib/mime/types/registry.rb +81 -0
  42. data/gems/mime-types-3.1/lib/mime/types.rb +228 -0
  43. data/gems/mime-types-3.1/lib/mime-types.rb +1 -0
  44. data/gems/mime-types-3.1/test/bad-fixtures/malformed +9 -0
  45. data/gems/mime-types-3.1/test/fixture/json.json +1 -0
  46. data/gems/mime-types-3.1/test/fixture/old-data +9 -0
  47. data/gems/mime-types-3.1/test/fixture/yaml.yaml +55 -0
  48. data/gems/mime-types-3.1/test/minitest_helper.rb +13 -0
  49. data/gems/mime-types-3.1/test/test_mime_type.rb +603 -0
  50. data/gems/mime-types-3.1/test/test_mime_types.rb +161 -0
  51. data/gems/mime-types-3.1/test/test_mime_types_cache.rb +109 -0
  52. data/gems/mime-types-3.1/test/test_mime_types_class.rb +155 -0
  53. data/gems/mime-types-3.1/test/test_mime_types_lazy.rb +43 -0
  54. data/gems/mime-types-3.1/test/test_mime_types_loader.rb +32 -0
  55. data/gems/mime-types-data-3.2016.0521/Code-of-Conduct.md +75 -0
  56. data/gems/mime-types-data-3.2016.0521/Contributing.md +157 -0
  57. data/gems/mime-types-data-3.2016.0521/History.md +351 -0
  58. data/gems/mime-types-data-3.2016.0521/Licence.md +25 -0
  59. data/gems/mime-types-data-3.2016.0521/Manifest.txt +18 -0
  60. data/gems/mime-types-data-3.2016.0521/README.md +61 -0
  61. data/gems/mime-types-data-3.2016.0521/Rakefile +80 -0
  62. data/gems/mime-types-data-3.2016.0521/data/mime-types.json +1 -0
  63. data/gems/mime-types-data-3.2016.0521/data/mime.content_type.column +1964 -0
  64. data/gems/mime-types-data-3.2016.0521/data/mime.docs.column +1964 -0
  65. data/gems/mime-types-data-3.2016.0521/data/mime.encoding.column +1964 -0
  66. data/gems/mime-types-data-3.2016.0521/data/mime.flags.column +1964 -0
  67. data/gems/mime-types-data-3.2016.0521/data/mime.friendly.column +1964 -0
  68. data/gems/mime-types-data-3.2016.0521/data/mime.pext.column +1964 -0
  69. data/gems/mime-types-data-3.2016.0521/data/mime.use_instead.column +1964 -0
  70. data/gems/mime-types-data-3.2016.0521/data/mime.xrefs.column +1964 -0
  71. data/gems/mime-types-data-3.2016.0521/lib/mime/types/data.rb +21 -0
  72. data/gems/mime-types-data-3.2016.0521/lib/mime-types-data.rb +3 -0
  73. data/gems/multipart-post-2.0.0/Gemfile +14 -0
  74. data/gems/multipart-post-2.0.0/History.txt +60 -0
  75. data/gems/multipart-post-2.0.0/Manifest.txt +9 -0
  76. data/gems/multipart-post-2.0.0/README.md +77 -0
  77. data/gems/multipart-post-2.0.0/Rakefile +9 -0
  78. data/gems/multipart-post-2.0.0/lib/composite_io.rb +108 -0
  79. data/gems/multipart-post-2.0.0/lib/multipart_post.rb +9 -0
  80. data/gems/multipart-post-2.0.0/lib/multipartable.rb +29 -0
  81. data/gems/multipart-post-2.0.0/lib/net/http/post/multipart.rb +27 -0
  82. data/gems/multipart-post-2.0.0/lib/parts.rb +96 -0
  83. data/gems/multipart-post-2.0.0/multipart-post.gemspec +22 -0
  84. data/gems/multipart-post-2.0.0/test/multibyte.txt +1 -0
  85. data/gems/multipart-post-2.0.0/test/net/http/post/test_multipart.rb +110 -0
  86. data/gems/multipart-post-2.0.0/test/test_composite_io.rb +115 -0
  87. data/gems/multipart-post-2.0.0/test/test_parts.rb +86 -0
  88. data/gems/parallel-1.12.1/MIT-LICENSE.txt +20 -0
  89. data/gems/parallel-1.12.1/lib/parallel/processor_count.rb +93 -0
  90. data/gems/parallel-1.12.1/lib/parallel/version.rb +3 -0
  91. data/gems/parallel-1.12.1/lib/parallel.rb +500 -0
  92. data/gems/ruby-progressbar-1.9.0/LICENSE.txt +19 -0
  93. data/gems/ruby-progressbar-1.9.0/README.md +38 -0
  94. data/gems/ruby-progressbar-1.9.0/Rakefile +2 -0
  95. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/base.rb +183 -0
  96. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/calculators/length.rb +99 -0
  97. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/calculators/running_average.rb +9 -0
  98. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/components/bar.rb +96 -0
  99. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/components/percentage.rb +29 -0
  100. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/components/rate.rb +43 -0
  101. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/components/time.rb +107 -0
  102. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/components/title.rb +13 -0
  103. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/components.rb +5 -0
  104. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/errors/invalid_progress_error.rb +4 -0
  105. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/format/formatter.rb +27 -0
  106. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/format/molecule.rb +59 -0
  107. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/format/string.rb +36 -0
  108. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/format.rb +3 -0
  109. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/output.rb +68 -0
  110. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/outputs/non_tty.rb +47 -0
  111. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/outputs/null.rb +33 -0
  112. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/outputs/tty.rb +32 -0
  113. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/progress.rb +118 -0
  114. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/refinements/enumerator.rb +25 -0
  115. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/refinements.rb +1 -0
  116. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/throttle.rb +25 -0
  117. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/time.rb +30 -0
  118. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/timer.rb +72 -0
  119. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar/version.rb +3 -0
  120. data/gems/ruby-progressbar-1.9.0/lib/ruby-progressbar.rb +18 -0
  121. data/gems/slugify-1.0.7/README +18 -0
  122. data/gems/slugify-1.0.7/lib/slugify.rb +1012 -0
  123. data/gems/slugify-1.0.7/lib/slugify_string.rb +11 -0
  124. data/gems/slugify-1.0.7/tests/slugify_test.rb +116 -0
  125. data/gems/slugify-1.0.7/tests/string_slugify_test.rb +23 -0
  126. data/gems/websocket-driver-0.6.5/CHANGELOG.md +123 -0
  127. data/gems/websocket-driver-0.6.5/LICENSE.md +22 -0
  128. data/gems/websocket-driver-0.6.5/README.md +369 -0
  129. data/gems/websocket-driver-0.6.5/examples/tcp_server.rb +28 -0
  130. data/gems/websocket-driver-0.6.5/ext/websocket-driver/Makefile +264 -0
  131. data/gems/websocket-driver-0.6.5/ext/websocket-driver/WebsocketMaskService.java +55 -0
  132. data/gems/websocket-driver-0.6.5/ext/websocket-driver/extconf.rb +4 -0
  133. data/gems/websocket-driver-0.6.5/ext/websocket-driver/websocket_mask.bundle +0 -0
  134. data/gems/websocket-driver-0.6.5/ext/websocket-driver/websocket_mask.c +41 -0
  135. data/gems/websocket-driver-0.6.5/ext/websocket-driver/websocket_mask.o +0 -0
  136. data/gems/websocket-driver-0.6.5/lib/websocket/driver/client.rb +140 -0
  137. data/gems/websocket-driver-0.6.5/lib/websocket/driver/draft75.rb +102 -0
  138. data/gems/websocket-driver-0.6.5/lib/websocket/driver/draft76.rb +96 -0
  139. data/gems/websocket-driver-0.6.5/lib/websocket/driver/event_emitter.rb +54 -0
  140. data/gems/websocket-driver-0.6.5/lib/websocket/driver/headers.rb +45 -0
  141. data/gems/websocket-driver-0.6.5/lib/websocket/driver/hybi/frame.rb +20 -0
  142. data/gems/websocket-driver-0.6.5/lib/websocket/driver/hybi/message.rb +31 -0
  143. data/gems/websocket-driver-0.6.5/lib/websocket/driver/hybi.rb +406 -0
  144. data/gems/websocket-driver-0.6.5/lib/websocket/driver/proxy.rb +68 -0
  145. data/gems/websocket-driver-0.6.5/lib/websocket/driver/server.rb +80 -0
  146. data/gems/websocket-driver-0.6.5/lib/websocket/driver/stream_reader.rb +55 -0
  147. data/gems/websocket-driver-0.6.5/lib/websocket/driver.rb +199 -0
  148. data/gems/websocket-driver-0.6.5/lib/websocket/http/headers.rb +112 -0
  149. data/gems/websocket-driver-0.6.5/lib/websocket/http/request.rb +45 -0
  150. data/gems/websocket-driver-0.6.5/lib/websocket/http/response.rb +29 -0
  151. data/gems/websocket-driver-0.6.5/lib/websocket/http.rb +15 -0
  152. data/gems/websocket-driver-0.6.5/lib/websocket/mask.rb +14 -0
  153. data/gems/websocket-driver-0.6.5/lib/websocket/websocket_mask.rb +2 -0
  154. data/gems/websocket-driver-0.6.5/lib/websocket_mask.bundle +0 -0
  155. data/gems/websocket-driver-0.6.5-java/CHANGELOG.md +123 -0
  156. data/gems/websocket-driver-0.6.5-java/LICENSE.md +22 -0
  157. data/gems/websocket-driver-0.6.5-java/README.md +369 -0
  158. data/gems/websocket-driver-0.6.5-java/examples/tcp_server.rb +28 -0
  159. data/gems/websocket-driver-0.6.5-java/ext/websocket-driver/WebsocketMaskService.java +55 -0
  160. data/gems/websocket-driver-0.6.5-java/ext/websocket-driver/extconf.rb +4 -0
  161. data/gems/websocket-driver-0.6.5-java/ext/websocket-driver/websocket_mask.c +41 -0
  162. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/client.rb +140 -0
  163. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/draft75.rb +102 -0
  164. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/draft76.rb +96 -0
  165. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/event_emitter.rb +54 -0
  166. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/headers.rb +45 -0
  167. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/hybi/frame.rb +20 -0
  168. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/hybi/message.rb +31 -0
  169. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/hybi.rb +406 -0
  170. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/proxy.rb +68 -0
  171. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/server.rb +80 -0
  172. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver/stream_reader.rb +55 -0
  173. data/gems/websocket-driver-0.6.5-java/lib/websocket/driver.rb +199 -0
  174. data/gems/websocket-driver-0.6.5-java/lib/websocket/http/headers.rb +112 -0
  175. data/gems/websocket-driver-0.6.5-java/lib/websocket/http/request.rb +45 -0
  176. data/gems/websocket-driver-0.6.5-java/lib/websocket/http/response.rb +29 -0
  177. data/gems/websocket-driver-0.6.5-java/lib/websocket/http.rb +15 -0
  178. data/gems/websocket-driver-0.6.5-java/lib/websocket/mask.rb +14 -0
  179. data/gems/websocket-driver-0.6.5-java/lib/websocket/websocket_mask.rb +2 -0
  180. data/gems/websocket-driver-0.6.5-java/lib/websocket_mask.jar +0 -0
  181. data/gems/websocket-extensions-0.1.3/CHANGELOG.md +15 -0
  182. data/gems/websocket-extensions-0.1.3/LICENSE.md +20 -0
  183. data/gems/websocket-extensions-0.1.3/README.md +313 -0
  184. data/gems/websocket-extensions-0.1.3/lib/websocket/extensions/parser.rb +111 -0
  185. data/gems/websocket-extensions-0.1.3/lib/websocket/extensions.rb +181 -0
  186. data/lib/kinetic-sdk.rb +1 -0
  187. data/lib/kinetic_sdk/bridgehub/bridgehub-sdk.rb +80 -0
  188. data/lib/kinetic_sdk/bridgehub/lib/access_keys.rb +67 -0
  189. data/lib/kinetic_sdk/bridgehub/lib/bridge.rb +69 -0
  190. data/lib/kinetic_sdk/discussions/discussions-sdk.rb +165 -0
  191. data/lib/kinetic_sdk/discussions/lib/discussions.rb +107 -0
  192. data/lib/kinetic_sdk/discussions/lib/invitations.rb +120 -0
  193. data/lib/kinetic_sdk/discussions/lib/messages.rb +190 -0
  194. data/lib/kinetic_sdk/discussions/lib/meta.rb +14 -0
  195. data/lib/kinetic_sdk/discussions/lib/participants.rb +64 -0
  196. data/lib/kinetic_sdk/discussions/lib/related_items.rb +54 -0
  197. data/lib/kinetic_sdk/discussions/lib/websockets.rb +96 -0
  198. data/lib/kinetic_sdk/filehub/filehub-sdk.rb +80 -0
  199. data/lib/kinetic_sdk/filehub/lib/access_keys.rb +67 -0
  200. data/lib/kinetic_sdk/filehub/lib/filestores.rb +67 -0
  201. data/lib/kinetic_sdk/request_ce/lib/attribute_definitions.rb +153 -0
  202. data/lib/kinetic_sdk/request_ce/lib/bridges.rb +66 -0
  203. data/lib/kinetic_sdk/request_ce/lib/categories.rb +34 -0
  204. data/lib/kinetic_sdk/request_ce/lib/datastore_form.rb +110 -0
  205. data/lib/kinetic_sdk/request_ce/lib/datastore_submissions.rb +157 -0
  206. data/lib/kinetic_sdk/request_ce/lib/form.rb +99 -0
  207. data/lib/kinetic_sdk/request_ce/lib/form_types.rb +51 -0
  208. data/lib/kinetic_sdk/request_ce/lib/jwt.rb +55 -0
  209. data/lib/kinetic_sdk/request_ce/lib/kapp.rb +93 -0
  210. data/lib/kinetic_sdk/request_ce/lib/meta.rb +14 -0
  211. data/lib/kinetic_sdk/request_ce/lib/oauth.rb +37 -0
  212. data/lib/kinetic_sdk/request_ce/lib/security_policy_definitions.rb +157 -0
  213. data/lib/kinetic_sdk/request_ce/lib/space.rb +89 -0
  214. data/lib/kinetic_sdk/request_ce/lib/submissions.rb +215 -0
  215. data/lib/kinetic_sdk/request_ce/lib/system_api.rb +69 -0
  216. data/lib/kinetic_sdk/request_ce/lib/teams.rb +113 -0
  217. data/lib/kinetic_sdk/request_ce/lib/users.rb +245 -0
  218. data/lib/kinetic_sdk/request_ce/lib/webhook_jobs.rb +142 -0
  219. data/lib/kinetic_sdk/request_ce/lib/webhooks.rb +192 -0
  220. data/lib/kinetic_sdk/request_ce/request-ce-sdk.rb +153 -0
  221. data/lib/kinetic_sdk/task/lib/access_keys.rb +94 -0
  222. data/lib/kinetic_sdk/task/lib/categories.rb +190 -0
  223. data/lib/kinetic_sdk/task/lib/config.rb +202 -0
  224. data/lib/kinetic_sdk/task/lib/engine.rb +42 -0
  225. data/lib/kinetic_sdk/task/lib/environment.rb +14 -0
  226. data/lib/kinetic_sdk/task/lib/errors.rb +165 -0
  227. data/lib/kinetic_sdk/task/lib/groups.rb +112 -0
  228. data/lib/kinetic_sdk/task/lib/handlers.rb +105 -0
  229. data/lib/kinetic_sdk/task/lib/health.rb +28 -0
  230. data/lib/kinetic_sdk/task/lib/license.rb +52 -0
  231. data/lib/kinetic_sdk/task/lib/policy_rules.rb +166 -0
  232. data/lib/kinetic_sdk/task/lib/setup.rb +56 -0
  233. data/lib/kinetic_sdk/task/lib/sources.rb +134 -0
  234. data/lib/kinetic_sdk/task/lib/tasks.rb +17 -0
  235. data/lib/kinetic_sdk/task/lib/trees.rb +274 -0
  236. data/lib/kinetic_sdk/task/lib/users.rb +75 -0
  237. data/lib/kinetic_sdk/task/task-sdk.rb +92 -0
  238. data/lib/kinetic_sdk/utils/kinetic-http-headers.rb +150 -0
  239. data/lib/kinetic_sdk/utils/kinetic-http-response.rb +75 -0
  240. data/lib/kinetic_sdk/utils/kinetic-http.rb +552 -0
  241. data/lib/kinetic_sdk/utils/logger.rb +70 -0
  242. data/lib/kinetic_sdk/utils/random.rb +30 -0
  243. data/lib/kinetic_sdk/version.rb +7 -0
  244. data/lib/kinetic_sdk.rb +57 -0
  245. metadata +414 -0
@@ -0,0 +1,406 @@
1
+ module WebSocket
2
+ class Driver
3
+
4
+ class Hybi < Driver
5
+ root = File.expand_path('../hybi', __FILE__)
6
+
7
+ autoload :Frame, root + '/frame'
8
+ autoload :Message, root + '/message'
9
+
10
+ def self.generate_accept(key)
11
+ Base64.strict_encode64(Digest::SHA1.digest(key + GUID))
12
+ end
13
+
14
+ GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
15
+
16
+ BYTE = 0b11111111
17
+ FIN = MASK = 0b10000000
18
+ RSV1 = 0b01000000
19
+ RSV2 = 0b00100000
20
+ RSV3 = 0b00010000
21
+ OPCODE = 0b00001111
22
+ LENGTH = 0b01111111
23
+
24
+ OPCODES = {
25
+ :continuation => 0,
26
+ :text => 1,
27
+ :binary => 2,
28
+ :close => 8,
29
+ :ping => 9,
30
+ :pong => 10
31
+ }
32
+
33
+ OPCODE_CODES = OPCODES.values
34
+ MESSAGE_OPCODES = OPCODES.values_at(:continuation, :text, :binary)
35
+ OPENING_OPCODES = OPCODES.values_at(:text, :binary)
36
+
37
+ ERRORS = {
38
+ :normal_closure => 1000,
39
+ :going_away => 1001,
40
+ :protocol_error => 1002,
41
+ :unacceptable => 1003,
42
+ :encoding_error => 1007,
43
+ :policy_violation => 1008,
44
+ :too_large => 1009,
45
+ :extension_error => 1010,
46
+ :unexpected_condition => 1011
47
+ }
48
+
49
+ ERROR_CODES = ERRORS.values
50
+ DEFAULT_ERROR_CODE = 1000
51
+ MIN_RESERVED_ERROR = 3000
52
+ MAX_RESERVED_ERROR = 4999
53
+
54
+ PACK_FORMATS = {2 => 'n', 8 => 'Q>'}
55
+
56
+ def initialize(socket, options = {})
57
+ super
58
+
59
+ @extensions = ::WebSocket::Extensions.new
60
+ @stage = 0
61
+ @masking = options[:masking]
62
+ @protocols = options[:protocols] || []
63
+ @protocols = @protocols.strip.split(/ *, */) if String === @protocols
64
+ @require_masking = options[:require_masking]
65
+ @ping_callbacks = {}
66
+
67
+ @frame = @message = nil
68
+
69
+ return unless @socket.respond_to?(:env)
70
+
71
+ sec_key = @socket.env['HTTP_SEC_WEBSOCKET_KEY']
72
+ protos = @socket.env['HTTP_SEC_WEBSOCKET_PROTOCOL']
73
+
74
+ @headers['Upgrade'] = 'websocket'
75
+ @headers['Connection'] = 'Upgrade'
76
+ @headers['Sec-WebSocket-Accept'] = Hybi.generate_accept(sec_key)
77
+
78
+ if protos = @socket.env['HTTP_SEC_WEBSOCKET_PROTOCOL']
79
+ protos = protos.split(/ *, */) if String === protos
80
+ @protocol = protos.find { |p| @protocols.include?(p) }
81
+ @headers['Sec-WebSocket-Protocol'] = @protocol if @protocol
82
+ end
83
+ end
84
+
85
+ def version
86
+ "hybi-#{@socket.env['HTTP_SEC_WEBSOCKET_VERSION']}"
87
+ end
88
+
89
+ def add_extension(extension)
90
+ @extensions.add(extension)
91
+ true
92
+ end
93
+
94
+ def parse(chunk)
95
+ @reader.put(chunk)
96
+ buffer = true
97
+ while buffer
98
+ case @stage
99
+ when 0 then
100
+ buffer = @reader.read(1)
101
+ parse_opcode(buffer.getbyte(0)) if buffer
102
+
103
+ when 1 then
104
+ buffer = @reader.read(1)
105
+ parse_length(buffer.getbyte(0)) if buffer
106
+
107
+ when 2 then
108
+ buffer = @reader.read(@frame.length_bytes)
109
+ parse_extended_length(buffer) if buffer
110
+
111
+ when 3 then
112
+ buffer = @reader.read(4)
113
+ if buffer
114
+ @stage = 4
115
+ @frame.masking_key = buffer
116
+ end
117
+
118
+ when 4 then
119
+ buffer = @reader.read(@frame.length)
120
+
121
+ if buffer
122
+ @stage = 0
123
+ emit_frame(buffer)
124
+ end
125
+
126
+ else
127
+ buffer = nil
128
+ end
129
+ end
130
+ end
131
+
132
+ def binary(message)
133
+ frame(message, :binary)
134
+ end
135
+
136
+ def ping(message = '', &callback)
137
+ @ping_callbacks[message] = callback if callback
138
+ frame(message, :ping)
139
+ end
140
+
141
+ def pong(message = '')
142
+ frame(message, :pong)
143
+ end
144
+
145
+ def close(reason = nil, code = nil)
146
+ reason ||= ''
147
+ code ||= ERRORS[:normal_closure]
148
+
149
+ if @ready_state <= 0
150
+ @ready_state = 3
151
+ emit(:close, CloseEvent.new(code, reason))
152
+ true
153
+ elsif @ready_state == 1
154
+ frame(reason, :close, code)
155
+ @ready_state = 2
156
+ true
157
+ else
158
+ false
159
+ end
160
+ end
161
+
162
+ def frame(buffer, type = nil, code = nil)
163
+ return queue([buffer, type, code]) if @ready_state <= 0
164
+ return false unless @ready_state == 1
165
+
166
+ message = Message.new
167
+ frame = Frame.new
168
+ is_text = String === buffer
169
+
170
+ message.rsv1 = message.rsv2 = message.rsv3 = false
171
+ message.opcode = OPCODES[type || (is_text ? :text : :binary)]
172
+
173
+ payload = is_text ? buffer.bytes.to_a : buffer
174
+ payload = [code].pack(PACK_FORMATS[2]).bytes.to_a + payload if code
175
+ message.data = payload.pack('C*')
176
+
177
+ if MESSAGE_OPCODES.include?(message.opcode)
178
+ message = @extensions.process_outgoing_message(message)
179
+ end
180
+
181
+ frame.final = true
182
+ frame.rsv1 = message.rsv1
183
+ frame.rsv2 = message.rsv2
184
+ frame.rsv3 = message.rsv3
185
+ frame.opcode = message.opcode
186
+ frame.masked = !!@masking
187
+ frame.masking_key = SecureRandom.random_bytes(4) if frame.masked
188
+ frame.length = message.data.bytesize
189
+ frame.payload = message.data
190
+
191
+ send_frame(frame)
192
+ true
193
+
194
+ rescue ::WebSocket::Extensions::ExtensionError => error
195
+ fail(:extension_error, error.message)
196
+ end
197
+
198
+ private
199
+
200
+ def send_frame(frame)
201
+ length = frame.length
202
+ buffer = []
203
+ masked = frame.masked ? MASK : 0
204
+
205
+ buffer[0] = (frame.final ? FIN : 0) |
206
+ (frame.rsv1 ? RSV1 : 0) |
207
+ (frame.rsv2 ? RSV2 : 0) |
208
+ (frame.rsv3 ? RSV3 : 0) |
209
+ frame.opcode
210
+
211
+ if length <= 125
212
+ buffer[1] = masked | length
213
+ elsif length <= 65535
214
+ buffer[1] = masked | 126
215
+ buffer[2..3] = [length].pack(PACK_FORMATS[2]).bytes.to_a
216
+ else
217
+ buffer[1] = masked | 127
218
+ buffer[2..9] = [length].pack(PACK_FORMATS[8]).bytes.to_a
219
+ end
220
+
221
+ if frame.masked
222
+ buffer.concat(frame.masking_key.bytes.to_a)
223
+ buffer.concat(Mask.mask(frame.payload, frame.masking_key).bytes.to_a)
224
+ else
225
+ buffer.concat(frame.payload.bytes.to_a)
226
+ end
227
+
228
+ @socket.write(buffer.pack('C*'))
229
+ end
230
+
231
+ def handshake_response
232
+ begin
233
+ extensions = @extensions.generate_response(@socket.env['HTTP_SEC_WEBSOCKET_EXTENSIONS'])
234
+ rescue => error
235
+ fail(:protocol_error, error.message)
236
+ return nil
237
+ end
238
+
239
+ @headers['Sec-WebSocket-Extensions'] = extensions if extensions
240
+
241
+ start = 'HTTP/1.1 101 Switching Protocols'
242
+ headers = [start, @headers.to_s, '']
243
+ headers.join("\r\n")
244
+ end
245
+
246
+ def shutdown(code, reason, error = false)
247
+ @frame = @message = nil
248
+ @stage = 5
249
+ @extensions.close
250
+
251
+ frame(reason, :close, code) if @ready_state < 2
252
+ @ready_state = 3
253
+
254
+ emit(:error, ProtocolError.new(reason)) if error
255
+ emit(:close, CloseEvent.new(code, reason))
256
+ end
257
+
258
+ def fail(type, message)
259
+ return if @ready_state > 1
260
+ shutdown(ERRORS[type], message, true)
261
+ end
262
+
263
+ def parse_opcode(octet)
264
+ rsvs = [RSV1, RSV2, RSV3].map { |rsv| (octet & rsv) == rsv }
265
+
266
+ @frame = Frame.new
267
+
268
+ @frame.final = (octet & FIN) == FIN
269
+ @frame.rsv1 = rsvs[0]
270
+ @frame.rsv2 = rsvs[1]
271
+ @frame.rsv3 = rsvs[2]
272
+ @frame.opcode = (octet & OPCODE)
273
+
274
+ @stage = 1
275
+
276
+ unless @extensions.valid_frame_rsv?(@frame)
277
+ return fail(:protocol_error,
278
+ "One or more reserved bits are on: reserved1 = #{@frame.rsv1 ? 1 : 0}" +
279
+ ", reserved2 = #{@frame.rsv2 ? 1 : 0 }" +
280
+ ", reserved3 = #{@frame.rsv3 ? 1 : 0 }")
281
+ end
282
+
283
+ unless OPCODES.values.include?(@frame.opcode)
284
+ return fail(:protocol_error, "Unrecognized frame opcode: #{@frame.opcode}")
285
+ end
286
+
287
+ unless MESSAGE_OPCODES.include?(@frame.opcode) or @frame.final
288
+ return fail(:protocol_error, "Received fragmented control frame: opcode = #{@frame.opcode}")
289
+ end
290
+
291
+ if @message and OPENING_OPCODES.include?(@frame.opcode)
292
+ return fail(:protocol_error, 'Received new data frame but previous continuous frame is unfinished')
293
+ end
294
+ end
295
+
296
+ def parse_length(octet)
297
+ @frame.masked = (octet & MASK) == MASK
298
+ @frame.length = (octet & LENGTH)
299
+
300
+ if @frame.length >= 0 and @frame.length <= 125
301
+ @stage = @frame.masked ? 3 : 4
302
+ return unless check_frame_length
303
+ else
304
+ @stage = 2
305
+ @frame.length_bytes = (@frame.length == 126) ? 2 : 8
306
+ end
307
+
308
+ if @require_masking and not @frame.masked
309
+ return fail(:unacceptable, 'Received unmasked frame but masking is required')
310
+ end
311
+ end
312
+
313
+ def parse_extended_length(buffer)
314
+ @frame.length = buffer.unpack(PACK_FORMATS[buffer.bytesize]).first
315
+ @stage = @frame.masked ? 3 : 4
316
+
317
+ unless MESSAGE_OPCODES.include?(@frame.opcode) or @frame.length <= 125
318
+ return fail(:protocol_error, "Received control frame having too long payload: #{@frame.length}")
319
+ end
320
+
321
+ return unless check_frame_length
322
+ end
323
+
324
+ def check_frame_length
325
+ length = @message ? @message.data.bytesize : 0
326
+
327
+ if length + @frame.length > @max_length
328
+ fail(:too_large, 'WebSocket frame length too large')
329
+ false
330
+ else
331
+ true
332
+ end
333
+ end
334
+
335
+ def emit_frame(buffer)
336
+ frame = @frame
337
+ opcode = frame.opcode
338
+ payload = frame.payload = Mask.mask(buffer, @frame.masking_key)
339
+ bytesize = payload.bytesize
340
+ bytes = payload.bytes.to_a
341
+
342
+ @frame = nil
343
+
344
+ case opcode
345
+ when OPCODES[:continuation] then
346
+ return fail(:protocol_error, 'Received unexpected continuation frame') unless @message
347
+ @message << frame
348
+
349
+ when OPCODES[:text], OPCODES[:binary] then
350
+ @message = Message.new
351
+ @message << frame
352
+
353
+ when OPCODES[:close] then
354
+ code = (bytesize >= 2) ? payload.unpack(PACK_FORMATS[2]).first : nil
355
+ reason = (bytesize > 2) ? Driver.encode(bytes[2..-1] || [], UNICODE) : nil
356
+
357
+ unless (bytesize == 0) or
358
+ (code && code >= MIN_RESERVED_ERROR && code <= MAX_RESERVED_ERROR) or
359
+ ERROR_CODES.include?(code)
360
+ code = ERRORS[:protocol_error]
361
+ end
362
+
363
+ if bytesize > 125 or (bytesize > 2 and reason.nil?)
364
+ code = ERRORS[:protocol_error]
365
+ end
366
+
367
+ shutdown(code || DEFAULT_ERROR_CODE, reason || '')
368
+
369
+ when OPCODES[:ping] then
370
+ frame(payload, :pong)
371
+
372
+ when OPCODES[:pong] then
373
+ message = Driver.encode(payload, UNICODE)
374
+ callback = @ping_callbacks[message]
375
+ @ping_callbacks.delete(message)
376
+ callback.call if callback
377
+ end
378
+
379
+ emit_message if frame.final and MESSAGE_OPCODES.include?(opcode)
380
+ end
381
+
382
+ def emit_message
383
+ message = @extensions.process_incoming_message(@message)
384
+ @message = nil
385
+
386
+ payload = message.data
387
+
388
+ case message.opcode
389
+ when OPCODES[:text] then
390
+ payload = Driver.encode(payload, UNICODE)
391
+ when OPCODES[:binary]
392
+ payload = payload.bytes.to_a
393
+ end
394
+
395
+ if payload
396
+ emit(:message, MessageEvent.new(payload))
397
+ else
398
+ fail(:encoding_error, 'Could not decode a text frame as UTF-8')
399
+ end
400
+ rescue ::WebSocket::Extensions::ExtensionError => error
401
+ fail(:extension_error, error.message)
402
+ end
403
+ end
404
+
405
+ end
406
+ end
@@ -0,0 +1,68 @@
1
+ module WebSocket
2
+ class Driver
3
+
4
+ class Proxy
5
+ include EventEmitter
6
+
7
+ PORTS = {'ws' => 80, 'wss' => 443}
8
+
9
+ attr_reader :status, :headers
10
+
11
+ def initialize(client, origin, options)
12
+ super()
13
+
14
+ @client = client
15
+ @http = HTTP::Response.new
16
+ @socket = client.instance_variable_get(:@socket)
17
+ @origin = URI.parse(@socket.url)
18
+ @url = URI.parse(origin)
19
+ @options = options
20
+ @state = 0
21
+
22
+ @headers = Headers.new
23
+ @headers['Host'] = @origin.host + (@origin.port ? ":#{@origin.port}" : '')
24
+ @headers['Connection'] = 'keep-alive'
25
+ @headers['Proxy-Connection'] = 'keep-alive'
26
+
27
+ if @url.user
28
+ auth = Base64.strict_encode64([@url.user, @url.password] * ':')
29
+ @headers['Proxy-Authorization'] = 'Basic ' + auth
30
+ end
31
+ end
32
+
33
+ def set_header(name, value)
34
+ return false unless @state == 0
35
+ @headers[name] = value
36
+ true
37
+ end
38
+
39
+ def start
40
+ return false unless @state == 0
41
+ @state = 1
42
+
43
+ port = @origin.port || PORTS[@origin.scheme]
44
+ start = "CONNECT #{@origin.host}:#{port} HTTP/1.1"
45
+ headers = [start, @headers.to_s, '']
46
+
47
+ @socket.write(headers.join("\r\n"))
48
+ true
49
+ end
50
+
51
+ def parse(chunk)
52
+ @http.parse(chunk)
53
+ return unless @http.complete?
54
+
55
+ @status = @http.code
56
+ @headers = Headers.new(@http.headers)
57
+
58
+ if @status == 200
59
+ emit(:connect, ConnectEvent.new)
60
+ else
61
+ message = "Can't establish a connection to the server at #{@socket.url}"
62
+ emit(:error, ProtocolError.new(message))
63
+ end
64
+ end
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,80 @@
1
+ module WebSocket
2
+ class Driver
3
+
4
+ class Server < Driver
5
+ EVENTS = %w[open message error close]
6
+
7
+ def initialize(socket, options = {})
8
+ super
9
+ @http = HTTP::Request.new
10
+ @delegate = nil
11
+ end
12
+
13
+ def env
14
+ @http.complete? ? @http.env : nil
15
+ end
16
+
17
+ def url
18
+ return nil unless e = env
19
+
20
+ url = "ws://#{e['HTTP_HOST']}"
21
+ url << e['PATH_INFO']
22
+ url << "?#{e['QUERY_STRING']}" unless e['QUERY_STRING'] == ''
23
+ url
24
+ end
25
+
26
+ %w[add_extension set_header start frame text binary ping close].each do |method|
27
+ define_method(method) do |*args, &block|
28
+ if @delegate
29
+ @delegate.__send__(method, *args, &block)
30
+ else
31
+ @queue << [method, args, block]
32
+ true
33
+ end
34
+ end
35
+ end
36
+
37
+ %w[protocol version].each do |method|
38
+ define_method(method) do
39
+ @delegate && @delegate.__send__(method)
40
+ end
41
+ end
42
+
43
+ def parse(chunk)
44
+ return @delegate.parse(chunk) if @delegate
45
+
46
+ @http.parse(chunk)
47
+ return fail_request('Invalid HTTP request') if @http.error?
48
+ return unless @http.complete?
49
+
50
+ @delegate = Driver.rack(self, @options)
51
+ open
52
+
53
+ EVENTS.each do |event|
54
+ @delegate.on(event) { |e| emit(event, e) }
55
+ end
56
+
57
+ emit(:connect, ConnectEvent.new)
58
+ end
59
+
60
+ def write(buffer)
61
+ @socket.write(buffer)
62
+ end
63
+
64
+ private
65
+
66
+ def fail_request(message)
67
+ emit(:error, ProtocolError.new(message))
68
+ emit(:close, CloseEvent.new(Hybi::ERRORS[:protocol_error], message))
69
+ end
70
+
71
+ def open
72
+ @queue.each do |method, args, block|
73
+ @delegate.__send__(method, *args, &block)
74
+ end
75
+ @queue = []
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,55 @@
1
+ module WebSocket
2
+ class Driver
3
+
4
+ class StreamReader
5
+ # Try to minimise the number of reallocations done:
6
+ MINIMUM_AUTOMATIC_PRUNE_OFFSET = 128
7
+
8
+ def initialize
9
+ @buffer = String.new('').force_encoding(BINARY)
10
+ @offset = 0
11
+ end
12
+
13
+ def put(chunk)
14
+ return unless chunk and chunk.bytesize > 0
15
+ @buffer << chunk.force_encoding(BINARY)
16
+ end
17
+
18
+ # Read bytes from the data:
19
+ def read(length)
20
+ return nil if (@offset + length) > @buffer.bytesize
21
+
22
+ chunk = @buffer.byteslice(@offset, length)
23
+ @offset += chunk.bytesize
24
+
25
+ prune if @offset > MINIMUM_AUTOMATIC_PRUNE_OFFSET
26
+
27
+ return chunk
28
+ end
29
+
30
+ def each_byte
31
+ prune
32
+
33
+ @buffer.each_byte do |octet|
34
+ @offset += 1
35
+ yield octet
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def prune
42
+ buffer_size = @buffer.bytesize
43
+
44
+ if @offset > buffer_size
45
+ @buffer = String.new('').force_encoding(BINARY)
46
+ else
47
+ @buffer = @buffer.byteslice(@offset, buffer_size - @offset)
48
+ end
49
+
50
+ @offset = 0
51
+ end
52
+ end
53
+
54
+ end
55
+ end