puma 4.3.12 → 6.3.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puma might be problematic. Click here for more details.

Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +1729 -521
  3. data/LICENSE +23 -20
  4. data/README.md +169 -45
  5. data/bin/puma-wild +3 -9
  6. data/docs/architecture.md +63 -26
  7. data/docs/compile_options.md +55 -0
  8. data/docs/deployment.md +60 -69
  9. data/docs/fork_worker.md +31 -0
  10. data/docs/images/puma-connection-flow-no-reactor.png +0 -0
  11. data/docs/images/puma-connection-flow.png +0 -0
  12. data/docs/images/puma-general-arch.png +0 -0
  13. data/docs/jungle/README.md +9 -0
  14. data/{tools → docs}/jungle/rc.d/README.md +1 -1
  15. data/{tools → docs}/jungle/rc.d/puma +2 -2
  16. data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
  17. data/docs/kubernetes.md +66 -0
  18. data/docs/nginx.md +2 -2
  19. data/docs/plugins.md +15 -15
  20. data/docs/rails_dev_mode.md +28 -0
  21. data/docs/restart.md +46 -23
  22. data/docs/signals.md +13 -11
  23. data/docs/stats.md +142 -0
  24. data/docs/systemd.md +84 -128
  25. data/docs/testing_benchmarks_local_files.md +150 -0
  26. data/docs/testing_test_rackup_ci_files.md +36 -0
  27. data/ext/puma_http11/PumaHttp11Service.java +2 -4
  28. data/ext/puma_http11/ext_help.h +1 -1
  29. data/ext/puma_http11/extconf.rb +49 -12
  30. data/ext/puma_http11/http11_parser.c +46 -48
  31. data/ext/puma_http11/http11_parser.h +2 -2
  32. data/ext/puma_http11/http11_parser.java.rl +3 -3
  33. data/ext/puma_http11/http11_parser.rl +3 -3
  34. data/ext/puma_http11/http11_parser_common.rl +2 -2
  35. data/ext/puma_http11/mini_ssl.c +278 -93
  36. data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
  37. data/ext/puma_http11/org/jruby/puma/Http11.java +6 -6
  38. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +4 -6
  39. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +241 -96
  40. data/ext/puma_http11/puma_http11.c +46 -57
  41. data/lib/puma/app/status.rb +53 -39
  42. data/lib/puma/binder.rb +237 -121
  43. data/lib/puma/cli.rb +34 -34
  44. data/lib/puma/client.rb +172 -98
  45. data/lib/puma/cluster/worker.rb +180 -0
  46. data/lib/puma/cluster/worker_handle.rb +97 -0
  47. data/lib/puma/cluster.rb +226 -231
  48. data/lib/puma/commonlogger.rb +21 -14
  49. data/lib/puma/configuration.rb +114 -87
  50. data/lib/puma/const.rb +139 -95
  51. data/lib/puma/control_cli.rb +99 -79
  52. data/lib/puma/detect.rb +33 -2
  53. data/lib/puma/dsl.rb +516 -110
  54. data/lib/puma/error_logger.rb +113 -0
  55. data/lib/puma/events.rb +16 -115
  56. data/lib/puma/io_buffer.rb +44 -2
  57. data/lib/puma/jruby_restart.rb +2 -59
  58. data/lib/puma/json_serialization.rb +96 -0
  59. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  60. data/lib/puma/launcher.rb +164 -155
  61. data/lib/puma/log_writer.rb +147 -0
  62. data/lib/puma/minissl/context_builder.rb +36 -19
  63. data/lib/puma/minissl.rb +230 -55
  64. data/lib/puma/null_io.rb +18 -1
  65. data/lib/puma/plugin/systemd.rb +90 -0
  66. data/lib/puma/plugin/tmp_restart.rb +1 -1
  67. data/lib/puma/plugin.rb +3 -12
  68. data/lib/puma/rack/builder.rb +7 -11
  69. data/lib/puma/rack/urlmap.rb +0 -0
  70. data/lib/puma/rack_default.rb +19 -4
  71. data/lib/puma/reactor.rb +93 -368
  72. data/lib/puma/request.rb +671 -0
  73. data/lib/puma/runner.rb +92 -75
  74. data/lib/puma/sd_notify.rb +149 -0
  75. data/lib/puma/server.rb +321 -794
  76. data/lib/puma/single.rb +20 -74
  77. data/lib/puma/state_file.rb +45 -8
  78. data/lib/puma/thread_pool.rb +140 -68
  79. data/lib/puma/util.rb +21 -4
  80. data/lib/puma.rb +54 -7
  81. data/lib/rack/handler/puma.rb +113 -87
  82. data/tools/{docker/Dockerfile → Dockerfile} +1 -1
  83. data/tools/trickletest.rb +0 -0
  84. metadata +33 -24
  85. data/docs/tcp_mode.md +0 -96
  86. data/ext/puma_http11/io_buffer.c +0 -155
  87. data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
  88. data/lib/puma/accept_nonblock.rb +0 -29
  89. data/lib/puma/tcp_logger.rb +0 -41
  90. data/tools/jungle/README.md +0 -19
  91. data/tools/jungle/init.d/README.md +0 -61
  92. data/tools/jungle/init.d/puma +0 -421
  93. data/tools/jungle/init.d/run-puma +0 -18
  94. data/tools/jungle/upstart/README.md +0 -61
  95. data/tools/jungle/upstart/puma-manager.conf +0 -31
  96. data/tools/jungle/upstart/puma.conf +0 -69
