Module: Wunderbar::CGI

Defined in:
lib/wunderbar/cgi-methods.rb

Class Method Summary collapse

Class Method Details

.call(scope) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/wunderbar/cgi-methods.rb', line 82

def self.call(scope)
  env = scope.env
  accept      = env['HTTP_ACCEPT'].to_s
  request_uri = env['REQUEST_URI'].to_s

  # implied request types
  xhr_json = Wunderbar::Options::XHR_JSON  || (accept =~ /json/)
  text = Wunderbar::Options::TEXT || 
    (accept =~ /plain/ and accept !~ /html/)
  @xhtml = (accept =~ /xhtml/ or accept == '')

  # overrides via the uri query parameter
  xhr_json ||= (request_uri =~ /\?json$/)
  text     ||= (request_uri =~ /\?text$/)

  # overrides via the command line
  xhtml_override = ARGV.include?('--xhtml')
  html_override  = ARGV.include?('--html')

  # disable conneg if only one handler is provided
  if Wunderbar.queue.length == 1
    type = Wunderbar.queue.first.first
    xhr_json = (type == :json)
    text     = (type == :text)
  end

  Wunderbar.queue.each do |type, args, block|
    case type
    when :html, :xhtml
      unless xhr_json or text
        if type == :html
          @xhtml = false unless xhtml_override
        else
          @xhtml = false if html_override
        end

        self.html(scope, *args, &block)
        return
      end
    when :json
      if xhr_json
        self.json(scope, *args, &block)
        return
      end
    when :text
      if text
        self.text(scope, *args, &block)
        return
      end
    end
  end
end

.headers(headers) ⇒ Object

map Ruby CGI headers to Rack headers



136
137
138
139
140
141
142
143
# File 'lib/wunderbar/cgi-methods.rb', line 136

def self.headers(headers)
  result = headers.dup
  type = result.delete('type') || 'text/html'
  charset = result.delete('charset')
  type = "#{type}; charset=#{charset}" if charset
  result['Content-Type'] ||= type
  result
end

.html(scope, *args, &block) ⇒ Object

produce html/xhtml



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/wunderbar/cgi-methods.rb', line 53

def self.html(scope, *args, &block)
  headers = { 'type' => 'text/html', 'charset' => 'UTF-8' }
  headers['type'] = 'application/xhtml+xml' if @xhtml

  x = HtmlMarkup.new(scope)

  begin
    if @xhtml
      output = x.xhtml *args, &block
    else
      output = x.html *args, &block
    end
  rescue ::Exception => exception
    headers['status'] =  "500 Internal Server Error"
    x.clear!
    output = x.html(*args) do
      _head do
        _title 'Internal Server Error'
      end
      _body do
        _h1 'Internal Server Error'
        _exception exception
      end
    end
  end

  out?(scope, headers) { output }
end

.json(scope, &block) ⇒ Object

produce json



7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/wunderbar/cgi-methods.rb', line 7

def self.json(scope, &block)
  headers = { 'type' => 'application/json', 'Cache-Control' => 'no-cache' }
  builder = JsonBuilder.new(scope)
  output = builder.encode(&block)
  headers['status'] =  "404 Not Found" if output == {}
rescue Exception => exception
  headers['status'] =  "500 Internal Server Error"
  builder._! Hash.new
  builder._exception exception
ensure
  out?(scope, headers) { builder.target! }
end

.out?(scope, headers, &block) ⇒ Boolean

Conditionally provide output, based on ETAG

Returns:

  • (Boolean)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/wunderbar/cgi-methods.rb', line 34

def self.out?(scope, headers, &block)
  content = block.call
  etag = Digest::MD5.hexdigest(content)

  if scope.env['HTTP_IF_NONE_MATCH'] == etag.inspect
    headers['Date'] = ::CGI.rfc1123_date(Time.now)
    scope.out headers.merge('status' => '304 Not Modified') do
      ''
    end
  else
    scope.out headers.merge('Etag' => etag.inspect) do
      content
    end
  end
rescue Exception => exception
  Wunderbar.fatal exception.inspect
end

.text(scope, &block) ⇒ Object

produce text



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/wunderbar/cgi-methods.rb', line 21

def self.text(scope, &block)
  headers = {'type' => 'text/plain', 'charset' => 'UTF-8'}
  builder = TextBuilder.new(scope)
  output = builder.encode(&block)
  headers['status'] =  "404 Not Found" if output == ''
rescue Exception => exception
  headers['status'] =  "500 Internal Server Error"
  builder._exception exception
ensure
  out?(scope, headers) { builder.target! }
end