001: /* ====================================================================
002: The Jicarilla Software License
003:
004: Copyright (c) 2003 Leo Simons.
005: All rights reserved.
006:
007: Permission is hereby granted, free of charge, to any person obtaining
008: a copy of this software and associated documentation files (the
009: "Software"), to deal in the Software without restriction, including
010: without limitation the rights to use, copy, modify, merge, publish,
011: distribute, sublicense, and/or sell copies of the Software, and to
012: permit persons to whom the Software is furnished to do so, subject to
013: the following conditions:
014:
015: The above copyright notice and this permission notice shall be
016: included in all copies or substantial portions of the Software.
017:
018: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
019: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
020: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
021: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
022: CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
023: TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
024: SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
025: ==================================================================== */
026: package org.jicarilla.webserver.plumbing;
027:
028: import EDU.oswego.cs.dl.util.concurrent.Channel;
029: import org.jicarilla.http.HTTPEncoding;
030: import org.jicarilla.http.HTTPField;
031: import org.jicarilla.http.HTTPMessage;
032: import org.jicarilla.http.util.NioUtil;
033: import org.jicarilla.plumbing.Sink;
034:
035: import java.nio.ByteBuffer;
036: import java.util.Iterator;
037:
038: /**
039: *
040: *
041: * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
042: * @version $Id: ResponseCompletionStage.java,v 1.1 2004/03/31 12:11:00 lsimons Exp $
043: */
044: public class ResponseCompletionStage extends AbstractStage {
045: public ResponseCompletionStage(final Channel channel,
046: final Sink errorHandler) {
047: super (channel, errorHandler);
048: }
049:
050: protected void process(final HTTPEvent e) {
051: ensureStartLine(e);
052: ensureContentLengthHeader(e);
053: }
054:
055: protected void ensureStartLine(final HTTPEvent e) {
056: final HTTPMessage res = e.getHTTPResponse();
057:
058: if (res.getField1() == null)
059: res.setField1(HTTPEncoding.VERSION_10);
060: if (res.getField2() == null)
061: res.setStatusCode(HTTPEncoding.STATUS_200_OK);
062: if (res.getField3() == null)
063: res.setField3(HTTPEncoding.STATUS_MSG[res.getStatusCode()]);
064: }
065:
066: protected void ensureContentLengthHeader(final HTTPEvent e) {
067: final HTTPMessage req = e.getHTTPRequest();
068: final HTTPMessage res = e.getHTTPResponse();
069:
070: if (contentLengthNotSet(res)) {
071: if (noBodySoNoContentLengthHeader(req, res))
072: return;
073:
074: if (nonIdentifyTransferCodingPresent(req, res))
075: return;
076:
077: final ByteBuffer[] body = res.getBodyParts();
078: if (body.length == 0) {
079: res.addHeader(
080: HTTPEncoding.HEADER_CONTENT_LENGTH_BUFFER,
081: NioUtil.toByteBuffer(0));
082: } else {
083: int size = 0;
084: for (int i = 0; i < body.length; i++) {
085: final ByteBuffer byteBuffer = body[i];
086: size += byteBuffer.remaining();
087: }
088:
089: res.addHeader(
090: HTTPEncoding.HEADER_CONTENT_LENGTH_BUFFER,
091: NioUtil.toByteBuffer(size));
092: }
093: }
094: }
095:
096: private boolean noBodySoNoContentLengthHeader(
097: final HTTPMessage req, final HTTPMessage res) {
098: if (HTTPEncoding.METHOD_HEAD.equals(req.getField1String()))
099: return true;
100:
101: final int responseCode = res.getStatusCode();
102: if ((HTTPEncoding.STATUS_100_Continue <= responseCode && responseCode < HTTPEncoding.STATUS_200_OK)
103: || responseCode == HTTPEncoding.STATUS_204_No_Content
104: || responseCode == HTTPEncoding.STATUS_304_Not_Modified)
105: return true;
106:
107: return false;
108: }
109:
110: protected boolean nonIdentifyTransferCodingPresent(
111: final HTTPMessage req, final HTTPMessage res) {
112: final Iterator it = res.getHeaders().iterator();
113: while (it.hasNext()) {
114: final HTTPField field = (HTTPField) it.next();
115: if (HTTPEncoding.HEADER_TRANSFER_ENCODING.equals(field
116: .getNameString())) {
117: return !HTTPEncoding.CONTENT_CODING_IDENTITY
118: .equals(field.getNameString());
119: }
120: }
121: return false;
122: }
123:
124: protected boolean contentLengthNotSet(final HTTPMessage response) {
125: final Iterator it = response.getHeaders().iterator();
126: while (it.hasNext()) {
127: final HTTPField field = (HTTPField) it.next();
128: if (field.getName().equals(
129: HTTPEncoding.HEADER_CONTENT_LENGTH_BUFFER)) {
130: return false;
131: }
132: }
133: return true;
134: }
135: }
|