data/lib/puma.rb CHANGED
@@ -3,29 +3,76 @@
3
3
  # Standard libraries
4
4
  require 'socket'
5
5
  require 'tempfile'
6
- require 'time'
7
- require 'etc'
8
6
  require 'uri'
9
7
  require 'stringio'
10
8
 
11
9
  require 'thread'
12
10
 
11
+ # use require, see https://github.com/puma/puma/pull/2381
12
+ require 'puma/puma_http11'
13
+
14
+ require_relative 'puma/detect'
15
+ require_relative 'puma/json_serialization'
16
+
13
17
  module Puma
14
- autoload :Const, 'puma/const'
15
- autoload :Server, 'puma/server'
16
- autoload :Launcher, 'puma/launcher'
18
+ # when Puma is loaded via `Puma::CLI`, all files are loaded via
19
+ # `require_relative`. The below are for non-standard loading
20
+ autoload :Const, "#{__dir__}/puma/const"
21
+ autoload :Server, "#{__dir__}/puma/server"
22
+ autoload :Launcher, "#{__dir__}/puma/launcher"
23
+ autoload :LogWriter, "#{__dir__}/puma/log_writer"
24
+
25
+ # at present, MiniSSL::Engine is only defined in extension code (puma_http11),
26
+ # not in minissl.rb
27
+ HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
28
+
29
+ HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS
30
+
31
+ if HAS_SSL
32
+ require_relative 'puma/minissl'
33
+ else
34
+ module MiniSSL
35
+ # this class is defined so that it exists when Puma is compiled
36
+ # without ssl support, as Server and Reactor use it in rescue statements.
37
+ class SSLError < StandardError ; end
38
+ end
39
+ end
17
40
 
41
+ def self.ssl?
42
+ HAS_SSL
43
+ end
44
+
45
+ def self.abstract_unix_socket?
46
+ @abstract_unix ||=
47
+ if HAS_UNIX_SOCKET
48
+ begin
49
+ ::UNIXServer.new("\0puma.temp.unix").close
50
+ true
51
+ rescue ArgumentError # darwin
52
+ false
53
+ end
54
+ else
55
+ false
56
+ end
57
+ end
58
+
59
+ # @!attribute [rw] stats_object=
18
60
  def self.stats_object=(val)
19
61
  @get_stats = val
20
62
  end
21
63
 
64
+ # @!attribute [rw] stats_object
22
65
  def self.stats
66
+ Puma::JSONSerialization.generate @get_stats.stats
67
+ end
68
+
69
+ # @!attribute [r] stats_hash
70
+ # @version 5.0.0
71
+ def self.stats_hash
23
72
  @get_stats.stats
24
73
  end
25
74
 
26
- # Thread name is new in Ruby 2.3
27
75
  def self.set_thread_name(name)
28
- return unless Thread.current.respond_to?(:name=)
29
76
  Thread.current.name = "puma #{name}"
30
77
  end
31
78
  end
