001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *
019: */
020: package org.safehaus.asyncweb.service.context;
021:
022: import java.net.InetSocketAddress;
023:
024: import org.safehaus.asyncweb.common.DefaultHttpResponse;
025: import org.safehaus.asyncweb.common.HttpRequest;
026: import org.safehaus.asyncweb.common.HttpResponse;
027: import org.safehaus.asyncweb.common.HttpResponseStatus;
028: import org.safehaus.asyncweb.common.MutableHttpResponse;
029: import org.safehaus.asyncweb.service.HttpServiceContext;
030: import org.safehaus.asyncweb.service.HttpSession;
031: import org.safehaus.asyncweb.service.ServiceContainer;
032: import org.safehaus.asyncweb.util.HttpHeaderConstants;
033: import org.slf4j.Logger;
034: import org.slf4j.LoggerFactory;
035:
036: /**
037: * A default implementation of {@link HttpServiceContext}.
038: *
039: * @author trustin
040: * @version $Rev:167 $, $Date:2006-11-15 11:10:05 +0000 (수, 15 11월 2006) $
041: */
042: public abstract class AbstractHttpServiceContext implements
043: HttpServiceContext {
044:
045: private final Logger log = LoggerFactory
046: .getLogger(AbstractHttpServiceContext.class);
047: private final InetSocketAddress remoteAddress;
048: private final HttpRequest request;
049: private HttpResponse committedResponse;
050: private HttpSession session;
051: private boolean createdSession;
052: private final ServiceContainer container;
053:
054: public AbstractHttpServiceContext(InetSocketAddress remoteAddress,
055: HttpRequest request, ServiceContainer container) {
056: if (remoteAddress == null) {
057: throw new NullPointerException("remoteAddress");
058: }
059: if (request == null) {
060: throw new NullPointerException("request");
061: }
062: if (container == null) {
063: throw new NullPointerException("container");
064: }
065:
066: this .remoteAddress = remoteAddress;
067: this .request = request;
068: this .container = container;
069: this .session = container.getSessionAccessor().getSession(this ,
070: false);
071: }
072:
073: public synchronized boolean isResponseCommitted() {
074: return committedResponse != null;
075: }
076:
077: /**
078: * Commits a <code>HttpResponse</code> to this <code>Request</code>.
079: *
080: * @param response The response to commit
081: * @return <code>true</code> iff the response was committed
082: */
083: public boolean commitResponse(HttpResponse response) {
084: synchronized (this ) {
085: if (isResponseCommitted()) {
086: if (log.isDebugEnabled()) {
087: log
088: .info("Request already comitted to a response. Disposing response");
089: }
090: return false;
091: }
092:
093: committedResponse = response;
094: }
095:
096: // Add the session identifier if the session was newly created.
097: if (createdSession) {
098: container.getSessionAccessor().addSessionIdentifier(this ,
099: (MutableHttpResponse) response);
100: }
101:
102: // Only parsed requests can be formatted.
103: if (getRequest().getMethod() != null) {
104: container.getErrorResponseFormatter().formatResponse(
105: getRequest(), (MutableHttpResponse) response);
106: }
107:
108: if (container.isSendServerHeader()) {
109: ((MutableHttpResponse) response).setHeader(
110: HttpHeaderConstants.KEY_SERVER, "AsyncWeb");
111: }
112:
113: // Normalize the response.
114: ((MutableHttpResponse) response).normalize(getRequest());
115:
116: // Override connection header if needed.
117: if (!container.getKeepAliveStrategy().keepAlive(this , response)) {
118: ((MutableHttpResponse) response).setHeader(
119: HttpHeaderConstants.KEY_CONNECTION,
120: HttpHeaderConstants.VALUE_CLOSE);
121: }
122:
123: boolean requiresClosure = !HttpHeaderConstants.VALUE_KEEP_ALIVE
124: .equalsIgnoreCase(response
125: .getHeader(HttpHeaderConstants.KEY_CONNECTION));
126:
127: if (requiresClosure && log.isDebugEnabled()) {
128: log.debug("Response status: " + response.getStatus());
129: log.debug("Keep-alive strategy requires closure of "
130: + getRemoteAddress());
131: }
132:
133: if (log.isDebugEnabled()) {
134: log.debug("Committing a response:");
135: log.debug("Status: " + response.getStatus() + ' '
136: + response.getStatusReasonPhrase());
137: log.debug("Headers: " + response.getHeaders());
138: }
139:
140: doWrite(requiresClosure);
141:
142: return true;
143: }
144:
145: public boolean commitResponse(HttpResponseStatus status) {
146: MutableHttpResponse response = new DefaultHttpResponse();
147: response.setStatus(status);
148: return commitResponse(response);
149: }
150:
151: public synchronized HttpResponse getCommittedResponse() {
152: return committedResponse;
153: }
154:
155: public InetSocketAddress getRemoteAddress() {
156: return remoteAddress;
157: }
158:
159: public HttpRequest getRequest() {
160: return request;
161: }
162:
163: public HttpSession getSession() {
164: return getSession(true);
165: }
166:
167: public synchronized HttpSession getSession(boolean create) {
168: if (session != null && !session.isValid()) {
169: session = null;
170: }
171: if (session == null) {
172: session = container.getSessionAccessor().getSession(this ,
173: create);
174: if (create) {
175: createdSession = true;
176: }
177: }
178:
179: return session;
180: }
181:
182: protected abstract void doWrite(boolean requiresClosure);
183: }
|