pakyow-core 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 062ec93abfc6a96dd0b24672d552144f1fe524e8
4
- data.tar.gz: bea34efd0af7831aa5ed5e28a525f37d162760c6
3
+ metadata.gz: 0eaf60c5af9154f9df19ab14a96308f39edafd34
4
+ data.tar.gz: 5a05552bab16a0579908bf7184aff752a6cf11d7
5
5
  SHA512:
6
- metadata.gz: 6867a6cee9e72ddd59d7d0a72cd2cc83ea4ba55e39c268ac34b48a666e3d5af8b02e0390e9bb9eb8356f47fd337316b13a9e81f3e1e3fffa623ff64ce0a5b096
7
- data.tar.gz: bf82dce8e66153023bb34d8bc89a78d4ed992d69631b6f58ca5e7d334b40ef1cdf2ccba4a3e013e07cc2f9d6daeda2e5a2f8780e30f845e55a98eec5e4871cdd
6
+ metadata.gz: b021ba547095c48b6b82c7d31300f25ca3b93a14e602725987fc6e4c20c0031a14cd4da1b48bd3669911eccfc6138448a5118d28265681946783786351745c32
7
+ data.tar.gz: f918b4f215fb736be9cab8ea44df1901599ca0227f923ef2c2366595a462703906e2f03ccf2c522d8859334703f662c90ea858d74f44c5b660e9ee5eb7a521c5
@@ -1,8 +1,35 @@
1
- = 0.9.1 / 2014-12-06
1
+ # 0.10.0 (to be released)
2
+
3
+ * Adds nested route groups / namespaces inherit hooks
4
+ * Static files are now served by default
5
+ * Consistently handles externally defined config options
6
+ * Adds post-processing step to route template expansions
7
+ * Prevents the logger from breaking when no log to write to
8
+ * Prevents resouces config from being reset on access
9
+ * Don't add query params when route building
10
+ * Fixes bug when defining nested restful routes
11
+ * Support passing group + route name to `redir` and `reroute`
12
+ * Updated status code names
13
+ * Sets mime type of response when setting type
14
+ * Exposes content type on response object
15
+ * Adds support for `pakyow.data` in Rack env
16
+ * Runs global config *after* local config
17
+ * Makes JSON body available in request params
18
+ * Fixes a bug in app reloading
19
+ * Ported all tests to rspec
20
+ * Adds the ability to halt execution in a 500 handler
21
+ * Fixes namespace collisions
22
+ * Use app's template for displaying Pakyow error views
23
+ * Provides default values for helpers when no context available
24
+ * Use `Bundler.require` to load dependencies in global config block
25
+ * Respects before hook order
26
+ * No longer overrides user-provided type when sending data/files
27
+
28
+ # 0.9.1 / 2014-12-06
2
29
 
3
30
  * No changes -- bumped version to be consistent
4
31
 
5
- = 0.9.0 / 2014-11-09
32
+ # 0.9.0 / 2014-11-09
6
33
 
7
34
  * Renames restful "remove" action to "delete"
8
35
  * Improves app generator bundle install by showing progress
@@ -10,17 +37,17 @@
10
37
  * Includes pakyow-rake as a dependency, and updates the generated Rakefile
11
38
  * Removes support for Ruby versions < 2.0.0
12
39
 
13
- = 0.8.0 / 2014-03-02
40
+ # 0.8.0 / 2014-03-02
14
41
 
15
42
  * Major rewrite, including changes to app definition and routing
16
43
 
17
- = 0.7.2 / 2012-02-29
44
+ # 0.7.2 / 2012-02-29
18
45
 
19
46
  * Application server shuts down gracefully
20
47
  * Fix issue requesting route with format
21
48
  * Fix issue surrounding ignore_routes -- now matches request path in all cases
22
49
 
23
- = 0.7.1 / 2012-01-08
50
+ # 0.7.1 / 2012-01-08
24
51
 
25
52
  * Changed loader to only load ruby files
26
53
  * Moved session from app to request
@@ -29,7 +56,7 @@
29
56
  * Fixed generated rakefile so it runs in a specific environment
30
57
  * Fixed issue running with ignore_routes turned on
31
58
 
32
- = 0.7.0 / 2011-11-19
59
+ # 0.7.0 / 2011-11-19
33
60
 
34
61
  * Added middleware for logging, static, and reloading
35
62
  * Added invoke_route! and invoke_handler! methods
