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.message;
29  
30  import java.io.Serializable;
31  
32  import org.apache.hc.core5.annotation.Contract;
33  import org.apache.hc.core5.annotation.ThreadingBehavior;
34  import org.apache.hc.core5.http.HttpResponse;
35  import org.apache.hc.core5.http.HttpVersion;
36  import org.apache.hc.core5.http.ProtocolVersion;
37  import org.apache.hc.core5.util.Args;
38  
39  /**
40   * HTTP/1.1 status line.
41   *
42   * @since 4.0
43   */
44  @Contract(threading = ThreadingBehavior.IMMUTABLE)
45  public final class StatusLine implements Serializable {
46  
47      private static final long serialVersionUID = -2443303766890459269L;
48  
49      /**
50       * The protocol version.
51       */
52      private final ProtocolVersion protoVersion;
53  
54      /**
55       * The status code.
56       */
57      private final int statusCode;
58  
59      /**
60       * The status code class.
61       */
62      private final StatusClass statusClass;
63  
64      /**
65       * The reason phrase.
66       */
67      private final String reasonPhrase;
68  
69      public StatusLine(final HttpResponse response) {
70          super();
71          Args.notNull(response, "Response");
72          this.protoVersion = response.getVersion() != null ? response.getVersion() : HttpVersion.HTTP_1_1;
73          this.statusCode = response.getCode();
74          this.statusClass = StatusClass.from(this.statusCode);
75          this.reasonPhrase = response.getReasonPhrase();
76      }
77  
78      /**
79       * Creates a new status line with the given version, status, and reason.
80       *
81       * @param version      the protocol version of the response
82       * @param statusCode   the status code of the response
83       * @param reasonPhrase the reason phrase to the status code, or
84       *                     {@code null}
85       */
86      public StatusLine(final ProtocolVersion version, final int statusCode, final String reasonPhrase) {
87          super();
88          this.statusCode = Args.notNegative(statusCode, "Status code");
89          this.statusClass = StatusClass.from(this.statusCode);
90          this.protoVersion = version != null ? version : HttpVersion.HTTP_1_1;
91          this.reasonPhrase = reasonPhrase;
92      }
93  
94      public int getStatusCode() {
95          return this.statusCode;
96      }
97  
98      public StatusClass getStatusClass() {
99          return this.statusClass;
100     }
101 
102     /**
103      * Whether this status code is in the HTTP series {@link StatusClass#INFORMATIONAL}.
104      *
105      * @since 5.1
106      */
107     public boolean isInformational() {
108         return getStatusClass() == StatusClass.INFORMATIONAL;
109     }
110 
111     /**
112      * Whether this status code is in the HTTP series {@link StatusClass#SUCCESSFUL}.
113      *
114      * @since 5.1
115      */
116     public boolean isSuccessful() {
117         return getStatusClass() == StatusClass.SUCCESSFUL;
118     }
119 
120     /**
121      * Whether this status code is in the HTTP series {@link StatusClass#REDIRECTION}.
122      *
123      * @since 5.1
124      */
125     public boolean isRedirection() {
126         return getStatusClass() == StatusClass.REDIRECTION;
127     }
128 
129     /**
130      * Whether this status code is in the HTTP series {@link StatusClass#CLIENT_ERROR}.
131      *
132      * @since 5.1
133      */
134     public boolean isClientError() {
135         return getStatusClass() == StatusClass.CLIENT_ERROR;
136     }
137 
138     /**
139      * Whether this status code is in the HTTP series {@link StatusClass#SERVER_ERROR}.
140      *
141      * @since 5.1
142      */
143     public boolean isServerError() {
144         return getStatusClass() == StatusClass.SERVER_ERROR;
145     }
146 
147     /**
148      * Whether this status code is in the HTTP series {@link StatusClass#CLIENT_ERROR}
149      * or {@link StatusClass#SERVER_ERROR}.
150      *
151      * @since 5.1
152      */
153     public boolean isError() {
154         return isClientError() || isServerError();
155     }
156 
157     public ProtocolVersion getProtocolVersion() {
158         return this.protoVersion;
159     }
160 
161     public String getReasonPhrase() {
162         return this.reasonPhrase;
163     }
164 
165     @Override
166     public String toString() {
167         final StringBuilder buf = new StringBuilder();
168         buf.append(this.protoVersion).append(" ").append(this.statusCode).append(" ");
169         if (this.reasonPhrase != null) {
170             buf.append(this.reasonPhrase);
171         }
172         return buf.toString();
173     }
174 
175     /**
176      * Standard classes of HTTP status codes, plus {@code OTHER} for non-standard codes.
177      * @see org.apache.hc.core5.http.HttpStatus
178      */
179     public enum StatusClass {
180 
181         /**
182          * Informational {@code 1xx} HTTP status codes.
183          */
184         INFORMATIONAL,
185 
186         /**
187          * Successful {@code 2xx} HTTP status codes.
188          */
189         SUCCESSFUL,
190 
191         /**
192          * Redirection {@code 3xx} HTTP status codes.
193          */
194         REDIRECTION,
195 
196         /**
197          * Client Error {@code 4xx} HTTP status codes.
198          */
199         CLIENT_ERROR,
200 
201         /**
202          * {@code 5xx} HTTP status codes.
203          */
204         SERVER_ERROR,
205 
206         /**
207          * Any other HTTP status codes (e.g. non-standard status codes).
208          */
209         OTHER;
210 
211         /**
212          * Gets the response status class for the given status code.
213          *
214          * @param statusCode response status code to get the class for.
215          * @return class of the response status code.
216          * @see org.apache.hc.core5.http.HttpStatus
217          */
218         public static StatusClass from(final int statusCode) {
219             final StatusClass statusClass;
220 
221             switch (statusCode / 100) {
222                 case 1:
223                     statusClass = INFORMATIONAL;
224                     break;
225                 case 2:
226                     statusClass = SUCCESSFUL;
227                     break;
228                 case 3:
229                     statusClass = REDIRECTION;
230                     break;
231                 case 4:
232                     statusClass = CLIENT_ERROR;
233                     break;
234                 case 5:
235                     statusClass = SERVER_ERROR;
236                     break;
237                 default:
238                     statusClass = OTHER;
239                     break;
240             }
241 
242             return statusClass;
243         }
244     }
245 }