summaryrefslogtreecommitdiffstats
path: root/simple/simple-http/src/main/java/org/simpleframework/http/core/ResponseMessage.java
blob: 4dcfb089855b9f24143f1972742acf4ba582894b (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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/*
 * ResponseMessage.java February 2001
 *
 * Copyright (C) 2001, Niall Gallagher <niallg@users.sf.net>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
 * implied. See the License for the specific language governing 
 * permissions and limitations under the License.
 */

package org.simpleframework.http.core;

import static org.simpleframework.http.Protocol.CONTENT_LENGTH;
import static org.simpleframework.http.Protocol.CONTENT_TYPE;
import static org.simpleframework.http.Protocol.SET_COOKIE;
import static org.simpleframework.http.Protocol.TRANSFER_ENCODING;

import org.simpleframework.http.ContentType;
import org.simpleframework.http.Cookie;
import org.simpleframework.http.ResponseHeader;
import org.simpleframework.http.Status;
import org.simpleframework.http.message.MessageHeader;
import org.simpleframework.http.parse.ContentTypeParser;

/**
 * The <code>ResponseMessage</code> object represents the header used
 * for a response. This is used to get and set the headers in a case
 * insensitive manner. It is also used to manage the cookies that are
 * send and received. Also, the status code and description can also
 * be set through this object as well as the protocol version. 
 * 
 * @author Niall Gallagher
 */
class ResponseMessage extends MessageHeader implements ResponseHeader {
   
   /**
    * This is the text description used for the response status.
    */
   private String text;
   
   /**
    * This is the major protocol version used for the response.
    */
   private int major;
   
   /**
    * This is the minor protocol version used for the response.
    */
   private int minor;
   
   /**
    * This is the status code used to identify the response type.
    */
   private int code; 
   
   /**
    * Constructor for the <code>ResponseMessage</code> object. This
    * is used to create a response message with a default status code
    * of 200 and a a protocol version of HTTP/1.1. If the response is
    * a different status code or version these can be modified. 
    */
   public ResponseMessage() {
      this.text = "OK";
      this.code = 200;
      this.major = 1;
      this.minor = 1;
   }
   
   /**
    * This represents the status code of the HTTP response. 
    * The response code represents the type of message that is
    * being sent to the client. For a description of the codes
    * see RFC 2616 section 10, Status Code Definitions. 
    *
    * @return the status code that this HTTP response has
    */ 
   public int getCode() {
      return code;
   }
     
   /**
    * This method allows the status for the response to be 
    * changed. This MUST be reflected the the response content
    * given to the client. For a description of the codes see
    * RFC 2616 section 10, Status Code Definitions.
    *
    * @param code the new status code for the HTTP response
    */ 
   public void setCode(int code) {
      this.code = code;
   }

   /**
    * This can be used to retrieve the text of a HTTP status
    * line. This is the text description for the status code.
    * This should match the status code specified by the RFC.
    *
    * @return the message description of the response
    */ 
   public String getDescription() {
      return text;
   }

   /**
    * This is used to set the text of the HTTP status line.
    * This should match the status code specified by the RFC.
    *
    * @param text the descriptive text message of the status
    */ 
   public void setDescription(String text) {
      this.text = text;
   }
   
   /**
    * This is used to acquire the status from the response. 
    * The <code>Status</code> object returns represents the
    * code that has been set on the response, it does not
    * necessarily represent the description in the response.
    * 
    * @return this is the response for this status line
    */
   public Status getStatus() {
      return Status.getStatus(code);
   }
   
   /**
    * This is used to set the status code and description
    * for this response. Setting the code and description in
    * this manner provides a much more convenient way to set
    * the response status line details.
    * 
    * @param status this is the status to set on the response
    */
   public void setStatus(Status status) {
      setCode(status.code);
      setDescription(status.description);
   }

   /**
    * This can be used to get the major number from a HTTP version.
    * The major version corresponds to the major type that is the 1
    * of a HTTP/1.0 version string. 
    *
    * @return the major version number for the request message
    */ 
   public int getMajor() {
      return major;
   }

   /**
    * This can be used to set the major number from a HTTP version.
    * The major version corresponds to the major type that is the 1
    * of a HTTP/1.0 version string. 
    *
    * @param major the major version number for the request message
    */ 
   public void setMajor(int major) {
      this.major = major;
   }

   /**
    * This can be used to get the minor number from a HTTP version.
    * The minor version corresponds to the major type that is the 0
    * of a HTTP/1.0 version string. This is used to determine if 
    * the request message has keep alive semantics.
    *
    * @return the minor version number for the request message
    */ 
   public int getMinor() {
      return minor;
   }
   
   /**
    * This can be used to get the minor number from a HTTP version.
    * The minor version corresponds to the major type that is the 0
    * of a HTTP/1.0 version string. This is used to determine if 
    * the request message has keep alive semantics.
    *
    * @param minor the minor version number for the request message
    */ 
   public void setMinor(int minor) {
      this.minor = minor;
   }
   
   /**
    * This is a convenience method that can be used to determine the 
    * content type of the message body. This will determine whether
    * there is a <code>Content-Type</code> header, if there is then
    * this will parse that header and represent it as a typed object
    * which will expose the various parts of the HTTP header.
    *
    * @return this returns the content type value if it exists
    */    
   public ContentType getContentType() {
      String value = getValue(CONTENT_TYPE);
      
      if(value == null) {
         return null; 
      }
      return new ContentTypeParser(value);
   }
   
   /**
    * This is a convenience method that can be used to determine
    * the length of the message body. This will determine if there
    * is a <code>Content-Length</code> header, if it does then the
    * length can be determined, if not then this returns -1.
    *
    * @return content length, or -1 if it cannot be determined
    */
   public long getContentLength() {
      return getLong(CONTENT_LENGTH);
   }
   
   /**
    * This is a convenience method that can be used to determine the 
    * content type of the message body. This will determine whether
    * there is a <code>Transfer-Encoding</code> header, if there is 
    * then this will parse that header and return the first token in
    * the comma separated list of values, which is the primary value.
    *
    * @return this returns the transfer encoding value if it exists
    */    
   public String getTransferEncoding() {
      return getValue(TRANSFER_ENCODING);
   }

   /**
    * This is used to compose the HTTP response header. All of the
    * headers added to the response are added, as well as the cookies
    * to form the response message header. To ensure that the text
    * produces is as required the header names are in the same case
    * as they were added to the response message.
    * 
    * @return a string representation of the response message
    */
   public CharSequence getHeader() {
      return toString();
   }
   
   /**
    * This is used to compose the HTTP response header. All of the
    * headers added to the response are added, as well as the cookies
    * to form the response message header. To ensure that the text
    * produces is as required the header names are in the same case
    * as they were added to the response message.
    * 
    * @return a string representation of the response message
    */
   public String toString() {   
      StringBuilder head = new StringBuilder(256);
      
      head.append("HTTP/").append(major);      
      head.append('.').append(minor);
      head.append(' ').append(code);
      head.append(' ').append(text);
      head.append("\r\n");
      
      for(String name : getNames()) {
         for(String value : getAll(name)) {
            head.append(name);
            head.append(": ");
            head.append(value);
            head.append("\r\n");
         }
      }
      for(Cookie cookie : getCookies()) {         
         head.append(SET_COOKIE);
         head.append(": ");
         head.append(cookie);
         head.append("\r\n");
      }      
      return head.append("\r\n").toString();      
   }
}