@@ -40,24 +67,24 @@
40
67
  * App file is no longer loaded twice upon initialization
41
68
  * Fix cookie creation when cookie is a non-nil value but not a String
42
69
 
43
- = 0.6.3 / 2011-09-13
70
+ # 0.6.3 / 2011-09-13
44
71
 
45
72
  * Fixes several load path issues
46
73
  * Fixes gemspecs so gem can be built/used from anywhere
47
74
  * Fixes inconsistency with with request.params having string and symbol keys
48
75
  * Fixes loading of middleware when staging application (simplifies rackup)
49
76
 
50
- = 0.6.2 / 2011-08-20
77
+ # 0.6.2 / 2011-08-20
51
78
 
52
79
  * Fixes issue running pakyow server on Windows
53
80
  * Fixes several issues related to error handlers
54
81
  * Fixes an issue when using alphanumeric ids in restful routes
55
82
  * JRuby Support
56
83
 
57
- = 0.6.1 / 2011-08-20
84
+ # 0.6.1 / 2011-08-20
58
85
 
59
86
  * Fixes gemspec problem
60
87
 
61
- = 0.6.0 / 2011-08-20
88
+ # 0.6.0 / 2011-08-20
62
89
 
63
90
  * Initial gem release of 0.6.0 codebase
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Bryan Powell
1
+ Copyright (c) 2011-2015 Bryan Powell
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ # pakyow-core
2
+
3
+ Core routing for Pakyow.
4
+
5
+ # Download
6
+
7
+ The latest version of Pakyow Core can be installed with RubyGems:
8
+
9
+ ```
10
+ gem install pakyow-core
11
+ ```
12
+
13
+ Source code can be downloaded as part of the Pakyow project on Github:
14
+
15
+ - https://github.com/pakyow/pakyow/tree/master/pakyow-core
16
+
17
+ # License
18
+
19
+ Pakyow Core is released free and open-source under the [MIT
20
+ License](http://opensource.org/licenses/MIT).
21
+
22
+ # Support
23
+
24
+ Documentation is available here:
25
+
26
+ - http://pakyow.org/docs/routing
27
+
28
+ Found a bug? Tell us about it here:
29
+
30
+ - https://github.com/pakyow/pakyow/issues
31
+
32
+ We'd love to have you in the community:
33
+
34
+ - http://pakyow.org/get-involved
@@ -39,6 +39,7 @@ module Pakyow
39
39
  return if running?
40
40
 
41
41
  @running = true
42
+
42
43
  builder.run(stage(*env_or_envs))
43
44
  detect_handler.run(builder, Host: config.server.host, Port: config.server.port) do |server|
44
45
  trap(:INT) { stop(server) }
@@ -143,16 +144,16 @@ module Pakyow
143
144
  config.app.loaded_envs = envs
144
145
  config.env = envs.first.to_sym
145
146
 
146
- # run global config first
147
- if global_proc = @@config[:global]
148
- config.app_config(&global_proc)
149
- end
150
-
151
- # then run other envs
147
+ # run specific config first
152
148
  envs.each do |env|
153
149
  next unless config_proc = @@config[env.to_sym]
154
150
  config.app_config(&config_proc)
155
151
  end
152
+
153
+ # then run global config
154
+ if global_proc = @@config[:global]
155
+ config.app_config(&global_proc)
156
+ end
156
157
  end
157
158
 
158
159
  protected
@@ -251,20 +252,12 @@ module Pakyow
251
252
  unless found?
252
253
  handle(404, false)
253
254
 
254
- if config.app.errors_in_browser
255
- response["Content-Type"] = 'text/html'
256
-
257
- view_file = File.join(File.expand_path('../../', __FILE__), 'views', 'errors', '404.html')
258
- content = File.open(view_file).read
259
-
255
+ present_error 404 do |content|
260
256
  path = String.normalize_path(request.path)
261
257
  path = '/' if path.empty?
262
258
 
263
- content.gsub!('{view_path}', path == '/' ? 'index.html' : "#{path}.html")
264
259
  content.gsub!('{route_path}', path)
265
-
266
- response.body = []
267
- response.body << content
260
+ content
268
261
  end
269
262
  end
270
263
  }
@@ -275,31 +268,24 @@ module Pakyow
275
268
 
276
269
  response.finish
277
270
  rescue StandardError => error
278
- call_stack(:before, :error)
279
-
280
271
  request.error = error
281
272
 
