fluentd 1.20.0-aarch64-mingw-ucrt

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 (341) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +116 -0
  3. data/ADOPTERS.md +5 -0
  4. data/AGENTS.md +46 -0
  5. data/AUTHORS +2 -0
  6. data/CHANGELOG.md +3324 -0
  7. data/CONTRIBUTING.md +45 -0
  8. data/GOVERNANCE.md +55 -0
  9. data/GithubWorkflow.md +78 -0
  10. data/LICENSE +202 -0
  11. data/MAINTAINERS.md +19 -0
  12. data/README.md +73 -0
  13. data/Rakefile +89 -0
  14. data/SECURITY.md +47 -0
  15. data/bin/fluent-binlog-reader +7 -0
  16. data/bin/fluent-ca-generate +6 -0
  17. data/bin/fluent-cap-ctl +7 -0
  18. data/bin/fluent-cat +5 -0
  19. data/bin/fluent-ctl +7 -0
  20. data/bin/fluent-debug +5 -0
  21. data/bin/fluent-gem +9 -0
  22. data/bin/fluent-plugin-config-format +5 -0
  23. data/bin/fluent-plugin-generate +5 -0
  24. data/bin/fluentd +15 -0
  25. data/code-of-conduct.md +3 -0
  26. data/docs/SECURITY_AUDIT.pdf +0 -0
  27. data/example/copy_roundrobin.conf +39 -0
  28. data/example/counter.conf +18 -0
  29. data/example/filter_stdout.conf +22 -0
  30. data/example/in_forward.conf +14 -0
  31. data/example/in_forward_client.conf +37 -0
  32. data/example/in_forward_shared_key.conf +15 -0
  33. data/example/in_forward_tls.conf +14 -0
  34. data/example/in_forward_users.conf +24 -0
  35. data/example/in_forward_workers.conf +21 -0
  36. data/example/in_http.conf +16 -0
  37. data/example/in_out_forward.conf +17 -0
  38. data/example/in_sample_blocks.conf +17 -0
  39. data/example/in_sample_with_compression.conf +23 -0
  40. data/example/in_syslog.conf +15 -0
  41. data/example/in_tail.conf +14 -0
  42. data/example/in_tcp.conf +13 -0
  43. data/example/in_udp.conf +13 -0
  44. data/example/logevents.conf +25 -0
  45. data/example/multi_filters.conf +61 -0
  46. data/example/out_copy.conf +20 -0
  47. data/example/out_exec_filter.conf +42 -0
  48. data/example/out_file.conf +13 -0
  49. data/example/out_forward.conf +35 -0
  50. data/example/out_forward_buf_file.conf +23 -0
  51. data/example/out_forward_client.conf +109 -0
  52. data/example/out_forward_heartbeat_none.conf +16 -0
  53. data/example/out_forward_sd.conf +17 -0
  54. data/example/out_forward_shared_key.conf +36 -0
  55. data/example/out_forward_tls.conf +18 -0
  56. data/example/out_forward_users.conf +65 -0
  57. data/example/out_null.conf +36 -0
  58. data/example/sd.yaml +8 -0
  59. data/example/secondary_file.conf +42 -0
  60. data/example/suppress_config_dump.conf +7 -0
  61. data/example/v0_12_filter.conf +78 -0
  62. data/example/v1_literal_example.conf +36 -0
  63. data/example/worker_section.conf +36 -0
  64. data/fluent.conf +139 -0
  65. data/lib/fluent/agent.rb +168 -0
  66. data/lib/fluent/capability.rb +87 -0
  67. data/lib/fluent/clock.rb +66 -0
  68. data/lib/fluent/command/binlog_reader.rb +244 -0
  69. data/lib/fluent/command/bundler_injection.rb +45 -0
  70. data/lib/fluent/command/ca_generate.rb +184 -0
  71. data/lib/fluent/command/cap_ctl.rb +174 -0
  72. data/lib/fluent/command/cat.rb +365 -0
  73. data/lib/fluent/command/ctl.rb +180 -0
  74. data/lib/fluent/command/debug.rb +103 -0
  75. data/lib/fluent/command/fluentd.rb +385 -0
  76. data/lib/fluent/command/plugin_config_formatter.rb +308 -0
  77. data/lib/fluent/command/plugin_generator.rb +365 -0
  78. data/lib/fluent/compat/call_super_mixin.rb +76 -0
  79. data/lib/fluent/compat/detach_process_mixin.rb +33 -0
  80. data/lib/fluent/compat/exec_util.rb +144 -0
  81. data/lib/fluent/compat/file_util.rb +54 -0
  82. data/lib/fluent/compat/filter.rb +68 -0
  83. data/lib/fluent/compat/formatter.rb +117 -0
  84. data/lib/fluent/compat/formatter_utils.rb +85 -0
  85. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
  86. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  87. data/lib/fluent/compat/input.rb +49 -0
  88. data/lib/fluent/compat/output.rb +721 -0
  89. data/lib/fluent/compat/output_chain.rb +60 -0
  90. data/lib/fluent/compat/parser.rb +310 -0
  91. data/lib/fluent/compat/parser_utils.rb +40 -0
  92. data/lib/fluent/compat/propagate_default.rb +62 -0
  93. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  94. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  95. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  96. data/lib/fluent/compat/socket_util.rb +165 -0
  97. data/lib/fluent/compat/string_util.rb +34 -0
  98. data/lib/fluent/compat/structured_format_mixin.rb +26 -0
  99. data/lib/fluent/compat/type_converter.rb +90 -0
  100. data/lib/fluent/config/basic_parser.rb +122 -0
  101. data/lib/fluent/config/configure_proxy.rb +424 -0
  102. data/lib/fluent/config/dsl.rb +152 -0
  103. data/lib/fluent/config/element.rb +265 -0
  104. data/lib/fluent/config/error.rb +44 -0
  105. data/lib/fluent/config/literal_parser.rb +305 -0
  106. data/lib/fluent/config/parser.rb +119 -0
  107. data/lib/fluent/config/section.rb +272 -0
  108. data/lib/fluent/config/types.rb +257 -0
  109. data/lib/fluent/config/v1_parser.rb +200 -0
  110. data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
  111. data/lib/fluent/config/yaml_parser/loader.rb +124 -0
  112. data/lib/fluent/config/yaml_parser/parser.rb +179 -0
  113. data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
  114. data/lib/fluent/config/yaml_parser.rb +56 -0
  115. data/lib/fluent/config.rb +89 -0
  116. data/lib/fluent/configurable.rb +202 -0
  117. data/lib/fluent/counter/base_socket.rb +44 -0
  118. data/lib/fluent/counter/client.rb +297 -0
  119. data/lib/fluent/counter/error.rb +86 -0
  120. data/lib/fluent/counter/mutex_hash.rb +163 -0
  121. data/lib/fluent/counter/server.rb +273 -0
  122. data/lib/fluent/counter/store.rb +205 -0
  123. data/lib/fluent/counter/validator.rb +145 -0
  124. data/lib/fluent/counter.rb +23 -0
  125. data/lib/fluent/daemon.rb +14 -0
  126. data/lib/fluent/daemonizer.rb +88 -0
  127. data/lib/fluent/engine.rb +269 -0
  128. data/lib/fluent/env.rb +45 -0
  129. data/lib/fluent/error.rb +37 -0
  130. data/lib/fluent/event.rb +369 -0
  131. data/lib/fluent/event_router.rb +315 -0
  132. data/lib/fluent/ext_monitor_require.rb +28 -0
  133. data/lib/fluent/file_wrapper.rb +137 -0
  134. data/lib/fluent/filter.rb +21 -0
  135. data/lib/fluent/fluent_log_event_router.rb +139 -0
  136. data/lib/fluent/formatter.rb +23 -0
  137. data/lib/fluent/input.rb +21 -0
  138. data/lib/fluent/label.rb +46 -0
  139. data/lib/fluent/load.rb +33 -0
  140. data/lib/fluent/log/console_adapter.rb +66 -0
  141. data/lib/fluent/log.rb +775 -0
  142. data/lib/fluent/match.rb +187 -0
  143. data/lib/fluent/mixin.rb +31 -0
  144. data/lib/fluent/msgpack_factory.rb +111 -0
  145. data/lib/fluent/oj_options.rb +61 -0
  146. data/lib/fluent/output.rb +29 -0
  147. data/lib/fluent/output_chain.rb +23 -0
  148. data/lib/fluent/parser.rb +23 -0
  149. data/lib/fluent/plugin/bare_output.rb +88 -0
  150. data/lib/fluent/plugin/base.rb +219 -0
  151. data/lib/fluent/plugin/buf_file.rb +256 -0
  152. data/lib/fluent/plugin/buf_file_single.rb +272 -0
  153. data/lib/fluent/plugin/buf_memory.rb +34 -0
  154. data/lib/fluent/plugin/buffer/chunk.rb +313 -0
  155. data/lib/fluent/plugin/buffer/file_chunk.rb +432 -0
  156. data/lib/fluent/plugin/buffer/file_single_chunk.rb +325 -0
  157. data/lib/fluent/plugin/buffer/memory_chunk.rb +91 -0
  158. data/lib/fluent/plugin/buffer.rb +1063 -0
  159. data/lib/fluent/plugin/compressable.rb +87 -0
  160. data/lib/fluent/plugin/exec_util.rb +22 -0
  161. data/lib/fluent/plugin/extractor.rb +132 -0
  162. data/lib/fluent/plugin/file_util.rb +22 -0
  163. data/lib/fluent/plugin/filter.rb +119 -0
  164. data/lib/fluent/plugin/filter_grep.rb +189 -0
  165. data/lib/fluent/plugin/filter_parser.rb +124 -0
  166. data/lib/fluent/plugin/filter_record_transformer.rb +325 -0
  167. data/lib/fluent/plugin/filter_stdout.rb +53 -0
  168. data/lib/fluent/plugin/formatter.rb +75 -0
  169. data/lib/fluent/plugin/formatter_csv.rb +92 -0
  170. data/lib/fluent/plugin/formatter_hash.rb +35 -0
  171. data/lib/fluent/plugin/formatter_json.rb +62 -0
  172. data/lib/fluent/plugin/formatter_ltsv.rb +44 -0
  173. data/lib/fluent/plugin/formatter_msgpack.rb +33 -0
  174. data/lib/fluent/plugin/formatter_out_file.rb +55 -0
  175. data/lib/fluent/plugin/formatter_single_value.rb +36 -0
  176. data/lib/fluent/plugin/formatter_stdout.rb +76 -0
  177. data/lib/fluent/plugin/formatter_tsv.rb +40 -0
  178. data/lib/fluent/plugin/in_debug_agent.rb +71 -0
  179. data/lib/fluent/plugin/in_dummy.rb +18 -0
  180. data/lib/fluent/plugin/in_exec.rb +124 -0
  181. data/lib/fluent/plugin/in_forward.rb +489 -0
  182. data/lib/fluent/plugin/in_gc_stat.rb +72 -0
  183. data/lib/fluent/plugin/in_http.rb +737 -0
  184. data/lib/fluent/plugin/in_monitor_agent.rb +406 -0
  185. data/lib/fluent/plugin/in_object_space.rb +93 -0
  186. data/lib/fluent/plugin/in_sample.rb +148 -0
  187. data/lib/fluent/plugin/in_syslog.rb +346 -0
  188. data/lib/fluent/plugin/in_tail/compatibility.rb +111 -0
  189. data/lib/fluent/plugin/in_tail/dir_watcher.rb +713 -0
  190. data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
  191. data/lib/fluent/plugin/in_tail/io_handler.rb +391 -0
  192. data/lib/fluent/plugin/in_tail/line_feeder.rb +230 -0
  193. data/lib/fluent/plugin/in_tail/position_file.rb +269 -0
  194. data/lib/fluent/plugin/in_tail/stat_watcher.rb +52 -0
  195. data/lib/fluent/plugin/in_tail/tail_watcher.rb +276 -0
  196. data/lib/fluent/plugin/in_tail/worker_pool.rb +298 -0
  197. data/lib/fluent/plugin/in_tail.rb +917 -0
  198. data/lib/fluent/plugin/in_tcp.rb +230 -0
  199. data/lib/fluent/plugin/in_udp.rb +101 -0
  200. data/lib/fluent/plugin/in_unix.rb +197 -0
  201. data/lib/fluent/plugin/input.rb +71 -0
  202. data/lib/fluent/plugin/metrics.rb +119 -0
  203. data/lib/fluent/plugin/metrics_local.rb +96 -0
  204. data/lib/fluent/plugin/multi_output.rb +179 -0
  205. data/lib/fluent/plugin/out_buffer.rb +40 -0
  206. data/lib/fluent/plugin/out_copy.rb +120 -0
  207. data/lib/fluent/plugin/out_exec.rb +105 -0
  208. data/lib/fluent/plugin/out_exec_filter.rb +319 -0
  209. data/lib/fluent/plugin/out_file.rb +371 -0
  210. data/lib/fluent/plugin/out_forward/ack_handler.rb +176 -0
  211. data/lib/fluent/plugin/out_forward/connection_manager.rb +131 -0
  212. data/lib/fluent/plugin/out_forward/error.rb +28 -0
  213. data/lib/fluent/plugin/out_forward/failure_detector.rb +84 -0
  214. data/lib/fluent/plugin/out_forward/handshake_protocol.rb +125 -0
  215. data/lib/fluent/plugin/out_forward/load_balancer.rb +114 -0
  216. data/lib/fluent/plugin/out_forward/socket_cache.rb +177 -0
  217. data/lib/fluent/plugin/out_forward.rb +865 -0
  218. data/lib/fluent/plugin/out_http.rb +419 -0
  219. data/lib/fluent/plugin/out_null.rb +74 -0
  220. data/lib/fluent/plugin/out_relabel.rb +32 -0
  221. data/lib/fluent/plugin/out_roundrobin.rb +84 -0
  222. data/lib/fluent/plugin/out_secondary_file.rb +148 -0
  223. data/lib/fluent/plugin/out_stdout.rb +81 -0
  224. data/lib/fluent/plugin/out_stream.rb +130 -0
  225. data/lib/fluent/plugin/output.rb +1688 -0
  226. data/lib/fluent/plugin/owned_by_mixin.rb +41 -0
  227. data/lib/fluent/plugin/parser.rb +274 -0
  228. data/lib/fluent/plugin/parser_apache.rb +28 -0
  229. data/lib/fluent/plugin/parser_apache2.rb +88 -0
  230. data/lib/fluent/plugin/parser_apache_error.rb +26 -0
  231. data/lib/fluent/plugin/parser_csv.rb +124 -0
  232. data/lib/fluent/plugin/parser_json.rb +118 -0
  233. data/lib/fluent/plugin/parser_ltsv.rb +49 -0
  234. data/lib/fluent/plugin/parser_msgpack.rb +72 -0
  235. data/lib/fluent/plugin/parser_multiline.rb +152 -0
  236. data/lib/fluent/plugin/parser_nginx.rb +28 -0
  237. data/lib/fluent/plugin/parser_none.rb +36 -0
  238. data/lib/fluent/plugin/parser_regexp.rb +68 -0
  239. data/lib/fluent/plugin/parser_syslog.rb +543 -0
  240. data/lib/fluent/plugin/parser_tsv.rb +47 -0
  241. data/lib/fluent/plugin/sd_file.rb +157 -0
  242. data/lib/fluent/plugin/sd_srv.rb +135 -0
  243. data/lib/fluent/plugin/sd_static.rb +58 -0
  244. data/lib/fluent/plugin/service_discovery.rb +65 -0
  245. data/lib/fluent/plugin/socket_util.rb +22 -0
  246. data/lib/fluent/plugin/storage.rb +84 -0
  247. data/lib/fluent/plugin/storage_local.rb +166 -0
  248. data/lib/fluent/plugin/string_util.rb +22 -0
  249. data/lib/fluent/plugin.rb +206 -0
  250. data/lib/fluent/plugin_helper/cert_option.rb +199 -0
  251. data/lib/fluent/plugin_helper/child_process.rb +369 -0
  252. data/lib/fluent/plugin_helper/compat_parameters.rb +343 -0
  253. data/lib/fluent/plugin_helper/counter.rb +51 -0
  254. data/lib/fluent/plugin_helper/event_emitter.rb +112 -0
  255. data/lib/fluent/plugin_helper/event_loop.rb +170 -0
  256. data/lib/fluent/plugin_helper/extract.rb +104 -0
  257. data/lib/fluent/plugin_helper/formatter.rb +147 -0
  258. data/lib/fluent/plugin_helper/http_server/app.rb +81 -0
  259. data/lib/fluent/plugin_helper/http_server/methods.rb +35 -0
  260. data/lib/fluent/plugin_helper/http_server/request.rb +53 -0
  261. data/lib/fluent/plugin_helper/http_server/router.rb +54 -0
  262. data/lib/fluent/plugin_helper/http_server/server.rb +116 -0
  263. data/lib/fluent/plugin_helper/http_server/ssl_context_builder.rb +41 -0
  264. data/lib/fluent/plugin_helper/http_server.rb +129 -0
  265. data/lib/fluent/plugin_helper/inject.rb +154 -0
  266. data/lib/fluent/plugin_helper/metrics.rb +136 -0
  267. data/lib/fluent/plugin_helper/parser.rb +147 -0
  268. data/lib/fluent/plugin_helper/record_accessor.rb +207 -0
  269. data/lib/fluent/plugin_helper/retry_state.rb +219 -0
  270. data/lib/fluent/plugin_helper/server.rb +840 -0
  271. data/lib/fluent/plugin_helper/service_discovery/manager.rb +146 -0
  272. data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
  273. data/lib/fluent/plugin_helper/service_discovery.rb +125 -0
  274. data/lib/fluent/plugin_helper/socket.rb +288 -0
  275. data/lib/fluent/plugin_helper/socket_option.rb +98 -0
  276. data/lib/fluent/plugin_helper/storage.rb +349 -0
  277. data/lib/fluent/plugin_helper/thread.rb +180 -0
  278. data/lib/fluent/plugin_helper/timer.rb +92 -0
  279. data/lib/fluent/plugin_helper.rb +75 -0
  280. data/lib/fluent/plugin_id.rb +93 -0
  281. data/lib/fluent/process.rb +22 -0
  282. data/lib/fluent/registry.rb +117 -0
  283. data/lib/fluent/root_agent.rb +468 -0
  284. data/lib/fluent/rpc.rb +95 -0
  285. data/lib/fluent/source_only_buffer_agent.rb +102 -0
  286. data/lib/fluent/static_config_analysis.rb +195 -0
  287. data/lib/fluent/supervisor.rb +1347 -0
  288. data/lib/fluent/system_config.rb +213 -0
  289. data/lib/fluent/test/base.rb +83 -0
  290. data/lib/fluent/test/driver/base.rb +231 -0
  291. data/lib/fluent/test/driver/base_owned.rb +83 -0
  292. data/lib/fluent/test/driver/base_owner.rb +135 -0
  293. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  294. data/lib/fluent/test/driver/filter.rb +61 -0
  295. data/lib/fluent/test/driver/formatter.rb +30 -0
  296. data/lib/fluent/test/driver/input.rb +31 -0
  297. data/lib/fluent/test/driver/multi_output.rb +53 -0
  298. data/lib/fluent/test/driver/output.rb +102 -0
  299. data/lib/fluent/test/driver/parser.rb +30 -0
  300. data/lib/fluent/test/driver/storage.rb +30 -0
  301. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  302. data/lib/fluent/test/filter_test.rb +77 -0
  303. data/lib/fluent/test/formatter_test.rb +65 -0
  304. data/lib/fluent/test/helpers.rb +138 -0
  305. data/lib/fluent/test/input_test.rb +174 -0
  306. data/lib/fluent/test/log.rb +79 -0
  307. data/lib/fluent/test/output_test.rb +156 -0
  308. data/lib/fluent/test/parser_test.rb +70 -0
  309. data/lib/fluent/test/startup_shutdown.rb +44 -0
  310. data/lib/fluent/test.rb +61 -0
  311. data/lib/fluent/time.rb +513 -0
  312. data/lib/fluent/timezone.rb +171 -0
  313. data/lib/fluent/tls.rb +105 -0
  314. data/lib/fluent/unique_id.rb +39 -0
  315. data/lib/fluent/variable_store.rb +40 -0
  316. data/lib/fluent/version.rb +21 -0
  317. data/lib/fluent/win32api.rb +38 -0
  318. data/lib/fluent/winsvc.rb +130 -0
  319. data/templates/new_gem/.gitignore +8 -0
  320. data/templates/new_gem/Gemfile +3 -0
  321. data/templates/new_gem/README.md.erb +43 -0
  322. data/templates/new_gem/Rakefile +13 -0
  323. data/templates/new_gem/fluent-plugin.gemspec.erb +28 -0
  324. data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
  325. data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
  326. data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
  327. data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
  328. data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
  329. data/templates/new_gem/lib/fluent/plugin/storage.rb.erb +40 -0
  330. data/templates/new_gem/test/helper.rb.erb +7 -0
  331. data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
  332. data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
  333. data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
  334. data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
  335. data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
  336. data/templates/new_gem/test/plugin/test_storage.rb.erb +18 -0
  337. data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
  338. data/templates/plugin_config_formatter/param.md-table.erb +10 -0
  339. data/templates/plugin_config_formatter/param.md.erb +34 -0
  340. data/templates/plugin_config_formatter/section.md.erb +12 -0
  341. metadata +996 -0
