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,
87                        final String reasonPhrase) {
88          super();
89          this.statusCode = Args.notNegative(statusCode, "Status code");
90          this.statusClass = StatusClass.from(this.statusCode);
91          this.protoVersion = version != null ? version : HttpVersion.HTTP_1_1;
92          this.reasonPhrase = reasonPhrase;
93      }
94  
95      public int getStatusCode() {
96          return this.statusCode;
97      }
98  
99      public StatusClass getStatusClass() {
100         return this.statusClass;
101     }
102 
103     public ProtocolVersion getProtocolVersion() {
104         return this.protoVersion;
105     }
106 
107     public String getReasonPhrase() {
108         return this.reasonPhrase;
109     }
110 
111     @Override
112     public String toString() {
113         final StringBuilder buf = new StringBuilder();
114         buf.append(this.protoVersion).append(" ").append(this.statusCode).append(" ");
115         if (this.reasonPhrase != null) {
116             buf.append(this.reasonPhrase);
117         }
118         return buf.toString();
119     }
120 
121     /**
122      * Standard classes of HTTP status codes, plus {@code OTHER} for non-standard codes.
123      */
124     public enum StatusClass {
125 
126         /**
127          * Informational {@code 1xx} HTTP status codes.
128          */
129         INFORMATIONAL,
130 
131         /**
132          * Successful {@code 2xx} HTTP status codes.
133          */
134         SUCCESSFUL,
135 
136         /**
137          * Redirection {@code 3xx} HTTP status codes.
138          */
139         REDIRECTION,
140 
141         /**
142          * Client Error {@code 4xx} HTTP status codes.
143          */
144         CLIENT_ERROR,
145 
146         /**
147          * {@code 5xx} HTTP status codes.
148          */
149         SERVER_ERROR,
150 
151         /**
152          * Any other HTTP status codes (e.g. non-standard status codes).
153          */
154         OTHER;
155 
156         /**
157          * Gets the response status class for the given status code.
158          *
159          * @param statusCode response status code to get the class for.
160          * @return class of the response status code.
161          */
162         public static StatusClass from(final int statusCode) {
163             final StatusClass statusClass;
164 
165             switch (statusCode / 100) {
166                 case 1:
167                     statusClass = INFORMATIONAL;
168                     break;
169                 case 2:
170                     statusClass = SUCCESSFUL;
171                     break;
172                 case 3:
173                     statusClass = REDIRECTION;
174                     break;
175                 case 4:
176                     statusClass = CLIENT_ERROR;
177                     break;
178                 case 5:
179                     statusClass = SERVER_ERROR;
180                     break;
181                 default:
182                     statusClass = OTHER;
183                     break;
184             }
185 
186             return statusClass;
187         }
188     }
189 }