282
- handle(500, false) unless found?
283
-
284
- if config.app.errors_in_browser
285
- response["Content-Type"] = 'text/html'
286
-
287
- view_file = File.join(File.expand_path('../../', __FILE__), 'views', 'errors', '500.html')
288
- content = File.open(view_file).read
273
+ catch :halt do
274
+ call_stack(:before, :error)
289
275
 
290
- path = String.normalize_path(request.path)
291
- path = '/' if path.empty?
276
+ handle(500, false) unless found?
292
277
 
293
- nice_source = error.backtrace[0].match(/^(.+?):(\d+)(|:in `(.+)')$/)
278
+ present_error 500 do |content|
279
+ nice_source = error.backtrace[0].match(/^(.+?):(\d+)(|:in `(.+)')$/)
294
280
 
295
- content.gsub!('{file}', nice_source[1].gsub(File.expand_path(Config.app.root) + '/', ''))
296
- content.gsub!('{line}', nice_source[2])
281
+ content.gsub!('{file}', nice_source[1].gsub(File.expand_path(Config.app.root) + '/', ''))
282
+ content.gsub!('{line}', nice_source[2])
297
283
 
298
- content.gsub!('{msg}', CGI.escapeHTML(error.to_s))
299
- content.gsub!('{trace}', error.backtrace.map { |bt| CGI.escapeHTML(bt) }.join('<br>'))
284
+ content.gsub!('{msg}', CGI.escapeHTML("#{error.class}: #{error}"))
285
+ content.gsub!('{trace}', error.backtrace.map { |bt| CGI.escapeHTML(bt) }.join('<br>'))
300
286
 
301
- response.body = []
302
- response.body << content
287
+ content
288
+ end
303
289
  end
304
290
 
305
291
  call_stack(:after, :error)
@@ -336,8 +322,9 @@ module Pakyow
336
322
 
337
323
  # Routes the request to different logic.
338
324
  #
339
- def reroute(path, method = nil)
340
- request.setup(path, method)
325
+ def reroute(location, method = nil)
326
+ location = Router.instance.path(location)
327
+ request.setup(location, method)
341
328
 
342
329
  call_stack(:before, :route)
343
330
  call_stack(:after, :match)
@@ -356,7 +343,7 @@ module Pakyow
356
343
  data = file_or_data.read
357
344
 
358
345
  # auto set type based on file type
359
- type = Rack::Mime.mime_type("." + String.split_at_last_dot(file_or_data.path)[1])
346
+ type ||= Rack::Mime.mime_type("." + String.split_at_last_dot(file_or_data.path)[1])
360
347
  else
361
348
  data = file_or_data
362
349
  end
@@ -372,7 +359,7 @@ module Pakyow
372
359
  # Redirects to location (immediately).
373
360
  #
374
361
  def redirect(location, status_code = 302)
375
- location = router.path(location) if location.is_a?(Symbol)
362
+ location = Router.instance.path(location)
376
363
 
377
364
  headers = response ? response.header : {}
378
365
  headers = headers.merge({'Location' => location})
@@ -408,7 +395,7 @@ module Pakyow
408
395
  call_stack(:before, :load)
409
396
 
410
397
  # load src files
411
- @loader = Loader.new
398
+ @loader ||= Loader.new
412
399
  @loader.load_from_path(config.app.src_dir)
413
400
 
414
401
  # load the routes
@@ -454,6 +441,30 @@ module Pakyow
454
441
  }
455
442
  end
456
443
 
444
+ def present_error(code)
445
+ return unless config.app.errors_in_browser
446
+
447
+ response["Content-Type"] = 'text/html'
448
+
449
+ if block_given?
450
+ content = yield(content_for_code(code))
451
+ end
452
+
453
+ response.body = [content]
454
+ end
455
+
456
+ def content_for_code(code)
457
+ File.open(
458
+ File.join(
459
+ File.expand_path(
460
+ '../../', __FILE__),
461
+ 'views',
462
+ 'errors',
463
+ code.to_s + '.html'
464
+ )
465
+ ).read
466
+ end
467
+
457
468
  end
458
469
 
459
470
  App.reset
@@ -9,6 +9,8 @@ require 'core/route_merger'
9
9
  require 'core/route_module'
10
10
  require 'core/route_set'
11
11
  require 'core/route_eval'
12
+ require 'core/route_expansion_eval'
13
+ require 'core/route_template_eval'
12
14
  require 'core/route_template_defaults'
13
15
  require 'core/route_lookup'
14
16
  require 'core/app'
@@ -25,9 +27,11 @@ require 'core/middleware/static'
25
27
  require 'core/middleware/reloader'
26
28
 
27
29
  module Pakyow
28
- attr_accessor :app, :logger
30
+ class << self
31
+ attr_accessor :app, :logger
32
+ end
29
33
 
30
- def configure_logger
34
+ def self.configure_logger
31
35
  logs = []
32
36
 
33
37
  if File.directory?(Config.logger.path)
@@ -10,7 +10,11 @@ Pakyow::Config.register(:app) { |config|
10
10
  config.opt :root, File.dirname('')
11
11
 
12
12
  # the location of the app's resources
13
- config.opt :resources, lambda { { default: File.join(root, 'public') } }
13
+ config.opt :resources, lambda {
14
+ @resources ||= {
15
+ default: File.join(root, 'public')
16
+ }
17
+ }
14
18
 
15
19
  # the location of the app's source code
16
20
  config.opt :src_dir, lambda { File.join(root, 'app', 'lib') }
@@ -34,7 +38,7 @@ Pakyow::Config.register(:app) { |config|
34
38
  config.opt :log, true
35
39
 
36
40
  # whether or not pakyow should serve static files
37
- config.opt :static
41
+ config.opt :static, true
38
42
 
39
43
  # stores the path to the app definition
40
44
  config.opt :path, lambda { Pakyow::App.path }
@@ -53,13 +57,13 @@ Pakyow::Config.register(:app) { |config|
53
57
  opts.auto_reload = false
54
58
  opts.errors_in_browser = true
55
59
  opts.log_output = false
56
- opts.static = false
60
+ opts.static = true
57
61
 
58
62
  }.env(:production) { |opts|
59
63
 
60
64
  opts.auto_reload = false
61
65
  opts.errors_in_browser = false
62
66
  opts.log_output = false
63
- opts.static = false
67
+ opts.static = true
64
68
 
65
69
  }
@@ -32,14 +32,16 @@ module Pakyow
32
32
 
33
33
  attr_reader :config_name
34
34
 
35
- def initialize(name)
35
+ def initialize(name, default_config: false)
36
36
  @config_name = name
37
37
  @opts = {}
38
38
  @envs = {}
39
+ @default_config = default_config
39
40
  end
40
41
 
41
42
  def defaults
42
- @defaults ||= Pakyow::Config.new("#{@config_name}.defaults")
43
+ return if @default_config # don't define defaults for defaults
44
+ @defaults ||= Pakyow::Config.new("#{@config_name}.defaults", default_config: true)
43
45
  end
44
46
 
45
47
  def env(name)
@@ -55,13 +57,14 @@ module Pakyow
55
57
  end
56
58
 
57
59
  def value(name, *args)
58
- value = @opts.fetch(name) { raise(ConfigError.new("No config option available for `#{@config_name}.#{name}`")) }
60
+ value = @opts.fetch(name) { raise(ConfigError.new("No config value available for `#{@config_name}.#{name}`")) }
59
61
  value = instance_exec(*args, &value) if value.is_a?(Proc)
60
62
  value
61
63
  end
62
64
 
63
65
  def opt(name, default = nil)
64
- @opts[name] = default
66
+ context = defaults ? defaults : self
67
+ context.instance_variable_get(:@opts)[name] = default
65
68
  end
66
69
 
67
70
  def reset
@@ -83,7 +86,7 @@ module Pakyow
83
86
  end
84
87
  end
85
88
 
86
- raise(ConfigError.new("No config option available for `#{@config_name}.#{method}`"))
89
+ raise(ConfigError.new("No config value available for `#{@config_name}.#{method}`"))
87
90
  end
88
91
  end
89
92
  end
@@ -14,25 +14,25 @@ module Pakyow
14
14
  end
15
15
 
16
16
  def request
17
- context.request
17
+ context ? context.request : nil
18
18
  end
19
19
  alias_method :req, :request
20
20
 
21
21
  def response
22
- context.response
22
+ context ? context.response : nil
23
23
  end
24
24
  alias_method :res, :response
25
25
 
26
26
  def params
27
- request.params
27
+ request ? request.params : {}
28
28
  end
29
29
 
30
30
  def session
31
- request.session
31
+ request ? request.session : {}
32
32
  end
33
33
 
34
34
  def cookies
35
- request.cookies
35
+ request ? request.cookies : {}
36
36
  end
37
37
 
38
38
  def config
@@ -40,6 +40,7 @@ module Pakyow
40
40
  end
41
41
 
42
42
  def <<(msg = nil, severity = :unknown)
43
+ return if @log.nil?
43
44
  msg << "\n"
44
45
 
45
46
  msg = format(msg, severity) if @format
@@ -102,7 +103,7 @@ module Pakyow
102
103
  # handles logging after an error occurs
103
104
  Pakyow::App.after(:error) {
104
105
  error = request.error
105
- Pakyow.logger.error "[500] #{error}\n" + error.backtrace.join("\n") + "\n\n"
106
+ Pakyow.logger.error "[500] #{error.class}: #{error}\n" + error.backtrace.join("\n") + "\n\n"
106
107
  }
107
108
 
108
109
  def initialize(app)
@@ -132,60 +133,7 @@ module Pakyow
132
133
  end
133
134
 
134
135
  def nice_status(status)
135
- {
136
- 100 => 'Continue',
137
- 101 => 'Switching Protocols',
138
-
139
- 200 => 'OK',
140
- 201 => 'Created',
141
- 202 => 'Accepted',
142
- 203 => 'Non-Authoritative Information',
143
- 204 => 'No Content',
144
- 205 => 'Reset Content',
145
- 206 => 'Partial Content',
146
-
147
- 300 => 'Multiple Choices',
148
- 301 => 'Moved Permanently',
149
- 302 => 'Found',
150
- 303 => 'See Other',
151
- 304 => 'Not Modified',
152
- 305 => 'Use Proxy',
153
- 306 => 'Switch Proxy',
154
- 307 => 'Temporary Redirect',
155
-
156
- 400 => 'Bad Request',
157
- 401 => 'Unauthorized',
158
- 402 => 'Payment Required',
159
- 403 => 'Forbidden',
160
- 404 => 'Not Found',
161
- 405 => 'Method Not Allowed',
162
- 406 => 'Not Acceptable',
163
- 407 => 'Proxy Authentication Required',
164
- 408 => 'Request Timeout',
165
- 409 => 'Conflict',
166
- 410 => 'Gone',
167
- 411 => 'Length Required',
168
- 412 => 'Precondition Failed',
169
- 413 => 'Request Entity Too Large',
170
- 414 => 'Request-URI Too Long',
171
- 415 => 'Unsupported Media Type',
172
- 416 => 'Requested Range Not Satisfiable',
173
- 417 => 'Expectation Failed',
174
- 418 => 'I\'m a teapot',
175
-
176
- 500 => 'Internal Server Error',
177
- 501 => 'Not Implemented',
178
- 502 => 'Bad Gateway',
179
- 503 => 'Service Unavailable',
180
- 504 => 'Gateway Timeout',
181
- 505 => 'HTTP Version Not Supported',
182
- 506 => 'Variant Also Negotiates',
183
- 507 => 'Insufficient Storage',
184
- 508 => 'Loop Detected',
185
- 509 => 'Bandwidth Limit Exceeded',
186
- 510 => 'Not Extended',
187
- 511 => 'Network Authentication Required'
188
- }[status] || '?'
136
+ Pakyow::Response::STATUS_CODE_NAMES[status] || '?'
189
137
  end
190
138
  end
191
139
  end
@@ -1,3 +1,5 @@
1
+ require 'json'
2
+
1
3
  module Pakyow
2
4
 
3
5
  # The Request object.
@@ -56,7 +58,9 @@ module Pakyow
56
58
 
57
59
  # Returns indifferent params (see {HashUtils.strhash} for more info on indifferent hashes).
58
60
  def params
59
- @params ||= Hash.strhash(super)
61
+ @params ||= Hash.strhash(super.merge!(env['pakyow.data'] || {}).merge!(JSON.parse(body.read.to_s)))
62
+ rescue JSON::JSONError
63
+ @params = Hash.strhash(super)
60
64
  end
61
65
 
62
66
  # Returns array of url components.
@@ -4,15 +4,130 @@ module Pakyow
4
4
  class Response < Rack::Response
5
5
  attr_reader :format
6
6
 
7
+ STATUS_CODE_NAMES = {
8
+ 100 => 'Continue',
9
+ 101 => 'Switching Protocols',
10
+
11
+ 200 => 'OK',
12
+ 201 => 'Created',
13
+ 202 => 'Accepted',
14
+ 203 => 'Non-Authoritative Information',
15
+ 204 => 'No Content',
16
+ 205 => 'Reset Content',
17
+ 206 => 'Partial Content',
18
+
19
+ 300 => 'Multiple Choices',
20
+ 301 => 'Moved Permanently',
21
+ 302 => 'Found',
22
+ 303 => 'See Other',
23
+ 304 => 'Not Modified',
24
+ 305 => 'Use Proxy',
25
+ 306 => 'Switch Proxy',
26
+ 307 => 'Temporary Redirect',
27
+
28
+ 400 => 'Bad Request',
29
+ 401 => 'Unauthorized',
30
+ 402 => 'Payment Required',
31
+ 403 => 'Forbidden',
32
+ 404 => 'Not Found',
33
+ 405 => 'Method Not Allowed',
34
+ 406 => 'Not Acceptable',
35
+ 407 => 'Proxy Authentication Required',
36
+ 408 => 'Request Timeout',
37
+ 409 => 'Conflict',
38
+ 410 => 'Gone',
39
+ 411 => 'Length Required',
40
+ 412 => 'Precondition Failed',
41
+ 413 => 'Request Entity Too Large',
42
+ 414 => 'Request-URI Too Long',
43
+ 415 => 'Unsupported Media Type',
44
+ 416 => 'Requested Range Not Satisfiable',
45
+ 417 => 'Expectation Failed',
46
+ 418 => 'I\'m a teapot',
47
+
48
+ 500 => 'Internal Server Error',
49
+ 501 => 'Not Implemented',
50
+ 502 => 'Bad Gateway',
51
+ 503 => 'Service Unavailable',
52
+ 504 => 'Gateway Timeout',
53
+ 505 => 'HTTP Version Not Supported',
54
+ 506 => 'Variant Also Negotiates',
55
+ 507 => 'Insufficient Storage',
56
+ 508 => 'Loop Detected',
57
+ 509 => 'Bandwidth Limit Exceeded',
58
+ 510 => 'Not Extended',
59
+ 511 => 'Network Authentication Required'
60
+ }
61
+
62
+ STATUS_CODE_LOOKUP = {
63
+ continue: 100,
64
+ switching_protocols: 101,
65
+
66
+ ok: 200,
67
+ created: 201,
68
+ accepted: 202,
69
+ non_authoritative_information: 203,
70
+ no_content: 204,
71
+ reset_content: 205,
72
+ partial_content: 206,
73
+
74
+ multiple_choices: 300,
75
+ moved_permanently: 301,
76
+ found: 302,
77
+ see_other: 303,
78
+ not_modified: 304,
79
+ use_proxy: 305,
80
+ reserved: 306,
81
+ temporary_redirect: 307,
82
+
83
+ bad_request: 400,
84
+ unauthorized: 401,
85
+ payment_required: 402,
86
+ forbidden: 403,
87
+ not_found: 404,
88
+ method_not_allowed: 405,
89
+ not_acceptable: 406,
90
+ proxy_authentication_required: 407,
91
+ request_timeout: 408,
92
+ conflict: 409,
93
+ gone: 410,
94
+ length_required: 411,
95
+ precondition_failed: 412,
96
+ request_entity_too_large: 413,
97
+ request_uri_too_long: 414,
98
+ unsupported_media_type: 415,
99
+ requested_range_not_satisfiable: 416,
100
+ expectation_failed: 417,
101
+ teapot: 418,
102
+
103
+ internal_server_error: 500,
104
+ not_implemented: 501,
105
+ bad_gateway: 502,
106
+ service_unavailable: 503,
107
+ gateway_timeout: 504,
108
+ http_version_not_supported: 505,
109
+ variant_also_negotiates: 506,
110
+ insufficient_storage: 507,
111
+ loop_detected: 508,
112
+ bandwidth_exceeded: 509,
113
+ not_extended: 510,
114
+ network_authentication_required: 511
115
+ }
116
+
7
117
  def initialize(*args)
8
118
  super
9
119
 
10
120
  self["Content-Type"] ||= 'text/html'
121
+ @format = Rack::Mime::MIME_TYPES.key(type)
11
122
  end
12
123
 
13
124
  def format=(format)
14
125
  @format = format
15
126
  self["Content-Type"] = Rack::Mime.mime_type(".#{format}")
16
127
  end
128
+
129
+ def type
130
+ self["Content-Type"]
131
+ end
17
132
  end
18
133
  end