Class: Wsv::Response

Inherits:
Object
  • Object
show all
Defined in:
lib/wsv/response.rb

Constant Summary collapse

SERVER_NAME =
"wsv/#{Wsv::VERSION}".freeze
INVALID_HEADER_NAME =
/[\s:]/
INVALID_HEADER_VALUE =
/[\r\n]/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(status:, headers: {}, body: "") ⇒ Response

Returns a new instance of Response.



17
18
19
20
21
22
23
24
25
# File 'lib/wsv/response.rb', line 17

def initialize(status:, headers: {}, body: "")
  headers.each do |name, value|
    raise ArgumentError, "invalid header name: #{name.inspect}" if name.to_s.match?(INVALID_HEADER_NAME)
    raise ArgumentError, "invalid header value: #{value.inspect}" if value.to_s.match?(INVALID_HEADER_VALUE)
  end
  @status = status
  @headers = headers
  @body = body
end

Instance Attribute Details

#bodyObject (readonly)

Returns the value of attribute body.



15
16
17
# File 'lib/wsv/response.rb', line 15

def body
  @body
end

#headersObject (readonly)

Returns the value of attribute headers.



15
16
17
# File 'lib/wsv/response.rb', line 15

def headers
  @headers
end

#statusObject (readonly)

Returns the value of attribute status.



15
16
17
# File 'lib/wsv/response.rb', line 15

def status
  @status
end

Class Method Details

.file(path, head: false) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/wsv/response.rb', line 50

def self.file(path, head: false)
  new(
    status: 200,
    headers: {
      "Content-Type" => MimeTypes.for_file(path),
      "Content-Length" => File.size(path).to_s,
      "Last-Modified" => File.mtime(path).httpdate,
      "Cache-Control" => "no-cache"
    },
    body: head ? "" : File.binread(path)
  )
end

.redirect(location, head: false) ⇒ Object



63
64
65
# File 'lib/wsv/response.rb', line 63

def self.redirect(location, head: false)
  text(301, headers: { "Location" => location }, head: head)
end

.text(status, headers: {}, head: false) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'lib/wsv/response.rb', line 40

def self.text(status, headers: {}, head: false)
  body = "#{status} #{Status.reason(status)}\n"
  base = {
    "Content-Type" => "text/plain; charset=utf-8",
    "Content-Length" => body.bytesize.to_s,
    "Cache-Control" => "no-cache"
  }
  new(status: status, headers: base.merge(headers), body: head ? "" : body)
end

Instance Method Details

#reasonObject



27
28
29
# File 'lib/wsv/response.rb', line 27

def reason
  Status.reason(status)
end

#write_to(io) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/wsv/response.rb', line 31

def write_to(io)
  io.write "HTTP/1.1 #{status} #{reason}\r\n"
  io.write "Server: #{SERVER_NAME}\r\n"
  io.write "Connection: close\r\n"
  headers.each { |name, value| io.write "#{name}: #{value}\r\n" }
  io.write "\r\n"
  io.write body
end