@@ -1,115 +1,141 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rack/handler'
4
-
5
- module Rack
6
- module Handler
7
- module Puma
8
- DEFAULT_OPTIONS = {
9
- :Verbose => false,
10
- :Silent => false
11
- }
12
-
13
- def self.config(app, options = {})
14
- require 'puma'
15
- require 'puma/configuration'
16
- require 'puma/events'
17
- require 'puma/launcher'
18
-
19
- default_options = DEFAULT_OPTIONS.dup
20
-
21
- # Libraries pass in values such as :Port and there is no way to determine
22
- # if it is a default provided by the library or a special value provided
23
- # by the user. A special key `user_supplied_options` can be passed. This
24
- # contains an array of all explicitly defined user options. We then
25
- # know that all other values are defaults
26
- if user_supplied_options = options.delete(:user_supplied_options)
27
- (options.keys - user_supplied_options).each do |k|
28
- default_options[k] = options.delete(k)
29
- end
3
+ # This module is used as an 'include' file in code at bottom of file
4
+ module Puma
5
+ module RackHandler
6
+ DEFAULT_OPTIONS = {
7
+ :Verbose => false,
8
+ :Silent => false
9
+ }
10
+
11
+ def config(app, options = {})
12
+ require_relative '../../puma'
13
+ require_relative '../../puma/configuration'
14
+ require_relative '../../puma/log_writer'
15
+ require_relative '../../puma/launcher'
16
+
17
+ default_options = DEFAULT_OPTIONS.dup
18
+
19
+ # Libraries pass in values such as :Port and there is no way to determine
20
+ # if it is a default provided by the library or a special value provided
21
+ # by the user. A special key `user_supplied_options` can be passed. This
22
+ # contains an array of all explicitly defined user options. We then
23
+ # know that all other values are defaults
24
+ if user_supplied_options = options.delete(:user_supplied_options)
25
+ (options.keys - user_supplied_options).each do |k|
26
+ default_options[k] = options.delete(k)
30
27
  end
28
+ end
31
29
 
32
- conf = ::Puma::Configuration.new(options, default_options) do |user_config, file_config, default_config|
33
- user_config.quiet
34
-
35
- if options.delete(:Verbose)
36
- app = Rack::CommonLogger.new(app, STDOUT)
37
- end
30
+ @events = options[:events] || ::Puma::Events.new
38
31
 
39
- if options[:environment]
40
- user_config.environment options[:environment]
32
+ conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config|
33
+ if options.delete(:Verbose)
34
+ begin
35
+ require 'rack/commonlogger' # Rack 1.x
36
+ rescue LoadError
37
+ require 'rack/common_logger' # Rack 2 and later
41
38
  end
39
+ app = ::Rack::CommonLogger.new(app, STDOUT)
40
+ end
42
41
 
43
- if options[:Threads]
44
- min, max = options.delete(:Threads).split(':', 2)
45
- user_config.threads min, max
46
- end
42
+ if options[:environment]
43
+ user_config.environment options[:environment]
44
+ end
47
45
 
48
- if options[:Host] || options[:Port]
49
- host = options[:Host] || default_options[:Host]
50
- port = options[:Port] || default_options[:Port]
51
- self.set_host_port_to_config(host, port, user_config)
52
- end
46
+ if options[:Threads]
47
+ min, max = options.delete(:Threads).split(':', 2)
48
+ user_config.threads min, max
49
+ end
53
50
 
54
- if default_options[:Host]
55
- file_config.set_default_host(default_options[:Host])
56
- end
57
- self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
51
+ if options[:Host] || options[:Port]
52
+ host = options[:Host] || default_options[:Host]
53
+ port = options[:Port] || default_options[:Port]
54
+ self.set_host_port_to_config(host, port, user_config)
55
+ end
58
56
 
59
- user_config.app app
57
+ if default_options[:Host]
58
+ file_config.set_default_host(default_options[:Host])
60
59
  end
61
- conf
60
+ self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
61
+
62
+ user_config.app app
62
63
  end
64
+ conf
65
+ end
63
66
 
64
- def self.run(app, options = {})
65
- conf = self.config(app, options)
67
+ def run(app, **options)
68
+ conf = self.config(app, options)
66
69
 
67
- events = options.delete(:Silent) ? ::Puma::Events.strings : ::Puma::Events.stdio
70
+ log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
68
71
 
69
- launcher = ::Puma::Launcher.new(conf, :events => events)
72
+ launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer, events: @events)
70
73
 
