Class: Tep::Response
- Inherits:
-
Object
- Object
- Tep::Response
- Defined in:
- lib/tep/response.rb
Instance Attribute Summary collapse
-
#body ⇒ Object
Returns the value of attribute body.
-
#file_path ⇒ Object
Returns the value of attribute file_path.
-
#halted ⇒ Object
Returns the value of attribute halted.
-
#headers ⇒ Object
Returns the value of attribute headers.
-
#lastmod_epoch ⇒ Object
readonly
Returns the value of attribute lastmod_epoch.
-
#set_cookies ⇒ Object
Returns the value of attribute set_cookies.
-
#status ⇒ Object
Returns the value of attribute status.
-
#streamer ⇒ Object
Returns the value of attribute streamer.
-
#streaming ⇒ Object
Returns the value of attribute streaming.
-
#upgrading_ws ⇒ Object
Returns the value of attribute upgrading_ws.
-
#ws_accept_key ⇒ Object
Returns the value of attribute ws_accept_key.
-
#ws_driver ⇒ Object
Returns the value of attribute ws_driver.
Instance Method Summary collapse
-
#cache_control(v) ⇒ Object
Set the Cache-Control header verbatim.
-
#etag(value) ⇒ Object
Strong ETag validator (quoted per RFC 7232).
-
#expires(secs) ⇒ Object
Cacheable for ‘secs` seconds: set both Expires (absolute HTTP-date) and Cache-Control: max-age (relative).
- #halted_close? ⇒ Boolean
-
#initialize ⇒ Response
constructor
A new instance of Response.
-
#last_modified(epoch) ⇒ Object
Last-Modified validator from Unix epoch seconds.
- #no_cache ⇒ Object
-
#no_store ⇒ Object
Common Cache-Control shortcuts.
- #send_file(path) ⇒ Object
-
#set_body(s) ⇒ Object
Unconditional body setter.
-
#set_body_if_empty(s) ⇒ Object
Spinel’s polymorphic-receiver write codegen emits a no-op for ‘res.body = x` when called from a context that has a poly value, so we force the assignment through this method (where `self` is unambiguously Response).
-
#set_cookie(name, value, opts) ⇒ Object
Sinatra-style cookie writer.
- #set_status(n) ⇒ Object
- #start_stream(streamer) ⇒ Object
-
#start_websocket(accept_key, driver) ⇒ Object
Mark the response as a WebSocket upgrade.
Constructor Details
#initialize ⇒ Response
Returns a new instance of Response.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/tep/response.rb', line 8 def initialize @status = 200 @headers = Tep.str_hash @body = "" @halted = false @file_path = "" # `Set-Cookie` is a header that can repeat; can't shove multiple # values into a Hash slot. Each entry here is one fully-formatted # Set-Cookie line, emitted verbatim by the writer. @set_cookies = [""] @set_cookies.delete_at(0) @streamer = Streamer.new # default no-op; only used when @streaming @streaming = false # WebSocket upgrade slots. The Tep::Server::Scheduled write # path sees @upgrading_ws and, instead of writing the normal # status-line response body, emits the 101 handshake response # then drives the recv loop via Tep::WebSocket::Connection # until the connection closes. @upgrading_ws = false @ws_accept_key = "" @ws_driver = Tep::WebSocket::Driver.new(0) # Last-Modified validator as epoch seconds (0 = unset). The header # carries the formatted date; this is kept for the conditional-GET # comparison against If-Modified-Since (issue #152). @lastmod_epoch = 0 end |
Instance Attribute Details
#body ⇒ Object
Returns the value of attribute body.
6 7 8 |
# File 'lib/tep/response.rb', line 6 def body @body end |
#file_path ⇒ Object
Returns the value of attribute file_path.
6 7 8 |
# File 'lib/tep/response.rb', line 6 def file_path @file_path end |
#halted ⇒ Object
Returns the value of attribute halted.
6 7 8 |
# File 'lib/tep/response.rb', line 6 def halted @halted end |
#headers ⇒ Object
Returns the value of attribute headers.
6 7 8 |
# File 'lib/tep/response.rb', line 6 def headers @headers end |
#lastmod_epoch ⇒ Object (readonly)
Returns the value of attribute lastmod_epoch.
37 38 39 |
# File 'lib/tep/response.rb', line 37 def lastmod_epoch @lastmod_epoch end |
#set_cookies ⇒ Object
Returns the value of attribute set_cookies.
6 7 8 |
# File 'lib/tep/response.rb', line 6 def @set_cookies end |
#status ⇒ Object
Returns the value of attribute status.
6 7 8 |
# File 'lib/tep/response.rb', line 6 def status @status end |
#streamer ⇒ Object
Returns the value of attribute streamer.
35 36 37 |
# File 'lib/tep/response.rb', line 35 def streamer @streamer end |
#streaming ⇒ Object
Returns the value of attribute streaming.
35 36 37 |
# File 'lib/tep/response.rb', line 35 def streaming @streaming end |
#upgrading_ws ⇒ Object
Returns the value of attribute upgrading_ws.
36 37 38 |
# File 'lib/tep/response.rb', line 36 def upgrading_ws @upgrading_ws end |
#ws_accept_key ⇒ Object
Returns the value of attribute ws_accept_key.
36 37 38 |
# File 'lib/tep/response.rb', line 36 def ws_accept_key @ws_accept_key end |
#ws_driver ⇒ Object
Returns the value of attribute ws_driver.
36 37 38 |
# File 'lib/tep/response.rb', line 36 def ws_driver @ws_driver end |
Instance Method Details
#cache_control(v) ⇒ Object
Set the Cache-Control header verbatim.
42 43 44 45 |
# File 'lib/tep/response.rb', line 42 def cache_control(v) @headers["Cache-Control"] = v self end |
#etag(value) ⇒ Object
Strong ETag validator (quoted per RFC 7232).
60 61 62 63 |
# File 'lib/tep/response.rb', line 60 def etag(value) @headers["ETag"] = "\"" + value + "\"" self end |
#expires(secs) ⇒ Object
Cacheable for ‘secs` seconds: set both Expires (absolute HTTP-date) and Cache-Control: max-age (relative).
53 54 55 56 57 |
# File 'lib/tep/response.rb', line 53 def expires(secs) @headers["Expires"] = Sock.sphttp_http_date(Time.now.to_i + secs) @headers["Cache-Control"] = "max-age=" + secs.to_s self end |
#halted_close? ⇒ Boolean
130 131 132 |
# File 'lib/tep/response.rb', line 130 def halted_close? @halted && @status >= 300 end |
#last_modified(epoch) ⇒ Object
Last-Modified validator from Unix epoch seconds. Remembers the epoch so conditional GET can compare it to If-Modified-Since.
67 68 69 70 71 |
# File 'lib/tep/response.rb', line 67 def last_modified(epoch) @lastmod_epoch = epoch @headers["Last-Modified"] = Sock.sphttp_http_date(epoch) self end |
#no_cache ⇒ Object
49 |
# File 'lib/tep/response.rb', line 49 def no_cache; cache_control("no-cache"); end |
#no_store ⇒ Object
Common Cache-Control shortcuts.
48 |
# File 'lib/tep/response.rb', line 48 def no_store; cache_control("no-store"); end |
#send_file(path) ⇒ Object
104 105 106 107 |
# File 'lib/tep/response.rb', line 104 def send_file(path) @file_path = path @body = "" end |
#set_body(s) ⇒ Object
Unconditional body setter. Same poly-write rationale as set_body_if_empty (self is unambiguously Response here, so the ‘@body = s` codegens correctly), but always assigns – used by Tep::Proxy, which writes the upstream body whether or not it’s empty (a 204 / empty upstream body must overwrite, not skip).
124 125 126 |
# File 'lib/tep/response.rb', line 124 def set_body(s) @body = s end |
#set_body_if_empty(s) ⇒ Object
Spinel’s polymorphic-receiver write codegen emits a no-op for ‘res.body = x` when called from a context that has a poly value, so we force the assignment through this method (where `self` is unambiguously Response).
113 114 115 116 117 |
# File 'lib/tep/response.rb', line 113 def set_body_if_empty(s) if @body.length == 0 && s.length > 0 @body = s end end |
#set_cookie(name, value, opts) ⇒ Object
Sinatra-style cookie writer. ‘opts` is a Bag-of-strings (path, expires, max-age, domain, samesite, httponly, secure). Empty `opts` is fine: just writes “name=value”.
90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/tep/response.rb', line 90 def (name, value, opts) line = name + "=" + Url.escape(value) if opts.length > 0 opts.each do |k, v| if v.length == 0 line = line + "; " + k # bare flag (HttpOnly, Secure) else line = line + "; " + k + "=" + v end end end @set_cookies.push(line) end |
#set_status(n) ⇒ Object
128 |
# File 'lib/tep/response.rb', line 128 def set_status(n); @status = n; end |
#start_stream(streamer) ⇒ Object
73 74 75 76 |
# File 'lib/tep/response.rb', line 73 def start_stream(streamer) @streamer = streamer @streaming = true end |
#start_websocket(accept_key, driver) ⇒ Object
Mark the response as a WebSocket upgrade. The server writes a 101 Switching Protocols response with the accept-key, assigns the live client fd onto the driver, then runs the recv loop.
81 82 83 84 85 |
# File 'lib/tep/response.rb', line 81 def start_websocket(accept_key, driver) @upgrading_ws = true @ws_accept_key = accept_key @ws_driver = driver end |