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"- SERVER_SOFTWARE =
"SERVER_SOFTWARE"- SERVER_SOFTWARE_VALUE =
"Raptor/#{Raptor::VERSION}".freeze
Class Method Summary collapse
-
.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
.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.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/raptor/http.rb', line 39 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.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/raptor/http.rb', line 66 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.
106 107 108 109 110 111 112 113 114 |
# File 'lib/raptor/http.rb', line 106 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 |