71
- yield launcher if block_given?
72
- begin
73
- launcher.run
74
- rescue Interrupt
75
- puts "* Gracefully stopping, waiting for requests to finish"
76
- launcher.stop
77
- puts "* Goodbye!"
78
- end
74
+ yield launcher if block_given?
75
+ begin
76
+ launcher.run
77
+ rescue Interrupt
78
+ puts "* Gracefully stopping, waiting for requests to finish"
79
+ launcher.stop
80
+ puts "* Goodbye!"
79
81
  end
82
+ end
80
83
 
81
- def self.valid_options
82
- {
83
- "Host=HOST" => "Hostname to listen on (default: localhost)",
84
- "Port=PORT" => "Port to listen on (default: 8080)",
85
- "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
86
- "Verbose" => "Don't report each request (default: false)"
87
- }
88
- end
84
+ def valid_options
85
+ {
86
+ "Host=HOST" => "Hostname to listen on (default: localhost)",
87
+ "Port=PORT" => "Port to listen on (default: 8080)",
88
+ "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
89
+ "Verbose" => "Don't report each request (default: false)"
90
+ }
91
+ end
89
92
 
90
- def self.set_host_port_to_config(host, port, config)
91
- config.clear_binds! if host || port
93
+ def set_host_port_to_config(host, port, config)
94
+ config.clear_binds! if host || port
92
95
 
93
- if host && (host[0,1] == '.' || host[0,1] == '/')
94
- config.bind "unix://#{host}"
95
- elsif host && host =~ /^ssl:\/\//
96
- uri = URI.parse(host)
97
- uri.port ||= port || ::Puma::Configuration::DefaultTCPPort
98
- config.bind uri.to_s
99
- else
96
+ if host && (host[0,1] == '.' || host[0,1] == '/')
97
+ config.bind "unix://#{host}"
98
+ elsif host && host =~ /^ssl:\/\//
99
+ uri = URI.parse(host)
100
+ uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
101
+ config.bind uri.to_s
102
+ else
100
103
 
101
- if host
102
- port ||= ::Puma::Configuration::DefaultTCPPort
103
- end
104
+ if host
105
+ port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
106
+ end
104
107
 
105
- if port
106
- host ||= ::Puma::Configuration::DefaultTCPHost
107
- config.port port, host
108
- end
108
+ if port
109
+ host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
110
+ config.port port, host
109
111
  end
110
112
  end
111
113
  end
114
+ end
115
+ end
112
116
 
113
- register :puma, Puma
117
+ # rackup was removed in Rack 3, it is now a separate gem
118
+ if Object.const_defined? :Rackup
119
+ module Rackup
120
+ module Handler
121
+ module Puma
122
+ class << self
123
+ include ::Puma::RackHandler
124
+ end
125
+ end
126
+ register :puma, Puma
127
+ end
128
+ end
129
+ else
130
+ do_register = Object.const_defined?(:Rack) && Rack.release < '3'
131
+ module Rack
132
+ module Handler
133
+ module Puma
134
+ class << self
135
+ include ::Puma::RackHandler
136
+ end
137
+ end
138
+ end
114
139
  end
140
+ ::Rack::Handler.register(:puma, ::Rack::Handler::Puma) if do_register
115
141
  end
@@ -1,6 +1,6 @@
1
1
  # Use this Dockerfile to create minimal reproductions of issues
2
2
 
3
- FROM ruby:2.6
3
+ FROM ruby:3.1
4
4
 
5
5
  # throw errors if Gemfile has been modified since Gemfile.lock
6
6
  RUN bundle config --global frozen 1
data/tools/trickletest.rb CHANGED
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.12
4
+ version: 6.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Phoenix
@@ -24,9 +24,9 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
- description: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server
27
+ description: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server
28
28
  for Ruby/Rack applications. Puma is intended for use in both development and production
29
- environments. It's great for highly concurrent Ruby implementations such as Rubinius
29
+ environments. It's great for highly parallel Ruby implementations such as Rubinius
30
30
  and JRuby as well as as providing process worker support to support CRuby well.
31
31
  email:
32
32
  - evan@phx.io
@@ -44,16 +44,26 @@ files:
44
44
  - bin/puma-wild
45
45
  - bin/pumactl
46
46
  - docs/architecture.md
47
+ - docs/compile_options.md
47
48
  - docs/deployment.md
49
+ - docs/fork_worker.md
48
50
  - docs/images/puma-connection-flow-no-reactor.png
49
51
  - docs/images/puma-connection-flow.png
50
52
  - docs/images/puma-general-arch.png
53
+ - docs/jungle/README.md
54
+ - docs/jungle/rc.d/README.md
55
+ - docs/jungle/rc.d/puma
56
+ - docs/jungle/rc.d/puma.conf
57
+ - docs/kubernetes.md
51
58
  - docs/nginx.md
52
59
  - docs/plugins.md
60
+ - docs/rails_dev_mode.md
53
61
  - docs/restart.md
54
62
  - docs/signals.md
63
+ - docs/stats.md
55
64
  - docs/systemd.md
56
- - docs/tcp_mode.md
65
+ - docs/testing_benchmarks_local_files.md
66
+ - docs/testing_test_rackup_ci_files.md
57
67
  - ext/puma_http11/PumaHttp11Service.java
58
68
  - ext/puma_http11/ext_help.h
59
69
  - ext/puma_http11/extconf.rb
@@ -62,65 +72,64 @@ files:
62
72
  - ext/puma_http11/http11_parser.java.rl
63
73
  - ext/puma_http11/http11_parser.rl
64
74
  - ext/puma_http11/http11_parser_common.rl
65
- - ext/puma_http11/io_buffer.c
66
75
  - ext/puma_http11/mini_ssl.c
76
+ - ext/puma_http11/no_ssl/PumaHttp11Service.java
67
77
  - ext/puma_http11/org/jruby/puma/Http11.java
68
78
  - ext/puma_http11/org/jruby/puma/Http11Parser.java
69
- - ext/puma_http11/org/jruby/puma/IOBuffer.java
70
79
  - ext/puma_http11/org/jruby/puma/MiniSSL.java
71
80
  - ext/puma_http11/puma_http11.c
72
81
  - lib/puma.rb
73
- - lib/puma/accept_nonblock.rb
74
82
  - lib/puma/app/status.rb
75
83
  - lib/puma/binder.rb
76
84
  - lib/puma/cli.rb
77
85
  - lib/puma/client.rb
78
86
  - lib/puma/cluster.rb
87
+ - lib/puma/cluster/worker.rb
88
+ - lib/puma/cluster/worker_handle.rb
79
89
  - lib/puma/commonlogger.rb
80
90
  - lib/puma/configuration.rb
81
91
  - lib/puma/const.rb
82
92
  - lib/puma/control_cli.rb
83
93
  - lib/puma/detect.rb
84
94
  - lib/puma/dsl.rb
95
+ - lib/puma/error_logger.rb
85
96
  - lib/puma/events.rb
86
97
  - lib/puma/io_buffer.rb
87
98
  - lib/puma/jruby_restart.rb
99
+ - lib/puma/json_serialization.rb
88
100
  - lib/puma/launcher.rb
101
+ - lib/puma/launcher/bundle_pruner.rb
102
+ - lib/puma/log_writer.rb
89
103
  - lib/puma/minissl.rb
90
104
  - lib/puma/minissl/context_builder.rb
91
105
  - lib/puma/null_io.rb
92
106
  - lib/puma/plugin.rb
107
+ - lib/puma/plugin/systemd.rb
93
108
  - lib/puma/plugin/tmp_restart.rb
94
109
  - lib/puma/rack/builder.rb
95
110
  - lib/puma/rack/urlmap.rb
96
111
  - lib/puma/rack_default.rb
97
112
  - lib/puma/reactor.rb
113
+ - lib/puma/request.rb
98
114
  - lib/puma/runner.rb
115
+ - lib/puma/sd_notify.rb
99
116
  - lib/puma/server.rb
100
117
  - lib/puma/single.rb
101
118
  - lib/puma/state_file.rb
102
- - lib/puma/tcp_logger.rb
103
119
  - lib/puma/thread_pool.rb
104
120
  - lib/puma/util.rb
105
121
  - lib/rack/handler/puma.rb
106
- - tools/docker/Dockerfile
107
- - tools/jungle/README.md
108
- - tools/jungle/init.d/README.md
109
- - tools/jungle/init.d/puma
110
- - tools/jungle/init.d/run-puma
111
- - tools/jungle/rc.d/README.md
112
- - tools/jungle/rc.d/puma
113
- - tools/jungle/rc.d/puma.conf
114
- - tools/jungle/upstart/README.md
115
- - tools/jungle/upstart/puma-manager.conf
116
- - tools/jungle/upstart/puma.conf
122
+ - tools/Dockerfile
117
123
  - tools/trickletest.rb
