You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xmlrpc-dev@ws.apache.org by jo...@apache.org on 2005/10/26 23:13:47 UTC
svn commit: r328736 [2/2] - in
/webservices/xmlrpc/branches/b20050512_streaming: ./ .settings/
src/java/org/apache/xmlrpc/serializer/ src/java/org/apache/xmlrpc/util/
src/java/org/apache/xmlrpc/webserver/
Added: webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/HttpServletResponseImpl.java
URL: http://svn.apache.org/viewcvs/webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/HttpServletResponseImpl.java?rev=328736&view=auto
==============================================================================
--- webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/HttpServletResponseImpl.java (added)
+++ webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/HttpServletResponseImpl.java Wed Oct 26 14:13:21 2005
@@ -0,0 +1,465 @@
+/*
+ * Copyright 1999,2005 The Apache Software Foundation.
+ *
+ * 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.apache.xmlrpc.webserver;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+
+/** Stub implementation of a {@link javax.servlet.http.HttpServletResponse}
+ * with lots of unimplemented methods. I implemented only those, which
+ * are required for testing the {@link org.apache.xmlrpc.webserver.XmlRpcServlet}.
+ * Perhaps someone else is adding more at a later time?
+ */
+public class HttpServletResponseImpl implements HttpServletResponse {
+ static final int BUFFER_SIZE = 8192;
+ private final Socket socket;
+ private final OutputStream ostream;
+ private final Map headers = new HashMap();
+ private int status = HttpServletResponse.SC_OK;
+ private String message = getStatusMessage(status);
+ private Locale locale;
+ private String charEncoding;
+ private PrintWriter writer;
+ private ServletOutputStreamImpl soStream;
+
+ /** Creates a new instance.
+ * @param pSocket The clients socket.
+ * @throws IOException Accessing the sockets output stream failed.
+ */
+ public HttpServletResponseImpl(Socket pSocket) throws IOException {
+ socket = pSocket;
+ ostream = socket.getOutputStream();
+ }
+
+ public void addCookie(Cookie pCookie) { throw new IllegalStateException("Not implemented"); }
+
+ public void addDateHeader(String pHeader, long pDate) { throw new IllegalStateException("Not implemented"); }
+
+ public void addHeader(String pHeader, String pValue) {
+ String key = pHeader.toLowerCase();
+ Object o = headers.get(key);
+ if (o == null) {
+ headers.put(key, pValue);
+ } else {
+ List list;
+ if (o instanceof String) {
+ list = new ArrayList();
+ headers.put(key, list);
+ list.add(o);
+ } else {
+ list = (List) o;
+ }
+ list.add(pValue);
+ }
+ }
+
+ private String getHeader(String pHeader) {
+ String key = pHeader.toLowerCase();
+ Object o = headers.get(key);
+ if (o == null) {
+ return null;
+ } else if (o instanceof String) {
+ return (String) o;
+ } else {
+ List list = (List) o;
+ if (list.size() == 0) {
+ return null;
+ } else {
+ return (String) list.get(0);
+ }
+ }
+ }
+
+ public void addIntHeader(String pHeader, int pValue) {
+ addHeader(pHeader, Integer.toString(pValue));
+ }
+
+ public boolean containsHeader(String pHeader) {
+ return headers.containsKey(pHeader.toLowerCase());
+ }
+
+ public String encodeRedirectURL(String pURL) { throw new IllegalStateException("Not implemented"); }
+
+ public String encodeRedirectUrl(String pURL) { return encodeRedirectURL(pURL); }
+
+ public String encodeURL(String pURL) { throw new IllegalStateException("Not implemented"); }
+
+ public String encodeUrl(String pURL) { return encodeUrl(pURL); }
+
+ public void sendError(int pStatusCode) throws IOException {
+ sendError(pStatusCode, getStatusMessage(pStatusCode));
+ }
+
+ public void sendError(int pStatusCode, String pMessage) throws IOException {
+ sendError(pStatusCode, pMessage, null);
+ }
+
+ protected void sendError(int pStatusCode, String pMessage, String pDescription)
+ throws IOException {
+ if (isCommitted()) {
+ throw new IllegalStateException("Can't send an error message, if the response has already been committed.");
+ }
+ headers.clear();
+ setContentType("text/html");
+ setStatus(pStatusCode, pMessage);
+ if (soStream == null) {
+ soStream = new ServletOutputStreamImpl(ostream, this);
+ } else {
+ soStream.reset();
+ }
+ OutputStreamWriter osw = new OutputStreamWriter(soStream, getCharacterEncoding());
+ osw.write("<html><head><title>" + pStatusCode + " " + pMessage + "</title></head>\r\n");
+ osw.write("<body><h1>" + pStatusCode + " " + pMessage + "</h1>\r\n");
+ if (pDescription != null) {
+ osw.write("<p>" + pDescription + "</p>\r\n");
+ }
+ osw.write("</body></html>\r\n");
+ osw.close();
+ }
+
+ public void sendRedirect(String arg0) throws IOException { throw new IllegalStateException("Not implemented"); }
+
+ public void setDateHeader(String arg0, long arg1) { throw new IllegalStateException("Not implemented"); }
+
+ public void setHeader(String pHeader, String pValue) {
+ headers.remove(pHeader.toLowerCase());
+ addHeader(pHeader, pValue);
+ }
+
+ public void setIntHeader(String pHeader, int pValue) {
+ setHeader(pHeader, Integer.toString(pValue));
+ }
+
+ public void setStatus(int pStatusCode) {
+ setStatus(pStatusCode, getStatusMessage(pStatusCode));
+ }
+
+ public void setStatus(int pStatusCode, String pMessage) {
+ status = pStatusCode;
+ message = pMessage;
+ }
+
+ public void flushBuffer() throws IOException {
+ ostream.flush();
+ }
+
+ public int getBufferSize() { return BUFFER_SIZE; }
+
+ /** <p>Sets the character encoding (MIME charset) of the response being sent
+ * to the client, for example, to UTF-8. If the character encoding has
+ * already been set by setContentType(java.lang.String) or
+ * setLocale(java.util.Locale), this method overrides it.
+ * Calling setContentType(java.lang.String) with the String
+ * of text/html and calling this method with the String of UTF-8
+ * is equivalent with calling setContentType with the String of
+ * text/html; charset=UTF-8.</p>
+ * <p>This method can be called repeatedly to change the character
+ * encoding. This method has no effect if it is called after getWriter
+ * has been called or after the response has been committed.</p>
+ * <p>Containers must communicate the character encoding used for
+ * the servlet response's writer to the client if the protocol
+ * provides a way for doing so. In the case of HTTP, the character
+ * encoding is communicated as part of the Content-Type header for
+ * text media types. Note that the character encoding cannot be
+ * communicated via HTTP headers if the servlet does not specify
+ * a content type; however, it is still used to encode text written
+ * via the servlet response's writer.</p>
+ * @param pCharset A String specifying only the character set defined
+ * by IANA Character Sets (http://www.iana.org/assignments/character-sets)
+ * @since Servlet API 2.4
+ * @see #setLocale(Locale)
+ */
+ public void setCharacterEncoding(String pCharset) {
+ charEncoding = pCharset;
+ }
+
+ public String getCharacterEncoding() {
+ if (charEncoding == null) {
+ return "ISO-8859-1";
+ } else {
+ return charEncoding;
+ }
+ }
+
+ public Locale getLocale() { return locale; }
+
+ public ServletOutputStream getOutputStream() throws IOException {
+ if (writer != null) {
+ throw new IllegalStateException("You may call either getWriter() or getOutputStream(), but not both.");
+ } else {
+ if (soStream == null) {
+ soStream = new ServletOutputStreamImpl(ostream, this);
+ }
+ return soStream;
+ }
+ }
+
+ public PrintWriter getWriter() throws IOException {
+ if (writer != null) {
+ return writer;
+ } else if (soStream != null) {
+ throw new IllegalStateException("You may call either getWriter() or getOutputStream(), but not both.");
+ } else {
+ writer = new PrintWriter(new OutputStreamWriter(getOutputStream(), getCharacterEncoding()));
+ return writer;
+ }
+ }
+
+ public boolean isCommitted() {
+ return soStream != null && soStream.isCommitted();
+ }
+
+ public void reset() {
+ resetBuffer();
+ setStatus(HttpServletResponse.SC_OK);
+ headers.clear();
+ charEncoding = null;
+ locale = null;
+ }
+
+ public void resetBuffer() {
+ if (isCommitted()) {
+ throw new IllegalStateException("The ServletOutputStream is already committed. A reset is no longer possible.");
+ }
+ if (soStream != null) {
+ soStream.reset();
+ }
+ }
+
+ public void setBufferSize(int pBufferSize) { throw new IllegalStateException("Not implemented"); }
+
+ public void setContentLength(int pContentLength) {
+ if (pContentLength == -1) {
+ headers.remove("content-length");
+ } else {
+ setIntHeader("content-length", pContentLength);
+ }
+ }
+
+ /** <p>Returns the content type used for the MIME body sent in this
+ * response. The content type proper must have been specified
+ * using setContentType(java.lang.String) before the response is
+ * committed. If no content type has been specified, this method
+ * returns null. If a content type has been specified and a
+ * character encoding has been explicitly or implicitly specified
+ * as described in getCharacterEncoding(), the charset parameter
+ * is included in the string returned. If no character encoding
+ * has been specified, the charset parameter is omitted.</p>
+ * @return A String specifying the content type, for example,
+ * text/html; charset=UTF-8, or null
+ * @since Servlet API 2.4
+ * @see #setContentType(String)
+ */
+ public String getContentType() {
+ String s = getHeader("content-type");
+ if (s != null && s.toLowerCase().startsWith("text/")) {
+ String enc = getCharacterEncoding();
+ if (enc != null) {
+ s += "; charset=" + enc;
+ }
+ }
+ return s;
+ }
+
+
+ public void setContentType(String pType) {
+ if (pType != null) {
+ boolean charSetFound = false;
+ StringBuffer sb = new StringBuffer();
+ for (StringTokenizer st = new StringTokenizer(pType, ";"); st.hasMoreTokens(); ) {
+ String t = st.nextToken();
+ if (t.toLowerCase().startsWith("charset=")) {
+ charSetFound = true;
+ setCharacterEncoding(t.substring("charset=".length()).trim());
+ } else {
+ if (sb.length() > 0) {
+ sb.append("; ");
+ }
+ sb.append(t);
+ }
+ }
+ if (charSetFound) {
+ pType = sb.toString();
+ }
+ }
+ setHeader("content-type", pType);
+ }
+
+ public void setLocale(Locale pLocale) { locale = pLocale; }
+
+ /** Returns a default message for a given HTTP status code.
+ * @param pStatusCode The status code being queried.
+ * @return The default message.
+ */
+ public static String getStatusMessage(int pStatusCode) {
+ switch (pStatusCode) {
+ case HttpServletResponse.SC_OK:
+ return ("OK");
+ case HttpServletResponse.SC_ACCEPTED:
+ return ("Accepted");
+ case HttpServletResponse.SC_BAD_GATEWAY:
+ return ("Bad Gateway");
+ case HttpServletResponse.SC_BAD_REQUEST:
+ return ("Bad Request");
+ case HttpServletResponse.SC_CONFLICT:
+ return ("Conflict");
+ case HttpServletResponse.SC_CONTINUE:
+ return ("Continue");
+ case HttpServletResponse.SC_CREATED:
+ return ("Created");
+ case HttpServletResponse.SC_EXPECTATION_FAILED:
+ return ("Expectation Failed");
+ case HttpServletResponse.SC_FORBIDDEN:
+ return ("Forbidden");
+ case HttpServletResponse.SC_GATEWAY_TIMEOUT:
+ return ("Gateway Timeout");
+ case HttpServletResponse.SC_GONE:
+ return ("Gone");
+ case HttpServletResponse.SC_HTTP_VERSION_NOT_SUPPORTED:
+ return ("HTTP Version Not Supported");
+ case HttpServletResponse.SC_INTERNAL_SERVER_ERROR:
+ return ("Internal Server Error");
+ case HttpServletResponse.SC_LENGTH_REQUIRED:
+ return ("Length Required");
+ case HttpServletResponse.SC_METHOD_NOT_ALLOWED:
+ return ("Method Not Allowed");
+ case HttpServletResponse.SC_MOVED_PERMANENTLY:
+ return ("Moved Permanently");
+ case HttpServletResponse.SC_MOVED_TEMPORARILY:
+ return ("Moved Temporarily");
+ case HttpServletResponse.SC_MULTIPLE_CHOICES:
+ return ("Multiple Choices");
+ case HttpServletResponse.SC_NO_CONTENT:
+ return ("No Content");
+ case HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION:
+ return ("Non-Authoritative Information");
+ case HttpServletResponse.SC_NOT_ACCEPTABLE:
+ return ("Not Acceptable");
+ case HttpServletResponse.SC_NOT_FOUND:
+ return ("Not Found");
+ case HttpServletResponse.SC_NOT_IMPLEMENTED:
+ return ("Not Implemented");
+ case HttpServletResponse.SC_NOT_MODIFIED:
+ return ("Not Modified");
+ case HttpServletResponse.SC_PARTIAL_CONTENT:
+ return ("Partial Content");
+ case HttpServletResponse.SC_PAYMENT_REQUIRED:
+ return ("Payment Required");
+ case HttpServletResponse.SC_PRECONDITION_FAILED:
+ return ("Precondition Failed");
+ case HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED:
+ return ("Proxy Authentication Required");
+ case HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE:
+ return ("Request Entity Too Large");
+ case HttpServletResponse.SC_REQUEST_TIMEOUT:
+ return ("Request Timeout");
+ case HttpServletResponse.SC_REQUEST_URI_TOO_LONG:
+ return ("Request URI Too Long");
+ case HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE:
+ return ("Requested Range Not Satisfiable");
+ case HttpServletResponse.SC_RESET_CONTENT:
+ return ("Reset Content");
+ case HttpServletResponse.SC_SEE_OTHER:
+ return ("See Other");
+ case HttpServletResponse.SC_SERVICE_UNAVAILABLE:
+ return ("Service Unavailable");
+ case HttpServletResponse.SC_SWITCHING_PROTOCOLS:
+ return ("Switching Protocols");
+ case HttpServletResponse.SC_UNAUTHORIZED:
+ return ("Unauthorized");
+ case HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE:
+ return ("Unsupported Media Type");
+ case HttpServletResponse.SC_USE_PROXY:
+ return ("Use Proxy");
+ case 207: // WebDAV
+ return ("Multi-Status");
+ case 422: // WebDAV
+ return ("Unprocessable Entity");
+ case 423: // WebDAV
+ return ("Locked");
+ case 507: // WebDAV
+ return ("Insufficient Storage");
+ default:
+ return ("HTTP Response Status " + pStatusCode);
+ }
+ }
+
+ String getHttpHeaders(Integer pContentLength) throws IOException {
+ StringBuffer sb = new StringBuffer();
+ sb.append("HTTP/1.0 ");
+ sb.append(status);
+ sb.append(' ');
+ sb.append(message);
+ sb.append("\r\n");
+ String contentType = getContentType();
+ if (contentType != null) {
+ sb.append("Content-Type: ");
+ sb.append(contentType);
+ sb.append("\r\n");
+ }
+ boolean contentLengthSeen = false;
+ for (Iterator iter = headers.entrySet().iterator(); iter.hasNext(); ) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String header = (String) entry.getKey();
+ if ("content-type".equalsIgnoreCase(header)) {
+ continue;
+ }
+ Object o = entry.getValue();
+ if (o == null) {
+ continue;
+ }
+ if ("content-length".equalsIgnoreCase(header)) {
+ contentLengthSeen = true;
+ }
+ if (o instanceof String) {
+ sb.append(header);
+ sb.append(": ");
+ sb.append(o);
+ sb.append("\r\n");
+ } else {
+ List list = (List) o;
+ for (int i = 0; i < list.size(); i++) {
+ sb.append(header);
+ sb.append(": ");
+ sb.append(list.get(i));
+ sb.append("\r\n");
+ }
+ }
+ }
+ if (pContentLength != null && !contentLengthSeen) {
+ sb.append("Content-Length: ");
+ sb.append(pContentLength);
+ sb.append("\r\n");
+ }
+ sb.append("\r\n");
+ return sb.toString();
+ }
+}
Added: webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletConnection.java
URL: http://svn.apache.org/viewcvs/webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletConnection.java?rev=328736&view=auto
==============================================================================
--- webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletConnection.java (added)
+++ webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletConnection.java Wed Oct 26 14:13:21 2005
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999,2005 The Apache Software Foundation.
+ *
+ * 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.apache.xmlrpc.webserver;
+
+import java.io.IOException;
+import java.net.Socket;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.xmlrpc.server.XmlRpcStreamServer;
+import org.apache.xmlrpc.util.ThreadPool.Task;
+
+
+/** {@link org.apache.xmlrpc.webserver.ServletWebServer ServletWebServer's}
+ * {@link org.apache.xmlrpc.util.ThreadPool.Task} for handling a single
+ * servlet connection.
+ */
+public class ServletConnection implements Task {
+ private final WebServer webServer;
+ private final XmlRpcStreamServer xmlRpcServer;
+ private final Socket socket;
+ private final HttpServletRequest request;
+ private final HttpServletResponse response;
+
+ public ServletConnection(WebServer pWebServer,
+ XmlRpcStreamServer pXmlRpcServer,
+ Socket pSocket) throws IOException {
+ webServer = pWebServer;
+ xmlRpcServer = pXmlRpcServer;
+ socket = pSocket;
+ request = new HttpServletRequestImpl(socket);
+ response = new HttpServletResponseImpl(socket);
+ }
+
+ public void run() throws Throwable {
+ // TODO Auto-generated method stub
+
+ }
+
+}
Added: webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletOutputStreamImpl.java
URL: http://svn.apache.org/viewcvs/webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletOutputStreamImpl.java?rev=328736&view=auto
==============================================================================
--- webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletOutputStreamImpl.java (added)
+++ webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletOutputStreamImpl.java Wed Oct 26 14:13:21 2005
@@ -0,0 +1,83 @@
+package org.apache.xmlrpc.webserver;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.servlet.ServletOutputStream;
+
+
+/** Default implementation of a servlet output stream.
+ * Handles output of HTTP headers.
+ */
+class ServletOutputStreamImpl extends ServletOutputStream {
+ private final OutputStream target;
+ private final HttpServletResponseImpl res;
+ private final byte[] buffer = new byte[HttpServletResponseImpl.BUFFER_SIZE];
+ private int bufferOffset;
+ private boolean closed;
+ private boolean committed;
+
+ ServletOutputStreamImpl(OutputStream pTarget, HttpServletResponseImpl pResponse) {
+ target = pTarget;
+ res = pResponse;
+ }
+
+ public void write(int b) throws IOException {
+ if (closed) {
+ throw new IOException("This output stream is already closed.");
+ }
+ if (bufferOffset == buffer.length) {
+ flush();
+ }
+ buffer[bufferOffset++] = (byte) b;
+ }
+
+ public void write(byte[] pChars, int pOffset, int pLen) throws IOException {
+ if (closed) {
+ throw new IOException("This output stream is already closed.");
+ }
+ while (pLen-- > 0) {
+ if (bufferOffset == buffer.length) {
+ flush();
+ }
+ buffer[bufferOffset++] = pChars[pOffset++];
+ }
+ }
+
+ private void flush(boolean pClosing) throws IOException {
+ if (!committed) {
+ committed = true;
+ String headers = res.getHttpHeaders(pClosing ? new Integer(bufferOffset) : null);
+ target.write(headers.getBytes("US-ASCII"));
+ }
+ if (bufferOffset > 0) {
+ target.write(buffer, 0, bufferOffset);
+ }
+ }
+
+ public void close() throws IOException {
+ if (!closed) {
+ flush(true);
+ closed = true;
+ target.close();
+ }
+ }
+
+ public void flush() throws IOException {
+ if (closed) {
+ throw new IOException("This output stream is already closed.");
+ }
+ flush(false);
+ target.flush();
+ }
+
+ void reset() {
+ if (committed) {
+ throw new IllegalStateException("The response is already committed. A reset cannot be performed.");
+ }
+ }
+
+ boolean isCommitted() {
+ return committed;
+ }
+}
Added: webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletWebServer.java
URL: http://svn.apache.org/viewcvs/webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletWebServer.java?rev=328736&view=auto
==============================================================================
--- webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletWebServer.java (added)
+++ webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/ServletWebServer.java Wed Oct 26 14:13:21 2005
@@ -0,0 +1,90 @@
+/*
+ * Copyright 1999,2005 The Apache Software Foundation.
+ *
+ * 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.apache.xmlrpc.webserver;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+
+import javax.servlet.ServletException;
+
+import org.apache.xmlrpc.server.XmlRpcStreamServer;
+import org.apache.xmlrpc.util.ThreadPool;
+
+
+/** A subclass of {@link WebServer}, which emulates a servlet
+ * container. Mainly useful for debugging.
+ */
+public class ServletWebServer extends WebServer {
+ /** This exception is thrown by the request handling classes,
+ * advising the server, that it should return an error response.
+ */
+ public static class Exception extends IOException {
+ private static final long serialVersionUID = 49879832748972394L;
+ private final int statusCode;
+ private final String description;
+
+ /** Creates a new instance.
+ * @param pStatusCode The HTTP status code being sent to the client.
+ * @param pMessage The HTTP status message being sent to the client.
+ * @param pDescription The error description being sent to the client
+ * in the response body.
+ */
+ public Exception(int pStatusCode, String pMessage, String pDescription) {
+ super(pMessage);
+ statusCode = pStatusCode;
+ description = pDescription;
+ }
+
+ public String getMessage() { return statusCode + " " + super.getMessage(); }
+
+ /** Returns the error description. The server will send the description
+ * as plain text in the response body.
+ * @return The error description.
+ */
+ public String getDescription() { return description; }
+
+ /** Returns the HTTP status code.
+ * @return The status code.
+ */
+ public int getStatusCode() { return statusCode; }
+ }
+
+ /** Creates a new instance, which is listening on all
+ * local IP addresses and the given port.
+ * @param pPort The servers port number; 0 for a random
+ * port being choosen.
+ */
+ public ServletWebServer(int pPort) {
+ super(pPort);
+ }
+
+ /** Creates a new instance, which is listening on the
+ * given IP address and the given port.
+ * @param pPort The servers port number; 0 for a random
+ * port being choosen.
+ * @param pAddr The servers IP address.
+ */
+ public ServletWebServer(int pPort, InetAddress pAddr) {
+ super(pPort, pAddr);
+ }
+
+ protected ThreadPool.Task newTask(WebServer pWebServer,
+ XmlRpcStreamServer pXmlRpcServer,
+ Socket pSocket) throws IOException {
+ return new ServletConnection(pWebServer, pXmlRpcServer, pSocket);
+ }
+}
Modified: webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/WebServer.java
URL: http://svn.apache.org/viewcvs/webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/WebServer.java?rev=328736&r1=328735&r2=328736&view=diff
==============================================================================
--- webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/WebServer.java (original)
+++ webservices/xmlrpc/branches/b20050512_streaming/src/java/org/apache/xmlrpc/webserver/WebServer.java Wed Oct 26 14:13:21 2005
@@ -248,7 +248,12 @@
}
return false;
}
-
+
+ protected ThreadPool.Task newTask(WebServer pServer, XmlRpcStreamServer pXmlRpcServer,
+ Socket pSocket) throws IOException {
+ return new Connection(pServer, pXmlRpcServer, pSocket);
+ }
+
/**
* Listens for client requests until stopped. Call {@link
* #start()} to invoke this method, and {@link #shutdown()} to
@@ -275,8 +280,8 @@
try {
if (allowConnection(socket)) {
- final Connection con = new Connection(this, server, socket);
- if (pool.startTask(con)) {
+ final ThreadPool.Task task = newTask(this, server, socket);
+ if (pool.startTask(task)) {
socket = null;
} else {
log("Maximum load of " + pool.getMaxThreads()