kinetic_sdk 0.1.1

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.
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,140 @@
1
+ module WebSocket
2
+ class Driver
3
+
4
+ class Client < Hybi
5
+ VALID_SCHEMES = %w[ws wss]
6
+
7
+ def self.generate_key
8
+ Base64.strict_encode64(SecureRandom.random_bytes(16))
9
+ end
10
+
11
+ attr_reader :status, :headers
12
+
13
+ def initialize(socket, options = {})
14
+ super
15
+
16
+ @ready_state = -1
17
+ @key = Client.generate_key
18
+ @accept = Hybi.generate_accept(@key)
19
+ @http = HTTP::Response.new
20
+
21
+ uri = URI.parse(@socket.url)
22
+ unless VALID_SCHEMES.include?(uri.scheme)
23
+ raise URIError, "#{socket.url} is not a valid WebSocket URL"
24
+ end
25
+
26
+ host = uri.host + (uri.port ? ":#{uri.port}" : '')
27
+ path = (uri.path == '') ? '/' : uri.path
28
+ @pathname = path + (uri.query ? '?' + uri.query : '')
29
+
30
+ @headers['Host'] = host
31
+ @headers['Upgrade'] = 'websocket'
32
+ @headers['Connection'] = 'Upgrade'
33
+ @headers['Sec-WebSocket-Key'] = @key
34
+ @headers['Sec-WebSocket-Version'] = '13'
35
+
36
+ if @protocols.size > 0
37
+ @headers['Sec-WebSocket-Protocol'] = @protocols * ', '
38
+ end
39
+
40
+ if uri.user
41
+ auth = Base64.strict_encode64([uri.user, uri.password] * ':')
42
+ @headers['Authorization'] = 'Basic ' + auth
43
+ end
44
+ end
45
+
46
+ def version
47
+ 'hybi-13'
48
+ end
49
+
50
+ def proxy(origin, options = {})
51
+ Proxy.new(self, origin, options)
52
+ end
53
+
54
+ def start
55
+ return false unless @ready_state == -1
56
+ @socket.write(handshake_request)
57
+ @ready_state = 0
58
+ true
59
+ end
60
+
61
+ def parse(chunk)
62
+ return if @ready_state == 3
63
+ return super if @ready_state > 0
64
+
65
+ @http.parse(chunk)
66
+ return fail_handshake('Invalid HTTP response') if @http.error?
67
+ return unless @http.complete?
68
+
69
+ validate_handshake
70
+ return if @ready_state == 3
71
+
72
+ open
73
+ parse(@http.body)
74
+ end
75
+
76
+ private
77
+
78
+ def handshake_request
79
+ extensions = @extensions.generate_offer
80
+ @headers['Sec-WebSocket-Extensions'] = extensions if extensions
81
+
82
+ start = "GET #{@pathname} HTTP/1.1"
83
+ headers = [start, @headers.to_s, '']
84
+ headers.join("\r\n")
85
+ end
86
+
87
+ def fail_handshake(message)
88
+ message = "Error during WebSocket handshake: #{message}"
89
+ @ready_state = 3
90
+ emit(:error, ProtocolError.new(message))
91
+ emit(:close, CloseEvent.new(ERRORS[:protocol_error], message))
92
+ end
93
+
94
+ def validate_handshake
95
+ @status = @http.code
96
+ @headers = Headers.new(@http.headers)
97
+
98
+ unless @http.code == 101
99
+ return fail_handshake("Unexpected response code: #{@http.code}")
100
+ end
101
+
102
+ upgrade = @http['Upgrade'] || ''
103
+ connection = @http['Connection'] || ''
104
+ accept = @http['Sec-WebSocket-Accept'] || ''
105
+ protocol = @http['Sec-WebSocket-Protocol'] || ''
106
+
107
+ if upgrade == ''
108
+ return fail_handshake("'Upgrade' header is missing")
109
+ elsif upgrade.downcase != 'websocket'
110
+ return fail_handshake("'Upgrade' header value is not 'WebSocket'")
111
+ end
112
+
113
+ if connection == ''
114
+ return fail_handshake("'Connection' header is missing")
115
+ elsif connection.downcase != 'upgrade'
116
+ return fail_handshake("'Connection' header value is not 'Upgrade'")
117
+ end
118
+
119
+ unless accept == @accept
120
+ return fail_handshake('Sec-WebSocket-Accept mismatch')
121
+ end
122
+
123
+ unless protocol == ''
124
+ if @protocols.include?(protocol)
125
+ @protocol = protocol
126
+ else
127
+ return fail_handshake('Sec-WebSocket-Protocol mismatch')
128
+ end
129
+ end
130
+
131
+ begin
132
+ @extensions.activate(@headers['Sec-WebSocket-Extensions'])
133
+ rescue ::WebSocket::Extensions::ExtensionError => error
134
+ return fail_handshake(error.message)
135
+ end
136
+ end
137
+ end
138
+
139
+ end
140
+ end
@@ -0,0 +1,102 @@
1
+ module WebSocket
2
+ class Driver
3
+
4
+ class Draft75 < Driver
5
+ def initialize(socket, options = {})
6
+ super
7
+
8
+ @stage = 0
9
+ @closing = false
10
+
11
+ @headers['Upgrade'] = 'WebSocket'
12
+ @headers['Connection'] = 'Upgrade'
13
+ @headers['WebSocket-Origin'] = @socket.env['HTTP_ORIGIN']
14
+ @headers['WebSocket-Location'] = @socket.url
15
+ end
16
+
17
+ def version
18
+ 'hixie-75'
19
+ end
20
+
21
+ def close(reason = nil, code = nil)
22
+ return false if @ready_state == 3
23
+ @ready_state = 3
24
+ emit(:close, CloseEvent.new(nil, nil))
25
+ true
26
+ end
27
+
28
+ def parse(chunk)
29
+ return if @ready_state > 1
30
+
31
+ @reader.put(chunk)
32
+
33
+ @reader.each_byte do |octet|
34
+ case @stage
35
+ when -1 then
36
+ @body << octet
37
+ send_handshake_body
38
+
39
+ when 0 then
40
+ parse_leading_byte(octet)
41
+
42
+ when 1 then
43
+ @length = (octet & 0x7F) + 128 * @length
44
+
45
+ if @closing and @length.zero?
46
+ return close
47
+ elsif (octet & 0x80) != 0x80
48
+ if @length.zero?
49
+ @stage = 0
50
+ else
51
+ @skipped = 0
52
+ @stage = 2
53
+ end
54
+ end
55
+
56
+ when 2 then
57
+ if octet == 0xFF
58
+ @stage = 0
59
+ emit(:message, MessageEvent.new(Driver.encode(@buffer, UNICODE)))
60
+ else
61
+ if @length
62
+ @skipped += 1
63
+ @stage = 0 if @skipped == @length
64
+ else
65
+ @buffer << octet
66
+ return close if @buffer.size > @max_length
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ def frame(buffer, type = nil, error_type = nil)
74
+ return queue([buffer, type, error_type]) if @ready_state == 0
75
+ frame = [0x00, buffer, 0xFF].pack('CA*C')
76
+ @socket.write(frame)
77
+ true
78
+ end
79
+
80
+ private
81
+
82
+ def handshake_response
83
+ start = 'HTTP/1.1 101 Web Socket Protocol Handshake'
84
+ headers = [start, @headers.to_s, '']
85
+ headers.join("\r\n")
86
+ end
87
+
88
+ def parse_leading_byte(octet)
89
+ if (octet & 0x80) == 0x80
90
+ @length = 0
91
+ @stage = 1
92
+ else
93
+ @length = nil
94
+ @skipped = nil
95
+ @buffer = []
96
+ @stage = 2
97
+ end
98
+ end
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,96 @@
1
+ module WebSocket
2
+ class Driver
3
+
4
+ class Draft76 < Draft75
5
+ BODY_SIZE = 8
6
+
7
+ def initialize(socket, options = {})
8
+ super
9
+ input = @socket.env['rack.input']
10
+ @stage = -1
11
+ @body = (input ? input.read : String.new('')).force_encoding(BINARY)
12
+
13
+ @headers.clear
14
+ @headers['Upgrade'] = 'WebSocket'
15
+ @headers['Connection'] = 'Upgrade'
16
+ @headers['Sec-WebSocket-Origin'] = @socket.env['HTTP_ORIGIN']
17
+ @headers['Sec-WebSocket-Location'] = @socket.url
18
+ end
19
+
20
+ def version
21
+ 'hixie-76'
22
+ end
23
+
24
+ def start
25
+ return false unless super
26
+ send_handshake_body
27
+ true
28
+ end
29
+
30
+ def close(reason = nil, code = nil)
31
+ return false if @ready_state == 3
32
+ @socket.write([0xFF, 0x00].pack('C*'))
33
+ @ready_state = 3
34
+ emit(:close, CloseEvent.new(nil, nil))
35
+ true
36
+ end
37
+
38
+ private
39
+
40
+ def handshake_response
41
+ env = @socket.env
42
+
43
+ key1 = env['HTTP_SEC_WEBSOCKET_KEY1']
44
+ number1 = number_from_key(key1)
45
+ spaces1 = spaces_in_key(key1)
46
+
47
+ key2 = env['HTTP_SEC_WEBSOCKET_KEY2']
48
+ number2 = number_from_key(key2)
49
+ spaces2 = spaces_in_key(key2)
50
+
51
+ if number1 % spaces1 != 0 or number2 % spaces2 != 0
52
+ emit(:error, ProtocolError.new('Client sent invalid Sec-WebSocket-Key headers'))
53
+ close
54
+ return nil
55
+ end
56
+
57
+ @key_values = [number1 / spaces1, number2 / spaces2]
58
+
59
+ start = 'HTTP/1.1 101 WebSocket Protocol Handshake'
60
+ headers = [start, @headers.to_s, '']
61
+ headers.join("\r\n")
62
+ end
63
+
64
+ def handshake_signature
65
+ return nil unless @body.bytesize >= BODY_SIZE
66
+
67
+ head = @body[0...BODY_SIZE]
68
+ Digest::MD5.digest((@key_values + [head]).pack('N2A*'))
69
+ end
70
+
71
+ def send_handshake_body
72
+ return unless signature = handshake_signature
73
+ @socket.write(signature)
74
+ @stage = 0
75
+ open
76
+ parse(@body[BODY_SIZE..-1]) if @body.bytesize > BODY_SIZE
77
+ end
78
+
79
+ def parse_leading_byte(octet)
80
+ return super unless octet == 0xFF
81
+ @closing = true
82
+ @length = 0
83
+ @stage = 1
84
+ end
85
+
86
+ def number_from_key(key)
87
+ key.scan(/[0-9]/).join('').to_i(10)
88
+ end
89
+
90
+ def spaces_in_key(key)
91
+ key.scan(/ /).size
92
+ end
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,54 @@
1
+ module WebSocket
2
+ class Driver
3
+
4
+ module EventEmitter
5
+ def initialize
6
+ @listeners = Hash.new { |h,k| h[k] = [] }
7
+ end
8
+
9
+ def add_listener(event, callable = nil, &block)
10
+ listener = callable || block
11
+ @listeners[event.to_s] << listener
12
+ listener
13
+ end
14
+
15
+ def on(event, callable = nil, &block)
16
+ if callable
17
+ add_listener(event, callable)
18
+ else
19
+ add_listener(event, &block)
20
+ end
21
+ end
22
+
23
+ def remove_listener(event, callable = nil, &block)
24
+ listener = callable || block
25
+ @listeners[event.to_s].delete(listener)
26
+ listener
27
+ end
28
+
29
+ def remove_all_listeners(event = nil)
30
+ if event
31
+ @listeners.delete(event.to_s)
32
+ else
33
+ @listeners.clear
34
+ end
35
+ end
36
+
37
+ def emit(event, *args)
38
+ @listeners[event.to_s].dup.each do |listener|
39
+ listener.call(*args)
40
+ end
41
+ end
42
+
43
+ def listener_count(event)
44
+ return 0 unless @listeners.has_key?(event.to_s)
45
+ @listeners[event.to_s].size
46
+ end
47
+
48
+ def listeners(event)
49
+ @listeners[event.to_s]
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ module WebSocket
2
+ class Driver
3
+
4
+ class Headers
5
+ ALLOWED_DUPLICATES = %w[set-cookie set-cookie2 warning www-authenticate]
6
+
7
+ def initialize(received = {})
8
+ @raw = received
9
+ clear
10
+
11
+ @received = {}
12
+ @raw.each { |k,v| @received[HTTP.normalize_header(k)] = v }
13
+ end
14
+
15
+ def clear
16
+ @sent = Set.new
17
+ @lines = []
18
+ end
19
+
20
+ def [](name)
21
+ @received[HTTP.normalize_header(name)]
22
+ end
23
+
24
+ def []=(name, value)
25
+ return if value.nil?
26
+ key = HTTP.normalize_header(name)
27
+ return unless @sent.add?(key) or ALLOWED_DUPLICATES.include?(key)
28
+ @lines << "#{name.strip}: #{value.to_s.strip}\r\n"
29
+ end
30
+
31
+ def inspect
32
+ @raw.inspect
33
+ end
34
+
35
+ def to_h
36
+ @raw.dup
37
+ end
38
+
39
+ def to_s
40
+ @lines.join('')
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,20 @@
1
+ module WebSocket
2
+ class Driver
3
+ class Hybi
4
+
5
+ class Frame
6
+ attr_accessor :final,
7
+ :rsv1,
8
+ :rsv2,
9
+ :rsv3,
10
+ :opcode,
11
+ :masked,
12
+ :masking_key,
13
+ :length_bytes,
14
+ :length,
15
+ :payload
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ module WebSocket
2
+ class Driver
3
+ class Hybi
4
+
5
+ class Message
6
+ attr_accessor :rsv1,
7
+ :rsv2,
8
+ :rsv3,
9
+ :opcode,
10
+ :data
11
+
12
+ def initialize
13
+ @rsv1 = false
14
+ @rsv2 = false
15
+ @rsv3 = false
16
+ @opcode = nil
17
+ @data = String.new('').force_encoding(BINARY)
18
+ end
19
+
20
+ def <<(frame)
21
+ @rsv1 ||= frame.rsv1
22
+ @rsv2 ||= frame.rsv2
23
+ @rsv3 ||= frame.rsv3
24
+ @opcode ||= frame.opcode
25
+ @data << frame.payload
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end