summaryrefslogtreecommitdiff
path: root/tool/lib/webrick/httpstatus.rb
blob: c811f21964990c3bfc3bd3f616fe1569226a9b7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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
81
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# frozen_string_literal: false
#--
# httpstatus.rb -- HTTPStatus Class
#
# Author: IPR -- Internet Programming with Ruby -- writers
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
# reserved.
#
# $IPR: httpstatus.rb,v 1.11 2003/03/24 20:18:55 gotoyuzo Exp $

require_relative 'accesslog'

module WEBrick

  ##
  # This module is used to manager HTTP status codes.
  #
  # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for more
  # information.
  module HTTPStatus

    ##
    # Root of the HTTP status class hierarchy
    class Status < StandardError
      class << self
        attr_reader :code, :reason_phrase # :nodoc:
      end

      # Returns the HTTP status code
      def code() self::class::code end

      # Returns the HTTP status description
      def reason_phrase() self::class::reason_phrase end

      alias to_i code # :nodoc:
    end

    # Root of the HTTP info statuses
    class Info        < Status; end
    # Root of the HTTP success statuses
    class Success     < Status; end
    # Root of the HTTP redirect statuses
    class Redirect    < Status; end
    # Root of the HTTP error statuses
    class Error       < Status; end
    # Root of the HTTP client error statuses
    class ClientError < Error; end
    # Root of the HTTP server error statuses
    class ServerError < Error; end

    class EOFError < StandardError; end

    # HTTP status codes and descriptions
    StatusMessage = { # :nodoc:
      100 => 'Continue',
      101 => 'Switching Protocols',
      200 => 'OK',
      201 => 'Created',
      202 => 'Accepted',
      203 => 'Non-Authoritative Information',
      204 => 'No Content',
      205 => 'Reset Content',
      206 => 'Partial Content',
      207 => 'Multi-Status',
      300 => 'Multiple Choices',
      301 => 'Moved Permanently',
      302 => 'Found',
      303 => 'See Other',
      304 => 'Not Modified',
      305 => 'Use Proxy',
      307 => 'Temporary Redirect',
      400 => 'Bad Request',
      401 => 'Unauthorized',
      402 => 'Payment Required',
      403 => 'Forbidden',
      404 => 'Not Found',
      405 => 'Method Not Allowed',
      406 => 'Not Acceptable',
      407 => 'Proxy Authentication Required',
      408 => 'Request Timeout',
      409 => 'Conflict',
      410 => 'Gone',
      411 => 'Length Required',
      412 => 'Precondition Failed',
      413 => 'Request Entity Too Large',
      414 => 'Request-URI Too Large',
      415 => 'Unsupported Media Type',
      416 => 'Request Range Not Satisfiable',
      417 => 'Expectation Failed',
      422 => 'Unprocessable Entity',
      423 => 'Locked',
      424 => 'Failed Dependency',
      426 => 'Upgrade Required',
      428 => 'Precondition Required',
      429 => 'Too Many Requests',
      431 => 'Request Header Fields Too Large',
      451 => 'Unavailable For Legal Reasons',
      500 => 'Internal Server Error',
      501 => 'Not Implemented',
      502 => 'Bad Gateway',
      503 => 'Service Unavailable',
      504 => 'Gateway Timeout',
      505 => 'HTTP Version Not Supported',
      507 => 'Insufficient Storage',
      511 => 'Network Authentication Required',
    }

    # Maps a status code to the corresponding Status class
    CodeToError = {} # :nodoc:

    # Creates a status or error class for each status code and
    # populates the CodeToError map.
    StatusMessage.each{|code, message|
      message.freeze
      var_name = message.gsub(/[ \-]/,'_').upcase
      err_name = message.gsub(/[ \-]/,'')

      case code
      when 100...200; parent = Info
      when 200...300; parent = Success
      when 300...400; parent = Redirect
      when 400...500; parent = ClientError
      when 500...600; parent = ServerError
      end

      const_set("RC_#{var_name}", code)
      err_class = Class.new(parent)
      err_class.instance_variable_set(:@code, code)
      err_class.instance_variable_set(:@reason_phrase, message)
      const_set(err_name, err_class)
      CodeToError[code] = err_class
    }

    ##
    # Returns the description corresponding to the HTTP status +code+
    #
    #   WEBrick::HTTPStatus.reason_phrase 404
    #   => "Not Found"
    def reason_phrase(code)
      StatusMessage[code.to_i]
    end

    ##
    # Is +code+ an informational status?
    def info?(code)
      code.to_i >= 100 and code.to_i < 200
    end

    ##
    # Is +code+ a successful status?
    def success?(code)
      code.to_i >= 200 and code.to_i < 300
    end

    ##
    # Is +code+ a redirection status?
    def redirect?(code)
      code.to_i >= 300 and code.to_i < 400
    end

    ##
    # Is +code+ an error status?
    def error?(code)
      code.to_i >= 400 and code.to_i < 600
    end

    ##
    # Is +code+ a client error status?
    def client_error?(code)
      code.to_i >= 400 and code.to_i < 500
    end

    ##
    # Is +code+ a server error status?
    def server_error?(code)
      code.to_i >= 500 and code.to_i < 600
    end

    ##
    # Returns the status class corresponding to +code+
    #
    #   WEBrick::HTTPStatus[302]
    #   => WEBrick::HTTPStatus::NotFound
    #
    def self.[](code)
      CodeToError[code]
    end

    module_function :reason_phrase
    module_function :info?, :success?, :redirect?, :error?
    module_function :client_error?, :server_error?
  end
end