001: /*
002: * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: */
007: package javax.servlet.http;
008:
009: import java.io.IOException;
010: import java.io.OutputStreamWriter;
011: import java.io.PrintWriter;
012: import java.io.Serializable;
013: import java.io.UnsupportedEncodingException;
014:
015: import javax.servlet.ServletException;
016: import javax.servlet.ServletOutputStream;
017: import javax.servlet.ServletRequest;
018: import javax.servlet.ServletResponse;
019:
020: /**
021: * Base class for http servlets
022: *
023: * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
024: */
025: public abstract class HttpServlet extends javax.servlet.GenericServlet
026: implements Serializable {
027: static final String METHOD_DELETE = "DELETE";
028: static final String METHOD_HEAD = "HEAD";
029: static final String METHOD_GET = "GET";
030: static final String METHOD_OPTIONS = "OPTIONS";
031: static final String METHOD_POST = "POST";
032: static final String METHOD_PUT = "PUT";
033: static final String METHOD_TRACE = "TRACE";
034: static final String HEADER_IFMODSINCE = "If-Modified-Since";
035: static final String HEADER_LASTMOD = "Last-Modified";
036:
037: public HttpServlet() {
038: super ();
039: }
040:
041: public void service(ServletRequest request, ServletResponse response)
042: throws ServletException, IOException {
043: if ((request instanceof HttpServletRequest)
044: && (response instanceof HttpServletResponse))
045: service((HttpServletRequest) request,
046: (HttpServletResponse) response);
047: else
048: throw new IllegalArgumentException(
049: "Not an Http servlet request - invalid types");
050: }
051:
052: private void notAcceptedMethod(HttpServletRequest request,
053: HttpServletResponse response, String method)
054: throws ServletException, IOException {
055: if (request.getProtocol().endsWith("1.1"))
056: response.sendError(
057: HttpServletResponse.SC_METHOD_NOT_ALLOWED, method
058: + " not allowed");
059: else
060: response.sendError(HttpServletResponse.SC_BAD_REQUEST,
061: method + " not allowed");
062: }
063:
064: protected void doGet(HttpServletRequest req,
065: HttpServletResponse resp) throws ServletException,
066: IOException {
067: notAcceptedMethod(req, resp, "GET");
068: }
069:
070: protected long getLastModified(HttpServletRequest req) {
071: return -1;
072: }
073:
074: protected void doPost(HttpServletRequest req,
075: HttpServletResponse resp) throws ServletException,
076: IOException {
077: notAcceptedMethod(req, resp, "POST");
078: }
079:
080: protected void doPut(HttpServletRequest req,
081: HttpServletResponse resp) throws ServletException,
082: IOException {
083: notAcceptedMethod(req, resp, "PUT");
084: }
085:
086: protected void doDelete(HttpServletRequest req,
087: HttpServletResponse resp) throws ServletException,
088: IOException {
089: notAcceptedMethod(req, resp, "DELETE");
090: }
091:
092: protected void doOptions(HttpServletRequest req,
093: HttpServletResponse resp) throws ServletException,
094: IOException {
095: notAcceptedMethod(req, resp, "OPTIONS");
096: }
097:
098: protected void doTrace(HttpServletRequest req,
099: HttpServletResponse resp) throws ServletException,
100: IOException {
101: notAcceptedMethod(req, resp, "TRACE");
102: }
103:
104: protected void service(HttpServletRequest request,
105: HttpServletResponse response) throws ServletException,
106: IOException {
107: String method = request.getMethod();
108:
109: if (method.equals(METHOD_GET)) {
110: long lastModified = getLastModified(request);
111: if (lastModified == -1)
112: doGet(request, response);
113: else {
114: long ifModifiedSince = request
115: .getDateHeader(HEADER_IFMODSINCE);
116: if (ifModifiedSince < (lastModified / 1000 * 1000)) {
117: if (!response.containsHeader(HEADER_LASTMOD)
118: && (lastModified >= 0))
119: response.setDateHeader(HEADER_LASTMOD,
120: lastModified);
121: doGet(request, response);
122: } else
123: response
124: .setStatus(HttpServletResponse.SC_NOT_MODIFIED);
125: }
126: } else if (method.equals(METHOD_HEAD)) {
127: long lastModified = getLastModified(request);
128: if (!response.containsHeader(HEADER_LASTMOD)
129: && (lastModified >= 0))
130: response.setDateHeader(HEADER_LASTMOD, lastModified);
131: doHead(request, response);
132: } else if (method.equals(METHOD_POST))
133: doPost(request, response);
134: else if (method.equals(METHOD_PUT))
135: doPut(request, response);
136: else if (method.equals(METHOD_DELETE))
137: doDelete(request, response);
138: else if (method.equals(METHOD_OPTIONS))
139: doOptions(request, response);
140: else if (method.equals(METHOD_TRACE))
141: doTrace(request, response);
142: else
143: notAcceptedMethod(request, response, method);
144: }
145:
146: protected void doHead(HttpServletRequest req,
147: HttpServletResponse resp) throws ServletException,
148: IOException {
149: NoBodyResponse response = new NoBodyResponse(resp);
150: doGet(req, response);
151: response.setContentLength();
152: }
153:
154: class NoBodyResponse extends HttpServletResponseWrapper {
155: private NoBodyOutputStream noBody;
156:
157: private PrintWriter writer;
158:
159: private boolean contentLengthSet;
160:
161: NoBodyResponse(HttpServletResponse mainResponse) {
162: super (mainResponse);
163: this .noBody = new NoBodyOutputStream();
164: }
165:
166: void setContentLength() {
167: if (!contentLengthSet)
168: setContentLength(this .noBody.getContentLength());
169: }
170:
171: public void setContentLength(int length) {
172: super .setContentLength(length);
173: this .contentLengthSet = true;
174: }
175:
176: public void setContentType(String type) {
177: getResponse().setContentType(type);
178: }
179:
180: public ServletOutputStream getOutputStream() throws IOException {
181: return noBody;
182: }
183:
184: public String getCharacterEncoding() {
185: return getResponse().getCharacterEncoding();
186: }
187:
188: public PrintWriter getWriter()
189: throws UnsupportedEncodingException {
190: if (writer == null)
191: writer = new PrintWriter(new OutputStreamWriter(noBody,
192: getCharacterEncoding()));
193: return writer;
194: }
195: }
196:
197: class NoBodyOutputStream extends ServletOutputStream {
198: private int contentLength = 0;
199:
200: NoBodyOutputStream() {
201: }
202:
203: int getContentLength() {
204: return contentLength;
205: }
206:
207: public void write(int b) throws IOException {
208: contentLength++;
209: }
210:
211: public void write(byte buf[], int offset, int len)
212: throws IOException {
213: contentLength += len;
214: }
215: }
216: }
|