View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.http.impl;
29  
30  import java.util.Locale;
31  
32  import org.apache.hc.core5.annotation.Contract;
33  import org.apache.hc.core5.annotation.ThreadingBehavior;
34  import org.apache.hc.core5.http.HttpStatus;
35  import org.apache.hc.core5.http.ReasonPhraseCatalog;
36  import org.apache.hc.core5.util.Args;
37  
38  /**
39   * English reason phrases for HTTP status codes.
40   *
41   * @since 4.0
42   */
43  @Contract(threading = ThreadingBehavior.IMMUTABLE)
44  public class EnglishReasonPhraseCatalog implements ReasonPhraseCatalog {
45  
46      // static array with english reason phrases defined below
47  
48      /**
49       * The default instance of this catalog.
50       * This catalog is thread safe, so there typically
51       * is no need to create other instances.
52       */
53      public final static EnglishReasonPhraseCataloghraseCatalog.html#EnglishReasonPhraseCatalog">EnglishReasonPhraseCatalog INSTANCE = new EnglishReasonPhraseCatalog();
54  
55  
56      /**
57       * Restricted default constructor, for derived classes.
58       * If you need an instance of this class, use {@link #INSTANCE INSTANCE}.
59       */
60      protected EnglishReasonPhraseCatalog() {
61          // no body
62      }
63  
64  
65      /**
66       * Obtains the reason phrase for a status code.
67       *
68       * @param status    the status code, in the range 100-599
69       * @param loc       ignored
70       *
71       * @return  the reason phrase, or {@code null}
72       */
73      @Override
74      public String getReason(final int status, final Locale loc) {
75          Args.checkRange(status, 100, 599, "Unknown category for status code");
76          final int category = status / 100;
77          final int subcode  = status - 100*category;
78  
79          String reason = null;
80          if (REASON_PHRASES[category].length > subcode) {
81              reason = REASON_PHRASES[category][subcode];
82          }
83  
84          return reason;
85      }
86  
87  
88      /** Reason phrases lookup table. */
89      private static final String[][] REASON_PHRASES = new String[][]{
90          null,
91          new String[4],  // 1xx
92          new String[27], // 2xx
93          new String[9],  // 3xx
94          new String[52], // 4xx
95          new String[12]   // 5xx
96      };
97  
98  
99  
100     /**
101      * Stores the given reason phrase, by status code.
102      * Helper method to initialize the static lookup table.
103      *
104      * @param status    the status code for which to define the phrase
105      * @param reason    the reason phrase for this status code
106      */
107     private static void setReason(final int status, final String reason) {
108         final int category = status / 100;
109         final int subcode  = status - 100*category;
110         REASON_PHRASES[category][subcode] = reason;
111     }
112 
113 
114     // ----------------------------------------------------- Static Initializer
115 
116     /** Set up status code to "reason phrase" map. */
117     static {
118         // HTTP 1.1 Server status codes -- see RFC 7231
119         setReason(HttpStatus.SC_OK,
120                   "OK");
121         setReason(HttpStatus.SC_CREATED,
122                   "Created");
123         setReason(HttpStatus.SC_ACCEPTED,
124                   "Accepted");
125         setReason(HttpStatus.SC_NO_CONTENT,
126                   "No Content");
127         setReason(HttpStatus.SC_MOVED_PERMANENTLY,
128                   "Moved Permanently");
129         setReason(HttpStatus.SC_MOVED_TEMPORARILY,
130                   "Moved Temporarily");
131         setReason(HttpStatus.SC_NOT_MODIFIED,
132                   "Not Modified");
133         setReason(HttpStatus.SC_BAD_REQUEST,
134                   "Bad Request");
135         setReason(HttpStatus.SC_UNAUTHORIZED,
136                   "Unauthorized");
137         setReason(HttpStatus.SC_FORBIDDEN,
138                   "Forbidden");
139         setReason(HttpStatus.SC_NOT_FOUND,
140                   "Not Found");
141         setReason(HttpStatus.SC_INTERNAL_SERVER_ERROR,
142                   "Internal Server Error");
143         setReason(HttpStatus.SC_NOT_IMPLEMENTED,
144                   "Not Implemented");
145         setReason(HttpStatus.SC_BAD_GATEWAY,
146                   "Bad Gateway");
147         setReason(HttpStatus.SC_SERVICE_UNAVAILABLE,
148                   "Service Unavailable");
149 
150         setReason(HttpStatus.SC_CONTINUE,
151                   "Continue");
152         setReason(HttpStatus.SC_TEMPORARY_REDIRECT,
153                   "Temporary Redirect");
154         setReason(HttpStatus.SC_METHOD_NOT_ALLOWED,
155                   "Method Not Allowed");
156         setReason(HttpStatus.SC_CONFLICT,
157                   "Conflict");
158         setReason(HttpStatus.SC_PRECONDITION_FAILED,
159                   "Precondition Failed");
160         setReason(HttpStatus.SC_REQUEST_TOO_LONG,
161                   "Request Too Long");
162         setReason(HttpStatus.SC_REQUEST_URI_TOO_LONG,
163                   "Request-URI Too Long");
164         setReason(HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE,
165                   "Unsupported Media Type");
166         setReason(HttpStatus.SC_MULTIPLE_CHOICES,
167                   "Multiple Choices");
168         setReason(HttpStatus.SC_SEE_OTHER,
169                   "See Other");
170         setReason(HttpStatus.SC_USE_PROXY,
171                   "Use Proxy");
172         setReason(HttpStatus.SC_PAYMENT_REQUIRED,
173                   "Payment Required");
174         setReason(HttpStatus.SC_NOT_ACCEPTABLE,
175                   "Not Acceptable");
176         setReason(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED,
177                   "Proxy Authentication Required");
178         setReason(HttpStatus.SC_REQUEST_TIMEOUT,
179                   "Request Timeout");
180 
181         setReason(HttpStatus.SC_SWITCHING_PROTOCOLS,
182                   "Switching Protocols");
183         setReason(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION,
184                   "Non Authoritative Information");
185         setReason(HttpStatus.SC_RESET_CONTENT,
186                   "Reset Content");
187         setReason(HttpStatus.SC_PARTIAL_CONTENT,
188                   "Partial Content");
189         setReason(HttpStatus.SC_GATEWAY_TIMEOUT,
190                   "Gateway Timeout");
191         setReason(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED,
192                   "Http Version Not Supported");
193         setReason(HttpStatus.SC_GONE,
194                   "Gone");
195         setReason(HttpStatus.SC_LENGTH_REQUIRED,
196                   "Length Required");
197         setReason(HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE,
198                   "Requested Range Not Satisfiable");
199         setReason(HttpStatus.SC_EXPECTATION_FAILED,
200                   "Expectation Failed");
201         setReason(HttpStatus.SC_MISDIRECTED_REQUEST,
202                 "Misdirected Request");
203 
204         // WebDAV Server-specific status codes
205         setReason(HttpStatus.SC_PROCESSING,
206                   "Processing");
207         setReason(HttpStatus.SC_MULTI_STATUS,
208                   "Multi-Status");
209         setReason(HttpStatus.SC_ALREADY_REPORTED,
210                 "Already Reported");
211         setReason(HttpStatus.SC_IM_USED,
212                 "IM Used");
213         setReason(HttpStatus.SC_UNPROCESSABLE_ENTITY,
214                   "Unprocessable Entity");
215         setReason(HttpStatus.SC_INSUFFICIENT_SPACE_ON_RESOURCE,
216                   "Insufficient Space On Resource");
217         setReason(HttpStatus.SC_METHOD_FAILURE,
218                   "Method Failure");
219         setReason(HttpStatus.SC_LOCKED,
220                   "Locked");
221         setReason(HttpStatus.SC_INSUFFICIENT_STORAGE,
222                   "Insufficient Storage");
223         setReason(HttpStatus.SC_LOOP_DETECTED,
224                 "Loop Detected");
225         setReason(HttpStatus.SC_NOT_EXTENDED,
226                 "Not Extended");
227         setReason(HttpStatus.SC_FAILED_DEPENDENCY,
228                   "Failed Dependency");
229         setReason(HttpStatus.SC_TOO_EARLY,
230                 "Too Early");
231         setReason(HttpStatus.SC_UPGRADE_REQUIRED,
232                 "Upgrade Required");
233 
234         // Additional HTTP Status Code - see RFC 6585
235         setReason(HttpStatus.SC_PRECONDITION_REQUIRED,
236                 "Precondition Required");
237         setReason(HttpStatus.SC_TOO_MANY_REQUESTS,
238                 "Too Many Requests");
239         setReason(HttpStatus.SC_REQUEST_HEADER_FIELDS_TOO_LARGE,
240                 "Request Header Fields Too Large");
241         setReason(HttpStatus.SC_NETWORK_AUTHENTICATION_REQUIRED,
242                 "Network Authentication Required");
243 
244         // Early Hints - see RFC 8297
245         setReason(HttpStatus.SC_EARLY_HINTS,
246                 "Early Hints");
247         //Permanent Redirect - see RFC 7538
248         setReason(HttpStatus.SC_PERMANENT_REDIRECT,
249                 "Permanent Redirect");
250         // Legal Obstacles - see RFC 7725
251         setReason(HttpStatus.SC_UNAVAILABLE_FOR_LEGAL_REASONS,
252                 "Unavailable For Legal Reasons");
253         // Transparent Content Negotiation - see RFC 2295
254         setReason(HttpStatus.SC_VARIANT_ALSO_NEGOTIATES,
255                 "Variant Also Negotiates");
256     }
257 
258 
259 }