You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2005/04/24 23:31:41 UTC
svn commit: r164502 - in /jakarta/httpclient/trunk/http-common/src:
examples/org/apache/http/examples/ java/org/apache/http/
java/org/apache/http/entity/ java/org/apache/http/impl/
Author: olegk
Date: Sun Apr 24 14:31:41 2005
New Revision: 164502
URL: http://svn.apache.org/viewcvs?rev=164502&view=rev
Log:
Elemental HTTP server demo + some minor tweaks
Added:
jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java (with props)
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/ConnectionClosedException.java (with props)
Modified:
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpMutableResponse.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpResponse.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/entity/EntityConsumer.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/BasicHttpResponse.java
jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
Added: jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java?rev=164502&view=auto
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java (added)
+++ jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java Sun Apr 24 14:31:41 2005
@@ -0,0 +1,260 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 1999-2004 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.examples;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpException;
+import org.apache.http.HttpMutableResponse;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpServerConnection;
+import org.apache.http.HttpStatus;
+import org.apache.http.ProtocolException;
+import org.apache.http.entity.EntityConsumer;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.BasicHttpResponse;
+import org.apache.http.impl.ConnectionClosedException;
+import org.apache.http.impl.ConnectionReuseStrategy;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.DefaultHttpParams;
+import org.apache.http.impl.DefaultHttpServerConnection;
+import org.apache.http.impl.MethodNotSupportedException;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+
+/**
+ * <p>
+ * </p>
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ *
+ * @version $Revision$
+ */
+public class ElementalHttpEchoServer {
+
+ private static final String TEST_SERVER = "Test server";
+
+ public static void main(String[] args) throws Exception {
+ Thread t = new RequestListenerThread(8080);
+ t.setDaemon(false);
+ t.start();
+ }
+
+ static class RequestHandler {
+
+ public RequestHandler() {
+ super();
+ }
+
+ public void handleRequest(final HttpRequest request, final HttpMutableResponse response)
+ throws IOException {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("<html>");
+ buffer.append("<body>");
+ buffer.append("<p>Request method: ");
+ buffer.append(request.getRequestLine().getMethod());
+ buffer.append("</p>");
+ buffer.append("<p>Request URI: ");
+ buffer.append(request.getRequestLine().getUri());
+ buffer.append("</p>");
+ buffer.append("<p>Request Version: ");
+ buffer.append(request.getRequestLine().getHttpVersion());
+ buffer.append("</p>");
+ if (request instanceof HttpEntityEnclosingRequest) {
+ HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
+ buffer.append("<p>Content Type: ");
+ buffer.append(entity.getContentType());
+ buffer.append("</p>");
+ buffer.append("<p>Content Chunk-coded: ");
+ buffer.append(entity.isChunked());
+ buffer.append("</p>");
+ EntityConsumer consume = new EntityConsumer((HttpEntityEnclosingRequest)request);
+ if (entity.getContentType() != null
+ && entity.getContentType().toLowerCase().startsWith("text/")) {
+ buffer.append("<p>");
+ buffer.append(consume.asString());
+ buffer.append("</p>");
+ } else {
+ byte[] raw = consume.asByteArray();
+ buffer.append("<p>");
+ for (int i = 0; i < raw.length; i++) {
+ buffer.append(Integer.toHexString(raw[i]).toLowerCase());
+ if (i % 20 == 19) {
+ buffer.append("<br>");
+ } else {
+ buffer.append(" ");
+ }
+ }
+ buffer.append("</p>");
+ }
+ }
+ buffer.append("</body>");
+ buffer.append("</html>");
+ StringEntity body = new StringEntity(buffer.toString());
+ body.setContentType("text/html; charset=UTF-8");
+
+ response.setStatusCode(HttpStatus.SC_OK);
+ response.setHeader(new Header("Server", TEST_SERVER));
+ response.setHeader(new Header("Connection", "Keep-Alive"));
+ if (body.isChunked() || body.getContentLength() < 0) {
+ response.setHeader(new Header("Transfer-Encoding", "chunked"));
+ } else {
+ response.setHeader(new Header("Content-Length",
+ Long.toString(body.getContentLength())));
+ }
+ if (body.getContentType() != null) {
+ response.setHeader(new Header("Content-Type", body.getContentType()));
+ }
+ response.setEntity(body);
+ }
+
+ public void handleException(final HttpException ex, final HttpMutableResponse response) {
+ if (ex instanceof MethodNotSupportedException) {
+ response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
+ } else if (ex instanceof ProtocolException) {
+ response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
+ } else {
+ response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ }
+ response.setHeader(new Header("Server", TEST_SERVER));
+ response.setHeader(new Header("Connection", "Close"));
+ }
+ }
+
+ static class RequestListenerThread extends Thread {
+
+ private final ServerSocketChannel serverchannel;
+ private HttpParams params;
+
+ public RequestListenerThread(int port) throws IOException {
+ this.serverchannel = ServerSocketChannel.open();
+ this.serverchannel.socket().bind(new InetSocketAddress(port));
+ this.params = new DefaultHttpParams(null);
+ }
+
+ public void run() {
+ System.out.println("Listening on port " + this.serverchannel.socket().getLocalPort());
+ while (!Thread.interrupted()) {
+ try {
+ SocketChannel channel = this.serverchannel.accept();
+ Socket socket = channel.socket();
+ HttpServerConnection conn = new DefaultHttpServerConnection();
+ System.out.println("Incoming connection from " + socket.getRemoteSocketAddress());
+ conn.bind(socket, this.params);
+ Thread t = new HttpConnectionThread(conn);
+ t.setDaemon(true);
+ t.start();
+ } catch (InterruptedIOException ex) {
+ break;
+ } catch (IOException e) {
+ System.err.println("I/O error initialising connection thread: "
+ + e.getMessage());
+ break;
+ }
+ }
+ }
+ }
+
+ static class HttpConnectionThread extends Thread {
+
+ private final HttpServerConnection conn;
+ private final HttpParams params;
+ private final RequestHandler handler;
+
+ public HttpConnectionThread(final HttpServerConnection conn) {
+ super();
+ this.conn = conn;
+ this.params = new DefaultHttpParams(null);
+ new HttpConnectionParams(this.params).setSoTimeout(15000);
+ this.handler = new RequestHandler();
+ }
+
+ public HttpParams getParams() {
+ return this.params;
+ }
+
+ public void closeConnection() {
+ try {
+ this.conn.close();
+ System.out.println("Connection closed");
+ } catch (IOException ex) {
+ System.err.println("I/O error closing connection: " + ex.getMessage());
+ }
+ }
+
+ public void run() {
+ System.out.println("New connection thread");
+ while (!Thread.interrupted()) {
+ BasicHttpResponse response = new BasicHttpResponse();
+ try {
+ this.conn.setSocketTimeout(100);
+ HttpRequest request = this.conn.receiveRequest(this.params);
+ System.out.println("Request received");
+ this.handler.handleRequest(request, response);
+ } catch (ConnectionClosedException ex) {
+ System.out.println("Client closed connection");
+ break;
+ } catch (HttpException ex) {
+ this.handler.handleException(ex, response);
+ } catch (IOException ex) {
+ System.err.println("I/O error receiving request: " + ex.getMessage());
+ closeConnection();
+ break;
+ }
+ try {
+ this.conn.sendResponse(response);
+ System.out.println("Response sent");
+ } catch (HttpException ex) {
+ System.err.println("Malformed response: " + ex.getMessage());
+ closeConnection();
+ } catch (IOException ex) {
+ System.err.println("I/O error sending response: " + ex.getMessage());
+ closeConnection();
+ break;
+ }
+ ConnectionReuseStrategy connreuse = new DefaultConnectionReuseStrategy();
+ if (!connreuse.keepAlive(response)) {
+ closeConnection();
+ break;
+ } else {
+ System.out.println("Connection kept alive");
+ }
+ }
+ }
+
+ }
+}
Propchange: jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/ElementalHttpEchoServer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpMutableResponse.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpMutableResponse.java?rev=164502&r1=164501&r2=164502&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpMutableResponse.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpMutableResponse.java Sun Apr 24 14:31:41 2005
@@ -40,6 +40,10 @@
*/
public interface HttpMutableResponse extends HttpMutableMessage, HttpResponse {
- void setEntity(HttpIncomingEntity entity);
+ void setStatusLine(StatusLine statusline);
+
+ void setStatusCode(int code);
+
+ void setEntity(HttpEntity entity);
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpResponse.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpResponse.java?rev=164502&r1=164501&r2=164502&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpResponse.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpResponse.java Sun Apr 24 14:31:41 2005
@@ -42,6 +42,6 @@
StatusLine getStatusLine();
- HttpIncomingEntity getEntity();
+ HttpEntity getEntity();
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/entity/EntityConsumer.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/entity/EntityConsumer.java?rev=164502&r1=164501&r2=164502&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/entity/EntityConsumer.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/entity/EntityConsumer.java Sun Apr 24 14:31:41 2005
@@ -37,7 +37,9 @@
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpIncomingEntity;
+import org.apache.http.HttpMessage;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.params.HttpProtocolParams;
@@ -53,14 +55,25 @@
*/
public class EntityConsumer {
- private final HttpResponse response;
+ private final HttpMessage message;
+ private final HttpIncomingEntity entity;
public EntityConsumer(final HttpResponse response) {
super();
if (response == null) {
throw new IllegalArgumentException("HTTP response may not be null");
}
- this.response = response;
+ this.message = response;
+ this.entity = (HttpIncomingEntity)response.getEntity();
+ }
+
+ public EntityConsumer(final HttpEntityEnclosingRequest request) {
+ super();
+ if (request == null) {
+ throw new IllegalArgumentException("HTTP request may not be null");
+ }
+ this.message = request;
+ this.entity = (HttpIncomingEntity)request.getEntity();
}
public static byte[] toByteArray(final HttpIncomingEntity entity) throws IOException {
@@ -137,20 +150,18 @@
}
public byte[] asByteArray() throws IOException {
- HttpIncomingEntity entity = this.response.getEntity();
- if (entity == null) {
+ if (this.entity == null) {
return new byte[] {};
}
- return toByteArray(entity);
+ return toByteArray(this.entity);
}
public String asString() throws IOException {
- HttpIncomingEntity entity = this.response.getEntity();
- if (entity == null) {
+ if (this.entity == null) {
return "";
}
- HttpProtocolParams params = new HttpProtocolParams(this.response.getParams());
- return toString(entity, params.getContentCharset());
+ HttpProtocolParams params = new HttpProtocolParams(this.message.getParams());
+ return toString(this.entity, params.getContentCharset());
}
}
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/BasicHttpResponse.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/BasicHttpResponse.java?rev=164502&r1=164501&r2=164502&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/BasicHttpResponse.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/BasicHttpResponse.java Sun Apr 24 14:31:41 2005
@@ -29,9 +29,11 @@
package org.apache.http.impl;
-import org.apache.http.HttpIncomingEntity;
+import org.apache.http.HttpEntity;
import org.apache.http.HttpMutableResponse;
+import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
+import org.apache.http.params.HttpProtocolParams;
/**
* <p>
@@ -45,25 +47,44 @@
public class BasicHttpResponse extends BasicHttpMessage implements HttpMutableResponse {
private StatusLine statusline = null;
- private HttpIncomingEntity entity = null;
+ private HttpEntity entity = null;
+ public BasicHttpResponse() {
+ super();
+ setStatusCode(HttpStatus.SC_OK);
+ }
+
public BasicHttpResponse(final StatusLine statusline) {
super();
- if (statusline == null) {
- throw new IllegalArgumentException("Status line may not be null");
- }
- this.statusline = statusline;
+ setStatusLine(statusline);
}
public StatusLine getStatusLine() {
return this.statusline;
}
- public HttpIncomingEntity getEntity() {
+ public HttpEntity getEntity() {
return this.entity;
}
+
+ public void setStatusLine(final StatusLine statusline) {
+ if (statusline == null) {
+ throw new IllegalArgumentException("Status line may not be null");
+ }
+ this.statusline = statusline;
+ }
+
+ public void setStatusCode(int code) {
+ if (code < 0) {
+ throw new IllegalArgumentException("Status line may not be null");
+ }
+ HttpProtocolParams params = new HttpProtocolParams(getParams());
+ this.statusline = new StatusLine(
+ params.getVersion(),
+ code, HttpStatus.getStatusText(code));
+ }
- public void setEntity(final HttpIncomingEntity entity) {
+ public void setEntity(final HttpEntity entity) {
this.entity = entity;
}
Added: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/ConnectionClosedException.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/ConnectionClosedException.java?rev=164502&view=auto
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/ConnectionClosedException.java (added)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/ConnectionClosedException.java Sun Apr 24 14:31:41 2005
@@ -0,0 +1,54 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 1999-2004 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.impl;
+
+import java.io.IOException;
+
+/**
+ * <p>
+ * </p>
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ *
+ * @version $Revision$
+ *
+ * @since 4.0
+ */
+public class ConnectionClosedException extends IOException {
+
+ /**
+ * Creates a new MethodNotSupportedException with the specified detail message.
+ *
+ * @param message The exception detail message
+ */
+ public ConnectionClosedException(final String message) {
+ super(message);
+ }
+
+}
Propchange: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/ConnectionClosedException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/ConnectionClosedException.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/ConnectionClosedException.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java?rev=164502&r1=164501&r2=164502&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java Sun Apr 24 14:31:41 2005
@@ -98,8 +98,8 @@
validateRequest(request);
validated = true;
sendContinue(responsever);
- receiveRequestBody((HttpMutableEntityEnclosingRequest)request);
}
+ receiveRequestBody((HttpMutableEntityEnclosingRequest)request);
}
if (!validated) {
validateRequest(request);
@@ -111,7 +111,7 @@
throws HttpException, IOException {
String line = this.datareceiver.readLine();
if (line == null) {
- throw new ProtocolException("Request line not found");
+ throw new ConnectionClosedException("Client closed connection");
}
RequestLine requestline = RequestLine.parse(line);
if (isWirelogEnabled()) {