Module: Raptor::Http
- Defined in:
- lib/raptor/http.rb,
sig/generated/raptor/http.rbs
Overview
Shared HTTP utilities used by both the HTTP/1.x and HTTP/2 handlers: Rack env keys that aren't provided by Rack itself, low-level socket writing, and Common Log Format access-log formatting.
Defined Under Namespace
Classes: WriteError
Constant Summary collapse
- WRITE_TIMEOUT =
5- CONTENT_LENGTH =
"CONTENT_LENGTH"- CONTENT_TYPE =
"CONTENT_TYPE"- HTTP_VERSION =
"HTTP_VERSION"- REMOTE_ADDR =
"REMOTE_ADDR"- REQUEST_URI =
"REQUEST_URI"- SERVER_SOFTWARE =
"SERVER_SOFTWARE"- SERVER_SOFTWARE_VALUE =
"Raptor/#{Raptor::VERSION}".freeze
Class Method Summary collapse
-
.call_response_finished(env, status, headers, error) ⇒ void
Calls every
rack.response_finishedcallback in reverse registration order, rescuing any that raise. -
.no_entity_body_status?(status) ⇒ Boolean
Returns whether an HTTP status forbids an entity body.
-
.parser_worker(env_template, max_body_size) ⇒ Proc
Returns a Ractor-safe proc that parses an HTTP/1.x request from the state hash's buffered bytes.
-
.socket_write(socket, string, timeout: WRITE_TIMEOUT) ⇒ void
Writes
stringin full, retrying on partial writes. -
.socket_writev(socket, strings, timeout: WRITE_TIMEOUT) ⇒ void
Writes
stringsin full via a singlewritev(2)syscall when possible, falling back to per-string writes on partial results. -
.write_access_log(io, env, status, size, remote_addr) ⇒ void
Writes a Common Log Format entry to
io.
Class Method Details
.call_response_finished(env, status, headers, error) ⇒ void
This method returns an undefined value.
Calls every rack.response_finished callback in reverse
registration order, rescuing any that raise.
130 131 132 133 134 135 136 |
# File 'lib/raptor/http.rb', line 130 def self.call_response_finished(env, status, headers, error) return unless env && env[Rack::RACK_RESPONSE_FINISHED].is_a?(Array) env[Rack::RACK_RESPONSE_FINISHED].reverse_each do |callable| callable.call(env, status, headers, error) rescue nil end end |
.no_entity_body_status?(status) ⇒ Boolean
Returns whether an HTTP status forbids an entity body.
36 37 38 |
# File 'lib/raptor/http.rb', line 36 def self.no_entity_body_status?(status) (status >= 100 && status < 200) || status == 204 || status == 304 end |
.parser_worker(env_template, max_body_size) ⇒ Proc
Returns a Ractor-safe proc that parses an HTTP/1.x request from the state hash's buffered bytes.
114 115 116 117 118 |
# File 'lib/raptor/http.rb', line 114 def self.parser_worker(env_template, max_body_size) proc do |data| Raptor::Http1.parse(data, env_template, max_body_size) end end |
.socket_write(socket, string, timeout: WRITE_TIMEOUT) ⇒ void
This method returns an undefined value.
Writes string in full, retrying on partial writes. Bounded by
timeout so a slow client can't pin the writing thread.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/raptor/http.rb', line 50 def self.socket_write(socket, string, timeout: WRITE_TIMEOUT) bytes = 0 byte_size = string.bytesize while bytes < byte_size begin bytes += socket.write_nonblock(bytes.zero? ? string : string.byteslice(bytes..-1)) rescue IO::WaitWritable raise WriteError unless socket.wait_writable(timeout) retry rescue IOError raise WriteError end end end |
.socket_writev(socket, strings, timeout: WRITE_TIMEOUT) ⇒ void
This method returns an undefined value.
Writes strings in full via a single writev(2) syscall when possible,
falling back to per-string writes on partial results. Bounded by
timeout so a slow client can't pin the writing thread.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/raptor/http.rb', line 77 def self.socket_writev(socket, strings, timeout: WRITE_TIMEOUT) total = strings.sum(&:bytesize) return if total.zero? begin written = Raptor::VectorIO.writev_nonblock(socket, strings) rescue IO::WaitWritable raise WriteError unless socket.wait_writable(timeout) retry rescue IOError raise WriteError end return if written == total offset = 0 strings.each do |string| size = string.bytesize if written >= offset + size offset += size else start = written - offset socket_write(socket, start.zero? ? string : string.byteslice(start..-1), timeout: timeout) offset += size written = offset end end end |
.write_access_log(io, env, status, size, remote_addr) ⇒ void
This method returns an undefined value.
Writes a Common Log Format entry to io. Write failures are silently
ignored.
149 150 151 152 153 154 155 156 157 |
# File 'lib/raptor/http.rb', line 149 def self.write_access_log(io, env, status, size, remote_addr) = Time.now.strftime("%d/%b/%Y:%H:%M:%S %z") method = env[Rack::REQUEST_METHOD] query = env[Rack::QUERY_STRING] path = query.empty? ? env[Rack::PATH_INFO] : "#{env[Rack::PATH_INFO]}?#{query}" protocol = env[Rack::SERVER_PROTOCOL] io.puts(%(#{remote_addr} - - [#{}] "#{method} #{path} #{protocol}" #{status} #{size})) rescue nil end |