Class: Vines::Stream::Http::Request

Inherits:
Object
  • Object
show all
Defined in:
lib/vines/stream/http/request.rb

Constant Summary collapse

BUF_SIZE =
1024
MODIFIED =
'%a, %d %b %Y %H:%M:%S GMT'.freeze
MOVED =
'Moved Permanently'.freeze
NOT_FOUND =
'Not Found'.freeze
NOT_MODIFIED =
'Not Modified'.freeze
IF_MODIFIED =
'If-Modified-Since'.freeze
TEXT_PLAIN =
'text/plain'.freeze
OPTIONS =
'OPTIONS'.freeze
CONTENT_TYPES =
{
  'html'     => 'text/html; charset="utf-8"',
  'js'       => 'application/javascript; charset="utf-8"',
  'css'      => 'text/css',
  'png'      => 'image/png',
  'jpg'      => 'image/jpeg',
  'jpeg'     => 'image/jpeg',
  'gif'      => 'image/gif',
  'manifest' => 'text/cache-manifest'
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stream, parser, body) ⇒ Request

Returns a new instance of Request.



28
29
30
31
32
33
34
35
36
# File 'lib/vines/stream/http/request.rb', line 28

def initialize(stream, parser, body)
  @stream, @body = stream, body
  @headers  = parser.headers
  @method   = parser.http_method
  @path     = parser.request_path
  @url      = parser.request_url
  @query    = parser.query_string
  @received = Time.now
end

Instance Attribute Details

#bodyObject (readonly)

Returns the value of attribute body.



26
27
28
# File 'lib/vines/stream/http/request.rb', line 26

def body
  @body
end

#headersObject (readonly)

Returns the value of attribute headers.



26
27
28
# File 'lib/vines/stream/http/request.rb', line 26

def headers
  @headers
end

#methodObject (readonly)

Returns the value of attribute method.



26
27
28
# File 'lib/vines/stream/http/request.rb', line 26

def method
  @method
end

#pathObject (readonly)

Returns the value of attribute path.



26
27
28
# File 'lib/vines/stream/http/request.rb', line 26

def path
  @path
end

#queryObject (readonly)

Returns the value of attribute query.



26
27
28
# File 'lib/vines/stream/http/request.rb', line 26

def query
  @query
end

#streamObject (readonly)

Returns the value of attribute stream.



26
27
28
# File 'lib/vines/stream/http/request.rb', line 26

def stream
  @stream
end

#urlObject (readonly)

Returns the value of attribute url.



26
27
28
# File 'lib/vines/stream/http/request.rb', line 26

def url
  @url
end

Instance Method Details

#ageObject

Return the number of seconds since this request was received.



39
40
41
# File 'lib/vines/stream/http/request.rb', line 39

def age
  Time.now - @received
end

#options?Boolean

Return true if the request method is OPTIONS, signaling a CORS preflight check.

Returns:

  • (Boolean)


86
87
88
# File 'lib/vines/stream/http/request.rb', line 86

def options?
  @method == OPTIONS
end

#reply(node, content_type) ⇒ Object

Send an HTTP 200 OK response wrapping the XMPP node content back to the client.



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/vines/stream/http/request.rb', line 72

def reply(node, content_type)
  body = node.to_s
  header = [
    "HTTP/1.1 200 OK",
    "Access-Control-Allow-Origin: *",
    "Content-Type: #{content_type}",
    "Content-Length: #{body.bytesize}",
    vroute_cookie
  ].compact.join("\r\n")
  @stream.stream_write([header, body].join("\r\n\r\n"))
end

#reply_to_optionsObject

Send a 200 OK response, allowing any origin domain to connect to the server, in response to CORS preflight OPTIONS requests. This allows any web application using strophe.js to connect to our BOSH port.



93
94
95
96
97
98
99
100
101
102
# File 'lib/vines/stream/http/request.rb', line 93

def reply_to_options
  allow = @headers['Access-Control-Request-Headers']
  headers = [
    "Access-Control-Allow-Origin: *",
    "Access-Control-Allow-Methods: POST, GET, OPTIONS",
    "Access-Control-Allow-Headers: #{allow}",
    "Access-Control-Max-Age: #{60 * 60 * 24 * 30}"
  ]
  send_status(200, 'OK', headers)
end

#reply_with_file(dir) ⇒ Object

Write the requested file to the client out of the given document root directory. Take care to prevent directory traversal attacks with paths like ../../../etc/passwd. Use the If-Modified-Since request header to implement caching.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/vines/stream/http/request.rb', line 47

def reply_with_file(dir)
  path = File.expand_path(File.join(dir, @path))

  # redirect requests missing a slash so relative links work
  if File.directory?(path) && !@path.end_with?('/')
    send_status(301, MOVED, "Location: #{redirect_uri}")
    return
  end

  path = File.join(path, 'index.html') if File.directory?(path)

  if path.start_with?(dir) && File.exist?(path)
    modified?(path) ? send_file(path) : send_status(304, NOT_MODIFIED)
  else
    missing = File.join(dir, '404.html')
    if File.exist?(missing)
      send_file(missing, 404, NOT_FOUND)
    else
      send_status(404, NOT_FOUND)
    end
  end
end