118
- homepage: http://puma.io
124
+ homepage: https://puma.io
119
125
  licenses:
120
126
  - BSD-3-Clause
121
127
  metadata:
122
- msys2_mingw_dependencies: openssl
128
+ bug_tracker_uri: https://github.com/puma/puma/issues
123
129
  changelog_uri: https://github.com/puma/puma/blob/master/History.md
130
+ homepage_uri: https://puma.io
131
+ source_code_uri: https://github.com/puma/puma
132
+ rubygems_mfa_required: 'true'
124
133
  post_install_message:
125
134
  rdoc_options: []
126
135
  require_paths:
@@ -129,16 +138,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
129
138
  requirements:
130
139
  - - ">="
131
140
  - !ruby/object:Gem::Version
132
- version: '2.2'
141
+ version: '2.4'
133
142
  required_rubygems_version: !ruby/object:Gem::Requirement
134
143
  requirements:
135
144
  - - ">="
136
145
  - !ruby/object:Gem::Version
137
146
  version: '0'
138
147
  requirements: []
139
- rubygems_version: 3.2.26
148
+ rubygems_version: 3.4.12
140
149
  signing_key:
141
150
  specification_version: 4
142
- summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
151
+ summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
143
152
  Ruby/Rack applications
144
153
  test_files: []
data/docs/tcp_mode.md DELETED
@@ -1,96 +0,0 @@
1
- # TCP mode
2
-
3
- Puma also could be used as a TCP server to process incoming TCP
4
- connections.
5
-
6
-
7
- ## Configuration
8
-
9
- TCP mode can be enabled with CLI option `--tcp-mode`:
10
-
11
- ```
12
- $ puma --tcp-mode
13
- ```
14
-
15
- Default ip and port to listen to are `0.0.0.0` and `9292`. You can configure
16
- them with `--port` and `--bind` options:
17
-
18
- ```
19
- $ puma --tcp-mode --bind tcp://127.0.0.1:9293
20
- $ puma --tcp-mode --port 9293
21
- ```
22
-
23
- TCP mode could be set with a configuration file as well with `tcp_mode`
24
- and `tcp_mode!` methods:
25
-
26
- ```
27
- # config/puma.rb
28
- tcp_mode
29
- ```
30
-
31
- When Puma starts in the TCP mode it prints the corresponding message:
32
-
33
- ```
34
- puma --tcp-mode
35
- Puma starting in single mode...
36
- ...
37
- * Mode: Lopez Express (tcp)
38
- ```
39
-
40
-
41
- ## How to declare an application
42
-
43
- An application to process TCP connections should be declared as a
44
- callable object which accepts `env` and `socket` arguments.
45
-
46
- `env` argument is a Hash with following structure:
47
-
48
- ```ruby
49
- { "thread" => {}, "REMOTE_ADDR" => "127.0.0.1:51133", "log" => "#<Proc:0x000..." }
50
- ```
51
-
52
- It consists of:
53
- * `thread` - a Hash for each thread in the thread pool that could be
54
- used to store information between requests
55
- * `REMOTE_ADDR` - a client ip address
56
- * `log` - a proc object to write something down
57
-
58
- `log` object could be used this way:
59
-
60
- ```ruby
61
- env['log'].call('message to log')
62
- #> 19/Oct/2019 20:28:53 - 127.0.0.1:51266 - message to log
63
- ```
64
-
65
-
66
- ## Example of an application
67
-
68
- Let's look at an example of a simple application which just echoes
69
- incoming string:
70
-
71
- ```ruby
72
- # config/puma.rb
73
- app do |env, socket|
74
- s = socket.gets
75
- socket.puts "Echo #{s}"
76
- end
77
- ```
78
-
79
- We can easily access the TCP server with `telnet` command and receive an
80
- echo:
81
-
82
- ```shell
83
- telnet 0.0.0.0 9293
84
- Trying 0.0.0.0...
85
- Connected to 0.0.0.0.
86
- Escape character is '^]'.
87
- sssss
88
- Echo sssss
89
- ^CConnection closed by foreign host.
90
- ```
91
-
92
-
93
- ## Socket management
94
-
95
- After the application finishes, Puma closes the socket. In order to
96
- prevent this, the application should set `env['detach'] = true`.