Module: Qeweney::ResponseMethods
- Included in:
- Request
- Defined in:
- lib/qeweney/response.rb
Constant Summary collapse
- WEBSOCKET_GUID =
'258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
Instance Method Summary collapse
- #file_full_path(path, opts) ⇒ Object
- #redirect(url, status = Status::FOUND) ⇒ Object
- #redirect_to_host(new_host, status = Status::FOUND) ⇒ Object
- #redirect_to_https(status = Status::MOVED_PERMANENTLY) ⇒ Object
- #respond_with_static_file(path, etag, last_modified, opts) ⇒ Object
- #serve_file(path, opts = {}) ⇒ Object
- #serve_io(io, opts) ⇒ Object
- #serve_io_deflate(io, opts) ⇒ Object
- #serve_io_gzip(io, opts) ⇒ Object
- #serve_rack(app) ⇒ Object
- #upgrade(protocol, custom_headers = nil) ⇒ Object
- #upgrade_to_websocket(custom_headers = nil) ⇒ Object
- #validate_static_file_cache(etag, last_modified) ⇒ Object
Instance Method Details
#file_full_path(path, opts) ⇒ Object
121 122 123 124 125 126 127 |
# File 'lib/qeweney/response.rb', line 121 def file_full_path(path, opts) if (base_path = opts[:base_path]) File.join(opts[:base_path], path) else path end end |
#redirect(url, status = Status::FOUND) ⇒ Object
49 50 51 |
# File 'lib/qeweney/response.rb', line 49 def redirect(url, status = Status::FOUND) respond(nil, ':status' => status, 'Location' => url) end |
#redirect_to_host(new_host, status = Status::FOUND) ⇒ Object
58 59 60 61 |
# File 'lib/qeweney/response.rb', line 58 def redirect_to_host(new_host, status = Status::FOUND) secure_uri = "//#{new_host}#{uri}" redirect(secure_uri, status) end |
#redirect_to_https(status = Status::MOVED_PERMANENTLY) ⇒ Object
53 54 55 56 |
# File 'lib/qeweney/response.rb', line 53 def redirect_to_https(status = Status::MOVED_PERMANENTLY) secure_uri = "https://#{host}#{uri}" redirect(secure_uri, status) end |
#respond_with_static_file(path, etag, last_modified, opts) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/qeweney/response.rb', line 85 def respond_with_static_file(path, etag, last_modified, opts) cache_headers = { 'etag' => etag, 'last-modified' => last_modified, } File.open(path, 'r') do |f| if opts[:headers] opts[:headers].merge!(cache_headers) else opts[:headers] = cache_headers end # accept_encoding should return encodings in client's order of preference accept_encoding.each do |encoding| case encoding when 'deflate' return serve_io_deflate(f, opts) when 'gzip' return serve_io_gzip(f, opts) end end serve_io(f, opts) end end |
#serve_file(path, opts = {}) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/qeweney/response.rb', line 63 def serve_file(path, opts = {}) full_path = file_full_path(path, opts) stat = File.stat(full_path) etag = StaticFileCaching.file_stat_to_etag(stat) last_modified = StaticFileCaching.file_stat_to_last_modified(stat) if validate_static_file_cache(etag, last_modified) return respond(nil, { ':status' => Status::NOT_MODIFIED, 'etag' => etag }) end mime_type = Qeweney::MimeTypes[File.extname(path)] opts[:stat] = stat (opts[:headers] ||= {})['Content-Type'] ||= mime_type if mime_type respond_with_static_file(full_path, etag, last_modified, opts) rescue Errno::ENOENT => e respond(nil, ':status' => Status::NOT_FOUND) end |
#serve_io(io, opts) ⇒ Object
129 130 131 |
# File 'lib/qeweney/response.rb', line 129 def serve_io(io, opts) respond(io.read, opts[:headers] || {}) end |
#serve_io_deflate(io, opts) ⇒ Object
133 134 135 136 137 138 139 140 141 |
# File 'lib/qeweney/response.rb', line 133 def serve_io_deflate(io, opts) deflate = Zlib::Deflate.new headers = opts[:headers].merge( 'content-encoding' => 'deflate', 'vary' => 'Accept-Encoding' ) respond(deflate.deflate(io.read, Zlib::FINISH), headers) end |
#serve_io_gzip(io, opts) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/qeweney/response.rb', line 143 def serve_io_gzip(io, opts) buf = StringIO.new z = Zlib::GzipWriter.new(buf) z << io.read z.flush z.close headers = opts[:headers].merge( 'content-encoding' => 'gzip', 'vary' => 'Accept-Encoding' ) respond(buf.string, headers) end |
#serve_rack(app) ⇒ Object
156 157 158 159 160 161 162 163 164 |
# File 'lib/qeweney/response.rb', line 156 def serve_rack(app) response = app.(Qeweney.rack_env_from_request(self)) headers = (response[1] || {}).merge(':status' => response[0]) respond(response[2].join, headers) # TODO: send separate chunks for multi-part body # TODO: add support for streaming body # TODO: add support for websocket end |
#upgrade(protocol, custom_headers = nil) ⇒ Object
25 26 27 28 29 30 31 32 33 34 |
# File 'lib/qeweney/response.rb', line 25 def upgrade(protocol, custom_headers = nil) upgrade_headers = { ':status' => Status::SWITCHING_PROTOCOLS, 'Upgrade' => protocol, 'Connection' => 'upgrade' } upgrade_headers.merge!(custom_headers) if custom_headers respond(nil, upgrade_headers) end |
#upgrade_to_websocket(custom_headers = nil) ⇒ Object
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/qeweney/response.rb', line 38 def upgrade_to_websocket(custom_headers = nil) key = "#{headers['sec-websocket-key']}#{WEBSOCKET_GUID}" upgrade_headers = { 'Sec-WebSocket-Accept' => Digest::SHA1.base64digest(key) } upgrade_headers.merge!(custom_headers) if custom_headers upgrade('websocket', upgrade_headers) adapter.websocket_connection(self) end |
#validate_static_file_cache(etag, last_modified) ⇒ Object
110 111 112 113 114 115 116 117 118 119 |
# File 'lib/qeweney/response.rb', line 110 def validate_static_file_cache(etag, last_modified) if (none_match = headers['if-none-match']) return true if none_match == etag end if (modified_since = headers['if-modified-since']) return true if modified_since == last_modified end false end |