@@ -0,0 +1,737 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/plugin/extractor'
18
+ require 'fluent/plugin/input'
19
+ require 'fluent/plugin/parser'
20
+ require 'fluent/event'
21
+
22
+ require 'http/parser'
23
+ require 'webrick/httputils'
24
+ require 'uri'
25
+ require 'socket'
26
+ require 'json'
27
+ require 'ipaddr'
28
+ require 'openssl'
29
+
30
+ module Fluent::Plugin
31
+ class InHttpParser < Parser
32
+ Fluent::Plugin.register_parser('in_http', self)
33
+
34
+ config_set_default :time_key, 'time'
35
+
36
+ def configure(conf)
37
+ super
38
+
39
+ # if no time parser related parameters, use in_http's time convert rule
40
+ @time_parser = if conf.has_key?('time_type') || conf.has_key?('time_format')
41
+ time_parser_create
42
+ else
43
+ nil
44
+ end
45
+ end
46
+
47
+ def parse(text)
48
+ # this plugin is dummy implementation not to raise error
49
+ yield nil, nil
50
+ end
51
+
52
+ def get_time_parser
53
+ @time_parser
54
+ end
55
+ end
56
+
57
+ class HttpInput < Input
58
+ Fluent::Plugin.register_input('http', self)
59
+
60
+ helpers :parser, :compat_parameters, :event_loop, :server
61
+
62
+ EMPTY_GIF_IMAGE = "GIF89a\u0001\u0000\u0001\u0000\x80\xFF\u0000\xFF\xFF\xFF\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0002D\u0001\u0000;".force_encoding("UTF-8")
63
+
64
+ desc 'The port to listen to.'
65
+ config_param :port, :integer, default: 9880
66
+ desc 'The bind address to listen to.'
67
+ config_param :bind, :string, default: '0.0.0.0'
68
+ desc 'The size limit of the POSTed element. Default is 32MB.'
69
+ config_param :body_size_limit, :size, default: 32*1024*1024 # TODO default
70
+ desc 'The size limit of the decompressed element.'
71
+ config_param :decompression_size_limit, :size, default: 256*1024*1024 # TODO default
72
+ desc 'The timeout limit for keeping the connection alive.'
73
+ config_param :keepalive_timeout, :time, default: 10 # TODO default
74
+ config_param :backlog, :integer, default: nil
75
+ desc 'Add HTTP_ prefix headers to the record.'
76
+ config_param :add_http_headers, :bool, default: false
77
+ desc 'Add REMOTE_ADDR header to the record.'
78
+ config_param :add_remote_addr, :bool, default: false
79
+ config_param :blocking_timeout, :time, default: 0.5
80
+ desc 'Set a allow list of domains that can do CORS (Cross-Origin Resource Sharing)'
81
+ config_param :cors_allow_origins, :array, default: nil
82
+ desc 'Tells browsers whether to expose the response to frontend when the credentials mode is "include".'
83
+ config_param :cors_allow_credentials, :bool, default: false
84
+ desc 'Respond with empty gif image of 1x1 pixel.'
85
+ config_param :respond_with_empty_img, :bool, default: false
86
+ desc 'Respond status code with 204.'
87
+ config_param :use_204_response, :bool, default: false
88
+ desc 'Dump error log or not'
89
+ config_param :dump_error_log, :bool, default: true
90
+ desc 'Add QUERY_ prefix query params to record'
91
+ config_param :add_query_params, :bool, default: false
92
+ desc "Add prefix to incoming tag"
93
+ config_param :add_tag_prefix, :string, default: nil
94
+
95
+ config_section :auth, required: false, multi: false do
96
+ desc 'The method for HTTP authentication'
97
+ config_param :method, :enum, list: [:basic], default: :basic
98
+ desc 'The username for basic authentication'
99
+ config_param :username, :string
100
+ desc 'The password for basic authentication'
101
+ config_param :password, :string, secret: true
102
+ end
103
+
104
+ config_section :security, required: false, multi: false do
105
+ config_section :client, param_name: :clients, required: false, multi: true do
106
+ desc 'Address or network of the client, IPv4 or IPv6. e.g. 192.168.1.10, 192.168.0.0/16, fd00::/8'
107
+ config_param :network, :string
108
+ end
109
+ end
110
+
111
+ config_section :parse do
112
+ config_set_default :@type, 'in_http'
113
+ end
114
+
115
+ EVENT_RECORD_PARAMETER = '_event_record'
116
+
117
+ def initialize
118
+ super
119
+
120
+ @km = nil
121
+ @nodes = []
122
+ @format_name = nil
123
+ @parser_time_key = nil
124
+
125
+ # default parsers
126
+ @parser_msgpack = nil
127
+ @parser_json = nil
128
+ @default_time_parser = nil
129
+ @default_keep_time_key = nil
130
+ @float_time_parser = nil
131
+
132
+ # <parse> configured parser
133
+ @custom_parser = nil
134
+ end
135
+
136
+ def configure(conf)
137
+ compat_parameters_convert(conf, :parser)
138
+
139
+ super
140
+
141
+ if @cors_allow_credentials
142
+ if @cors_allow_origins.nil? || @cors_allow_origins.include?('*')
143
+ raise Fluent::ConfigError, "Cannot enable cors_allow_credentials without specific origins"
144
+ end
145
+ end
146
+
147
+ raise Fluent::ConfigError, "'add_tag_prefix' parameter must not be empty" if @add_tag_prefix && @add_tag_prefix.empty?
148
+
149
+ configure_security if @security
150
+
151
+ m = if @parser_configs.first['@type'] == 'in_http'
152
+ @parser_msgpack = parser_create(usage: 'parser_in_http_msgpack', type: 'msgpack')
153
+ @parser_msgpack.time_key = nil
154
+ @parser_msgpack.estimate_current_event = false
155
+ @parser_json = parser_create(usage: 'parser_in_http_json', type: 'json')
156
+ @parser_json.time_key = nil
157
+ @parser_json.estimate_current_event = false
158
+
159
+ default_parser = parser_create(usage: '')
160
+ @format_name = 'default'
161
+ @parser_time_key = default_parser.time_key
162
+ @default_time_parser = default_parser.get_time_parser
163
+ @default_keep_time_key = default_parser.keep_time_key
164
+ method(:parse_params_default)
165
+ else
166
+ @custom_parser = parser_create
167
+ @format_name = @parser_configs.first['@type']
168
+ @parser_time_key = @custom_parser.time_key
169
+ method(:parse_params_with_parser)
170
+ end
171
+ self.singleton_class.module_eval do
172
+ define_method(:parse_params, m)
173
+ end
174
+ end
175
+
176
+ class KeepaliveManager < Coolio::TimerWatcher
177
+ def initialize(timeout)
178
+ super(1, true)
179
+ @cons = {}
180
+ @timeout = timeout.to_i
181
+ end
182
+
183
+ def add(sock)
184
+ @cons[sock] = sock
185
+ end
186
+
187
+ def delete(sock)
188
+ @cons.delete(sock)
189
+ end
190
+
191
+ def on_timer
192
+ @cons.each_pair {|sock,val|
193
+ if sock.step_idle > @timeout
194
+ sock.close
195
+ end
196
+ }
197
+ end
198
+ end
199
+
200
+ def multi_workers_ready?
201
+ true
202
+ end
203
+
204
+ def start
205
+ @_event_loop_run_timeout = @blocking_timeout
206
+
207
+ super
208
+
209
+ log.debug "listening http", bind: @bind, port: @port
210
+
211
+ @km = KeepaliveManager.new(@keepalive_timeout)
212
+ event_loop_attach(@km)
213
+
214
+ server_create_connection(:in_http, @port, bind: @bind, backlog: @backlog, &method(:on_server_connect))
215
+ @float_time_parser = Fluent::NumericTimeParser.new(:float)
216
+ end
217
+
218
+ def close
219
+ server_wait_until_stop
220
+ super
221
+ end
222
+
223
+ RES_TEXT_HEADER = {'Content-Type' => 'text/plain'}.freeze
224
+ RESPONSE_200 = ["200 OK".freeze, RES_TEXT_HEADER, "".freeze].freeze
225
+ RESPONSE_204 = ["204 No Content".freeze, {}.freeze].freeze
226
+ RESPONSE_IMG = ["200 OK".freeze, {'Content-Type'=>'image/gif; charset=utf-8'}.freeze, EMPTY_GIF_IMAGE].freeze
227
+ RES_400_STATUS = "400 Bad Request".freeze
228
+ RES_500_STATUS = "500 Internal Server Error".freeze
229
+
230
+ def on_request(path_info, params)
231
+ begin
232
+ path = path_info[1..-1] # remove /
233
+ tag = path.split('/').join('.')
234
+ tag = "#{@add_tag_prefix}.#{tag}" if @add_tag_prefix
235
+
236
+ mes = Fluent::MultiEventStream.new
237
+ parse_params(params) do |record_time, record|
238
+ if record.nil?
239
+ log.debug { "incoming event is invalid: path=#{path_info} params=#{params.to_json}" }
240
+ next
241
+ end
242
+
243
+ add_params_to_record(record, params)
244
+
245
+ time = if param_time = params['time']
246
+ param_time = param_time.to_f
247
+ param_time.zero? ? Fluent::EventTime.now : @float_time_parser.parse(param_time)
248
+ else
249
+ record_time.nil? ? convert_time_field(record) : record_time
250
+ end
251
+
252
+ mes.add(time, record)
253
+ end
254
+ rescue => e
255
+ if @dump_error_log
256
+ log.error "failed to process request", error: e
257
+ end
258
+ return [RES_400_STATUS, RES_TEXT_HEADER, "400 Bad Request\n#{e}\n"]
259
+ end
260
+
261
+ # TODO server error
262
+ begin
263
+ router.emit_stream(tag, mes) unless mes.empty?
264
+ rescue => e
265
+ if @dump_error_log
266
+ log.error "failed to emit data", error: e
267
+ end
268
+ return [RES_500_STATUS, RES_TEXT_HEADER, "500 Internal Server Error\n#{e}\n"]
269
+ end
270
+
271
+ if @respond_with_empty_img
272
+ return RESPONSE_IMG
273
+ else
274
+ if @use_204_response
275
+ return RESPONSE_204
276
+ else
277
+ return RESPONSE_200
278
+ end
279
+ end
280
+ end
281
+
282
+ private
283
+
284
+ def configure_security
285
+ @nodes = @security.clients.map do |client|
286
+ begin
287
+ IPAddr.new(client.network)
288
+ rescue ArgumentError
289
+ raise Fluent::ConfigError, "network '#{client.network}' address format is invalid"
290
+ end
291
+ end
292
+ end
293
+
294
+ def allowed_client?(address)
295
+ return true if @nodes.empty?
296
+ @nodes.any? { |node| node.include?(address) rescue false }
297
+ end
298
+
299
+ def on_server_connect(conn)
300
+ unless allowed_client?(conn.remote_addr)
301
+ log.warn "client address does not match any allowed network", address: conn.remote_addr
302
+ conn.data {|_data| }
303
+ conn.close
304
+ return
305
+ end
306
+
307
+ handler = Handler.new(conn, @km, method(:on_request),
308
+ @body_size_limit, @decompression_size_limit, @format_name, log,
309
+ @cors_allow_origins, @cors_allow_credentials,
310
+ @add_query_params, @auth)
311
+
312
+ conn.on(:data) do |data|
313
+ handler.on_read(data)
314
+ end
315
+
316
+ conn.on(:write_complete) do |_|
317
+ handler.on_write_complete
318
+ end
319
+
320
+ conn.on(:close) do |_|
321
+ handler.on_close
322
+ end
323
+ end
324
+
325
+ def parse_params_default(params)
326
+ if msgpack = params['msgpack']
327
+ @parser_msgpack.parse(msgpack) do |_time, record|
328
+ yield nil, record
329
+ end
330
+ elsif js = params['json']
331
+ @parser_json.parse(js) do |_time, record|
332
+ yield nil, record
333
+ end
334
+ elsif ndjson = params['ndjson']
335
+ ndjson.split(/\r?\n/).each do |js|
336
+ @parser_json.parse(js) do |_time, record|
337
+ yield nil, record
338
+ end
339
+ end
340
+ else
341
+ raise "'json', 'ndjson' or 'msgpack' parameter is required"
342
+ end
343
+ end
344
+
345
+ def parse_params_with_parser(params)
346
+ if content = params[EVENT_RECORD_PARAMETER]
347
+ @custom_parser.parse(content) do |time, record|
348
+ yield time, record
349
+ end
350
+ else
351
+ raise "'#{EVENT_RECORD_PARAMETER}' parameter is required"
352
+ end
353
+ end
354
+
355
+ def add_params_to_record(record, params)
356
+ if @add_http_headers
357
+ params.each_pair { |k, v|
358
+ if k.start_with?("HTTP_".freeze)
359
+ record[k] = v
360
+ end
361
+ }
362
+ end
363
+
364
+ if @add_query_params
365
+ params.each_pair { |k, v|
366
+ if k.start_with?("QUERY_".freeze)
367
+ record[k] = v
368
+ end
369
+ }
370
+ end
371
+
372
+ if @add_remote_addr
373
+ record['REMOTE_ADDR'] = params['REMOTE_ADDR']
374
+ end
375
+ end
376
+
377
+ def convert_time_field(record)
378
+ if t = @default_keep_time_key ? record[@parser_time_key] : record.delete(@parser_time_key)
379
+ if @default_time_parser
380
+ @default_time_parser.parse(t)
381
+ else
382
+ Fluent::EventTime.from_time(Time.at(t))
383
+ end
384
+ else
385
+ Fluent::EventTime.now
386
+ end
387
+ end
388
+
389
+ class Handler
390
+ attr_reader :content_type
391
+
392
+ def initialize(io, km, callback, body_size_limit, decompression_size_limit, format_name, log,
393
+ cors_allow_origins, cors_allow_credentials, add_query_params, auth = nil)
394
+ @io = io
395
+ @km = km
396
+ @callback = callback
397
+ @body_size_limit = body_size_limit
398
+ @decompression_size_limit = decompression_size_limit
399
+ @next_close = false
400
+ @format_name = format_name
401
+ @log = log
402
+ @cors_allow_origins = cors_allow_origins
403
+ @cors_allow_credentials = cors_allow_credentials
404
+ @idle = 0
405
+ @add_query_params = add_query_params
406
+ @auth = auth
407
+ @authorization = nil
408
+ @km.add(self)
409
+
410
+ @remote_port, @remote_addr = io.remote_port, io.remote_addr
411
+ @parser = Http::Parser.new(self)
412
+ end
413
+
414
+ def step_idle
415
+ @idle += 1
416
+ end
417
+
418
+ def on_close
419
+ @km.delete(self)
420
+ end
421
+
422
+ def on_read(data)
423
+ @idle = 0
424
+ @parser << data
425
+ rescue
426
+ @log.warn "unexpected error", error: $!.to_s
427
+ @log.warn_backtrace
428
+ @io.close
429
+ end
430
+
431
+ def on_message_begin
432
+ @body = ''
433
+ end
434
+
435
+ def on_headers_complete(headers)
436
+ expect = nil
437
+ size = nil
438
+
439
+ if @parser.http_version == [1, 1]
440
+ @keep_alive = true
441
+ else
442
+ @keep_alive = false
443
+ end
444
+ @env = {}
445
+ @content_type = ""
446
+ @content_encoding = ""
447
+ @authorization = nil
448
+ headers.each_pair {|k,v|
449
+ @env["HTTP_#{k.tr('-','_').upcase}"] = v
450
+ case k
451
+ when /\AExpect\z/i
452
+ expect = v
453
+ when /\AContent-Length\Z/i
454
+ size = v.to_i
455
+ when /\AContent-Type\Z/i
456
+ @content_type = v
457
+ when /\AContent-Encoding\Z/i
458
+ @content_encoding = v
459
+ when /\AConnection\Z/i
460
+ if /close/i.match?(v)
461
+ @keep_alive = false
462
+ elsif /Keep-alive/i.match?(v)
463
+ @keep_alive = true
464
+ end
465
+ when /\AOrigin\Z/i
466
+ @origin = v
467
+ when /\AX-Forwarded-For\Z/i
468
+ # For multiple X-Forwarded-For headers. Use first header value.
469
+ v = v.first if v.is_a?(Array)
470
+ @remote_addr = v.split(",").first
471
+ when /\AAccess-Control-Request-Method\Z/i
472
+ @access_control_request_method = v
473
+ when /\AAccess-Control-Request-Headers\Z/i
474
+ @access_control_request_headers = v
475
+ when /\AAuthorization\Z/i
476
+ @authorization = v.is_a?(Array) ? v.first : v
477
+ end
478
+ }
479
+
480
+ if @auth
481
+ # Never let the credential reach a record built by add_http_headers.
482
+ @env.delete("HTTP_AUTHORIZATION")
483
+
484
+ unless preflight_request? || authenticate
485
+ @log.warn "authentication failed", address: @remote_addr
486
+ send_response_and_close(RES_401_STATUS, {'WWW-Authenticate' => AUTH_CHALLENGE}, "")
487
+ return
488
+ end
489
+ end
490
+
491
+ if expect
492
+ if expect == '100-continue'.freeze
493
+ if !size || size < @body_size_limit
494
+ send_response_nobody("100 Continue", {})
495
+ else
496
+ send_response_and_close("413 Request Entity Too Large", {}, "Too large")
497
+ end
498
+ else
499
+ send_response_and_close("417 Expectation Failed", {}, "")
500
+ end
501
+ end
502
+ end
503
+
504
+ def on_body(chunk)
505
+ return if closing?
506
+
507
+ if @body.bytesize + chunk.bytesize > @body_size_limit
508
+ unless closing?
509
+ send_response_and_close("413 Request Entity Too Large", {}, "Too large")
510
+ end
511
+ return
512
+ end
513
+ @body << chunk
514
+ end
515
+
516
+ RES_200_STATUS = "200 OK".freeze
517
+ RES_401_STATUS = "401 Unauthorized".freeze
518
+ AUTH_CHALLENGE = 'Basic realm="fluentd"'.freeze
519
+ RES_403_STATUS = "403 Forbidden".freeze
520
+
521
+ # Azure App Service sends GET requests for health checking purpose.
522
+ # Respond with `200 OK` to accommodate it.
523
+ def handle_get_request
524
+ return send_response_and_close(RES_200_STATUS, {}, "")
525
+ end
526
+
527
+ # Web browsers can send an OPTIONS request before performing POST
528
+ # to check if cross-origin requests are supported.
529
+ def handle_options_request
530
+ # Is CORS enabled in the first place?
531
+ if @cors_allow_origins.nil?
532
+ return send_response_and_close(RES_403_STATUS, {}, "")
533
+ end
534
+
535
+ # in_http does not support HTTP methods except POST
536
+ if @access_control_request_method != 'POST'
537
+ return send_response_and_close(RES_403_STATUS, {}, "")
538
+ end
539
+
540
+ header = {
541
+ "Access-Control-Allow-Methods" => "POST",
542
+ "Access-Control-Allow-Headers" => @access_control_request_headers || "",
543
+ }
544
+
545
+ # Check the origin and send back a CORS response
546
+ if @cors_allow_origins.include?('*')
547
+ header["Access-Control-Allow-Origin"] = "*"
548
+ send_response_and_close(RES_200_STATUS, header, "")
549
+ elsif include_cors_allow_origin
550
+ header["Access-Control-Allow-Origin"] = @origin
551
+ if @cors_allow_credentials
552
+ header["Access-Control-Allow-Credentials"] = true
553
+ end
554
+ send_response_and_close(RES_200_STATUS, header, "")
555
+ else
556
+ send_response_and_close(RES_403_STATUS, {}, "")
557
+ end
558
+ end
559
+
560
+ def on_message_complete
561
+ return if closing?
562
+
563
+ if @parser.http_method == 'GET'.freeze
564
+ return handle_get_request()
565
+ end
566
+
567
+ if @parser.http_method == 'OPTIONS'.freeze
568
+ return handle_options_request()
569
+ end
570
+
571
+ # CORS check
572
+ # ==========
573
+ # For every incoming request, we check if we have some CORS
574
+ # restrictions and allow listed origins through @cors_allow_origins.
575
+ # If origin is empty, it's likely a server-to-server request and considered safe.
576
+ unless @cors_allow_origins.nil?
577
+ unless @cors_allow_origins.include?('*') || include_cors_allow_origin || @origin.nil?
578
+ send_response_and_close(RES_403_STATUS, {'Connection' => 'close'}, "")
579
+ return
580
+ end
581
+ end
582
+
583
+ # Content Encoding
584
+ # =================
585
+ # Decode payload according to the "Content-Encoding" header.
586
+ # For now, we only support 'gzip' and 'deflate'.
587
+ begin
588
+ if @content_encoding == 'gzip'.freeze
589
+ @body = Extractor.decompress_gzip(@body, limit: @decompression_size_limit)
590
+ elsif @content_encoding == 'deflate'.freeze
591
+ @body = Extractor.decompress_deflate(@body, limit: @decompression_size_limit)
592
+ end
593
+ rescue
594
+ @log.warn 'fails to decode payload', error: $!.to_s
595
+ send_response_and_close(RES_400_STATUS, {}, "")
596
+ return
597
+ end
598
+
599
+ @env['REMOTE_ADDR'] = @remote_addr if @remote_addr
600
+
601
+ uri = URI.parse(@parser.request_url)
602
+ params = parse_query(uri.query)
603
+
604
+ if @format_name != 'default'
605
+ params[EVENT_RECORD_PARAMETER] = @body
606
+ elsif /^application\/x-www-form-urlencoded/.match?(@content_type)
607
+ params.update parse_query(@body)
608
+ elsif @content_type =~ /^multipart\/form-data; boundary=(.+)/
609
+ boundary = WEBrick::HTTPUtils.dequote($1)
610
+ params.update WEBrick::HTTPUtils.parse_form_data(@body, boundary)
611
+ elsif /^application\/json/.match?(@content_type)
612
+ params['json'] = @body
613
+ elsif /^application\/csp-report/.match?(@content_type)
614
+ params['json'] = @body
615
+ elsif /^application\/msgpack/.match?(@content_type)
616
+ params['msgpack'] = @body
617
+ elsif /^application\/x-ndjson/.match?(@content_type)
618
+ params['ndjson'] = @body
619
+ end
620
+ path_info = uri.path
621
+
622
+ if (@add_query_params)
623
+
624
+ query_params = parse_query(uri.query)
625
+
626
+ query_params.each_pair {|k,v|
627
+ params["QUERY_#{k.tr('-','_').upcase}"] = v
628
+ }
629
+ end
630
+
631
+ params.merge!(@env)
632
+
633
+ @env.clear
634
+
635
+ code, header, body = @callback.call(path_info, params)
636
+ body = body.to_s
637
+ header = header.dup if header.frozen?
638
+
639
+ unless @cors_allow_origins.nil?
640
+ if @cors_allow_origins.include?('*')
641
+ header['Access-Control-Allow-Origin'] = '*'
642
+ elsif include_cors_allow_origin
643
+ header['Access-Control-Allow-Origin'] = @origin
644
+ if @cors_allow_credentials
645
+ header["Access-Control-Allow-Credentials"] = true
646
+ end
647
+ end
648
+ end
649
+
650
+ if @keep_alive
651
+ header['Connection'] = 'Keep-Alive'.freeze
652
+ send_response(code, header, body)
653
+ else
654
+ send_response_and_close(code, header, body)
655
+ end
656
+ end
657
+
658
+ def close
659
+ @io.close
660
+ end
661
+
662
+ def on_write_complete
663
+ @io.close if @next_close
664
+ end
665
+
666
+ def send_response_and_close(code, header, body)
667
+ send_response(code, header, body)
668
+ @next_close = true
669
+ end
670
+
671
+ def closing?
672
+ @next_close
673
+ end
674
+
675
+ def send_response(code, header, body)
676
+ header['Content-Length'] ||= body.bytesize
677
+ header['Content-Type'] ||= 'text/plain'.freeze
678
+
679
+ data = %[HTTP/1.1 #{code}\r\n]
680
+ header.each_pair {|k,v|
681
+ data << "#{k}: #{v}\r\n"
682
+ }
683
+ data << "\r\n".freeze
684
+ @io.write(data)
685
+
686
+ @io.write(body)
687
+ end
688
+
689
+ def send_response_nobody(code, header)
690
+ data = %[HTTP/1.1 #{code}\r\n]
691
+ header.each_pair {|k,v|
692
+ data << "#{k}: #{v}\r\n"
693
+ }
694
+ data << "\r\n".freeze
695
+ @io.write(data)
696
+ end
697
+
698
+ def include_cors_allow_origin
699
+ if @origin.nil?
700
+ return false
701
+ end
702
+
703
+ if @cors_allow_origins.include?(@origin)
704
+ return true
705
+ end
706
+ filtered_cors_allow_origins = @cors_allow_origins.select {|origin| origin != ""}
707
+ r = filtered_cors_allow_origins.find do |origin|
708
+ (start_str, end_str) = origin.split("*", 2)
709
+ @origin.start_with?(start_str) && @origin.end_with?(end_str)
710
+ end
711
+
712
+ !r.nil?
713
+ end
714
+
715
+ def parse_query(query)
716
+ query.nil? ? {} : Hash[URI.decode_www_form(query, Encoding::ASCII_8BIT)]
717
+ end
718
+
719
+ # Browsers never attach Authorization to a CORS preflight.
720
+ def preflight_request?
721
+ @parser.http_method == 'OPTIONS'.freeze
722
+ end
723
+
724
+ def authenticate
725
+ scheme, credentials = @authorization.to_s.split(' ', 2)
726
+ return false unless scheme == 'Basic'.freeze
727
+
728
+ username, password = credentials.to_s.unpack1('m').to_s.split(':', 2)
729
+ username_matched = OpenSSL.secure_compare(username.to_s, @auth.username)
730
+ password_matched = OpenSSL.secure_compare(password.to_s, @auth.password)
731
+ username_matched && password_matched
732
+ rescue ArgumentError
733
+ false
734
+ end
735
+ end
736
+ end
737
+ end