Revision: 3096
http://vexi.svn.sourceforge.net/vexi/?rev=3096&view=rev
Author: jeffbuhrt
Date: 2008-08-23 13:22:39 +0000 (Sat, 23 Aug 2008)
Log Message:
-----------
Core pipeling support using Apache.org's httpcore-4.0-beta2. An important
XMLRPC change is keepAlive is processed after the result data is read. When the
RPC receives a result the Connection: close means the next time a new socket is
needed, but the current result is still fine.
Modified Paths:
--------------
branches/vexi1/core/src/org/vexi/net/RPC.java
branches/vexi1/core/src/org/vexi/net/SOAP.java
branches/vexi1/core/src/org/vexi/net/XMLRPC.java
Modified: branches/vexi1/core/src/org/vexi/net/RPC.java
===================================================================
--- branches/vexi1/core/src/org/vexi/net/RPC.java 2008-08-20 17:19:55 UTC
(rev 3095)
+++ branches/vexi1/core/src/org/vexi/net/RPC.java 2008-08-23 13:22:39 UTC
(rev 3096)
@@ -116,7 +116,7 @@
protected String method;
/** FIXME */
- protected HTTP http;
+ protected LocalHTTP http;
/** FIXME */
protected String action;
Modified: branches/vexi1/core/src/org/vexi/net/SOAP.java
===================================================================
--- branches/vexi1/core/src/org/vexi/net/SOAP.java 2008-08-20 17:19:55 UTC
(rev 3095)
+++ branches/vexi1/core/src/org/vexi/net/SOAP.java 2008-08-23 13:22:39 UTC
(rev 3096)
@@ -39,7 +39,16 @@
*/
public SOAP(String url, String action, String namespace) {
super(url);
- http = url.startsWith("stdio:") ? HTTP.stdio : new HTTP(url);
+ //http = url.startsWith("stdio:") ? HTTP.stdio : new HTTP(url);
+ if (url.startsWith("stdio:"))
+ http = LocalHTTP.stdio;
+ else {
+ try {
+ http = new LocalHTTP(url);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
this.action = action;
this.namespace = namespace;
if (Debug.NET) {
@@ -155,7 +164,8 @@
String s = new String();
stringwriter.write(s);
Log.info(this, stringwriter.toString());
- java.io.InputStream inputstream =
super.http.httpPOST("text/xml", "\r\n" + stringwriter.toString());
+ //java.io.InputStream inputstream =
super.http.httpPOST("text/xml", "\r\n" + stringwriter.toString());
+ java.io.InputStream inputstream =
super.http.POST("text/xml", "\r\n" + stringwriter.toString(), null, null);
BufferedReader bufferedreader = Log.rpc ? new
BufferedReader(new FilterReader(new InputStreamReader(inputstream)) {
public int read() throws IOException {
int i = super.read();
Modified: branches/vexi1/core/src/org/vexi/net/XMLRPC.java
===================================================================
--- branches/vexi1/core/src/org/vexi/net/XMLRPC.java 2008-08-20 17:19:55 UTC
(rev 3095)
+++ branches/vexi1/core/src/org/vexi/net/XMLRPC.java 2008-08-23 13:22:39 UTC
(rev 3096)
@@ -8,10 +8,36 @@
import java.io.FilterReader;
import java.io.StringReader;
import java.io.StringWriter;
+import java.net.Socket;
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.DefaultHttpClientConnection;
+import org.apache.http.message.BasicHttpEntityEnclosingRequest;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.BasicHttpProcessor;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestExecutor;
+import org.apache.http.protocol.RequestConnControl;
+import org.apache.http.protocol.RequestContent;
+import org.apache.http.protocol.RequestExpectContinue;
+import org.apache.http.protocol.RequestTargetHost;
+import org.apache.http.protocol.RequestUserAgent;
+
import org.ibex.js.JS;
import org.ibex.js.JSArray;
import org.ibex.js.JSExn;
+import org.ibex.net.SSL;
import org.ibex.util.Hash;
import org.ibex.util.Log;
import org.ibex.util.Task;
@@ -30,9 +56,9 @@
/**
* Class Constructor invoked when only a url and methodname are specified
- *
+ * An absolute
* @param url
- * An absolute URL giving the location of the XMLRPC service
+ * URL giving the location of the XMLRPC service
* handler
* @param method
* The named of the XMLRPC method that will be invoked on the
@@ -40,7 +66,16 @@
*/
public XMLRPC(String url, String method) {
super(url);
- http = url.startsWith("stdio:") ? HTTP.stdio : new HTTP(url);
+ //http = url.startsWith("stdio:") ? HTTP.stdio : new HTTP(url);
+ if (url.startsWith("stdio:"))
+ http = LocalHTTP.stdio;
+ else {
+ try {
+ http = new LocalHTTP(url);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
this.method = method;
}
@@ -136,7 +171,9 @@
if (Log.rpc) {
Log.info(this, "send:\n" + request);
}
- InputStream is = http.httpPOST("text/xml", "\r\n" +
request.toString());
+ //InputStream is = http.httpPOST("text/xml", "\r\n" +
request.toString());
+ InputStream is = http.POST("text/xml",
request.toString(),
+ null, null);
BufferedReader br = !Log.rpc ? new BufferedReader(
new InputStreamReader(is)) : new
BufferedReader(
new FilterReader(new
InputStreamReader(is)) {
@@ -199,6 +236,147 @@
}
});
+ } finally {
+ if (!http.keepAlive)
+ http.close();
}
}
}
+
+class LocalHTTP {
+ final String url;
+
+ boolean ssl;
+
+ // The close for keepAlive 'close' is processed after reading the rest
of
+ // the result.
+ boolean keepAlive = true;
+
+ final String path;
+
+ final HttpHost host;
+
+ // HttpComponents guff
+ final HttpParams params;
+
+ final BasicHttpProcessor httpproc;
+
+ final HttpRequestExecutor httpexecutor;
+
+ final ConnectionReuseStrategy connStrategy;
+
+ final DefaultHttpClientConnection conn;
+
+ static LocalHTTP stdio = null;
+ static {
+ try {
+ stdio = new LocalHTTP("stdio:");
+ }
+ catch (Exception e) {/*ignore*/}
+ }
+
+ public LocalHTTP(String url) throws IOException {
+ this.url = url;
+
+ if (url.startsWith("https:")) {
+ ssl = true;
+ } else if (!url.startsWith("http:")) {
+
+ throw new IOException("HTTP only supports http/https
urls");
+ }
+ if (url.indexOf("://") == -1)
+ throw new IOException("URLs must contain a ://");
+ String temphost = url.substring(url.indexOf("://") + 3);
+ path = temphost.substring(temphost.indexOf('/'));
+ temphost = temphost.substring(0, temphost.indexOf('/'));
+ int port;
+ if (temphost.indexOf(':') != -1) {
+ port = Integer.parseInt(temphost
+ .substring(temphost.indexOf(':') + 1));
+ temphost = temphost.substring(0, temphost.indexOf(':'));
+ } else {
+ port = ssl ? 443 : 80;
+ }
+ host = new HttpHost(temphost, port);
+
+ params = new BasicHttpParams();
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+ HttpProtocolParams.setContentCharset(params, "UTF-8");
+ HttpProtocolParams.setUserAgent(params, "Vexi");
+ HttpProtocolParams.setUseExpectContinue(params, true);
+
+ httpproc = new BasicHttpProcessor();
+ // Required protocol interceptors
+ httpproc.addInterceptor(new RequestContent());
+ httpproc.addInterceptor(new RequestTargetHost());
+ // Recommended protocol interceptors
+ httpproc.addInterceptor(new RequestConnControl());
+ httpproc.addInterceptor(new RequestUserAgent());
+ httpproc.addInterceptor(new RequestExpectContinue());
+
+ httpexecutor = new HttpRequestExecutor();
+
+ connStrategy = new DefaultConnectionReuseStrategy();
+ conn = new DefaultHttpClientConnection();
+
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ }
+
+ private Socket getSocket(String host, int port, boolean ssl,
+ boolean negotiate) throws IOException {
+ Socket ret = ssl ? new SSL(host, port, negotiate) : new Socket(
+ java.net.InetAddress.getByName(host), port);
+ ret.setTcpNoDelay(false);
+ return ret;
+ }
+
+ public InputStream POST(String contentType, String content, Object b,
Object c)
+ throws IOException {
+
+ HttpContext context = new BasicHttpContext(null);
+
+ context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
+ context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
+
+ try {
+
+ if (!conn.isOpen()) {
+ Log.warn(XMLRPC.class, "Creating socket");
+ Socket socket = getSocket(host.getHostName(),
host.getPort(),
+ ssl, true);
+ // Socket socket = new
Socket(host.getHostName(),
+ // host.getPort());
+ conn.bind(socket, params);
+ }
+ BasicHttpEntityEnclosingRequest request = new
BasicHttpEntityEnclosingRequest(
+ "POST", path);
+ StringEntity entity = new StringEntity(content,
"UTF-8");
+ entity.setContentType(contentType);
+ request.setEntity(entity);
+
+ context.setAttribute(ExecutionContext.HTTP_REQUEST,
request);
+ request.setParams(params);
+ httpexecutor.preProcess(request, httpproc, context);
+ HttpResponse response = httpexecutor
+ .execute(request, conn, context);
+ httpexecutor.postProcess(response, httpproc, context);
+ if (!connStrategy.keepAlive(response, context))
+ keepAlive = false;
+ return response.getEntity().getContent();
+
+ } catch (HttpException he) {
+ throw new IOException(he);
+ }
+ }
+
+ public void close () {
+ try {
+ conn.close();
+ } catch (IOException e) {
+ }
+ }
+}
+
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn