jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dpfis...@apache.org
Subject svn commit: r1171142 - in /jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk: client/ server/
Date Thu, 15 Sep 2011 15:36:48 GMT
Author: dpfister
Date: Thu Sep 15 15:36:48 2011
New Revision: 1171142

URL: http://svn.apache.org/viewvc?rev=1171142&view=rev
Log:
HTTP interface to microkernel
- add connection reuse

Modified:
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Client.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Request.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/HttpProcessor.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Response.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Client.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Client.java?rev=1171142&r1=1171141&r2=1171142&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Client.java
(original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Client.java
Thu Sep 15 15:36:48 2011
@@ -35,6 +35,8 @@ public class Client implements MicroKern
     
     private final InetSocketAddress addr;
     
+    private HttpExecutor executor;
+    
     private boolean disposed;
     
     /**
@@ -49,7 +51,14 @@ public class Client implements MicroKern
     //-------------------------------------------------- implements MicroKernel
     
     public void dispose() {
-        disposed = true;
+        if (disposed) {
+            return;
+        }
+        try {
+            IOUtils.closeQuietly(executor);
+        } finally {
+            disposed = true;
+        }
     }
 
     public String getHeadRevision() throws MicroKernelException {
@@ -246,14 +255,22 @@ public class Client implements MicroKern
      * @return request
      * @throws IOException if an I/O error occurs
      * @throws MicroKernelException if an exception occurs
-     * 
-     * TODO reuse executors and/or requests
      */
     private Request createRequest(String command) throws IOException, MicroKernelException
{
         if (disposed) {
             throw new IllegalStateException("This instance has already been disposed");
         }
-        Socket socket = new Socket(addr.getAddress(), addr.getPort());
-        return new Request(new HttpExecutor(socket), command);
+        if (executor != null && !executor.isAlive()) {
+            IOUtils.closeQuietly(executor);
+            executor = null;
+        }
+        if (executor == null) {
+            executor = new HttpExecutor(createSocket());
+        }
+        return new Request(executor, command);
+    }
+    
+    private Socket createSocket() throws IOException {
+        return new Socket(addr.getAddress(), addr.getPort());
     }
 }

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java?rev=1171142&r1=1171141&r2=1171142&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java
(original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java
Thu Sep 15 15:36:48 2011
@@ -25,8 +25,10 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.Socket;
 import java.net.URLEncoder;
+import java.security.SecureRandom;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Random;
 
 import org.apache.jackrabbit.mk.util.BoundedInputStream;
 import org.apache.jackrabbit.mk.util.ChunkedInputStream;
@@ -38,9 +40,6 @@ import org.apache.jackrabbit.mk.util.IOU
  */
 class HttpExecutor implements Closeable {
 
-    // TODO should actually NEVER match some part of binary content
-    private static final String BOUNDARY = "------ClientFormBoundaryHB5WJrSAPZjfwtqt--";
-    
     private final Socket socket;
     
     private InputStream socketIn;
@@ -70,8 +69,9 @@ class HttpExecutor implements Closeable 
             throws IOException {
         
         // send request
-        socketOut = new BufferedOutputStream(socket.getOutputStream());
-
+        if (socketOut == null) {
+            socketOut = new BufferedOutputStream(socket.getOutputStream());
+        }
         String contentType = "application/x-www-form-urlencoded";
         if (in != null) {
             contentType = "multipart/form-data";
@@ -85,11 +85,12 @@ class HttpExecutor implements Closeable 
         OutputStream bodyOut = new ChunkedOutputStream(socketOut);
         
         if (in != null) {
-            bodyOut.write(BOUNDARY.getBytes());
+            String boundary = getBoundary();
+            bodyOut.write(boundary.getBytes());
             bodyOut.write("\r\n\r\n".getBytes());
             IOUtils.copy(in, bodyOut);
             bodyOut.write("\r\n".getBytes());
-            bodyOut.write(BOUNDARY.getBytes());
+            bodyOut.write(boundary.getBytes());
         } else {
             for (Map.Entry<String,String> param : params.entrySet()) {
                 String s = String.format("%s=%s&", 
@@ -103,7 +104,9 @@ class HttpExecutor implements Closeable 
         socketOut.flush();
         
         // read response
-        socketIn = new BufferedInputStream(socket.getInputStream());
+        if (socketIn == null) {
+            socketIn = new BufferedInputStream(socket.getInputStream());
+        }
         
         String responseLine = readLine(socketIn);
         String[] parts = responseLine.split(" ");
@@ -166,6 +169,10 @@ class HttpExecutor implements Closeable 
             throw new IOException(msg);
         }
     }
+    
+    public boolean isAlive() {
+        return !socket.isClosed();
+    }
 
     public void close() {
         IOUtils.closeQuietly(socketOut);
@@ -208,4 +215,33 @@ class HttpExecutor implements Closeable 
             }
         }
     }
+
+    /**
+     * Boundary.
+     */
+    private static String boundary; 
+    
+    /**
+     * Boundary characters.
+     */
+    private static final char[] BOUNDARY_CHARACTERS = 
+            "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+    
+    /**
+     * Return a multipart boundary.
+     * 
+     * @return boundary
+     */
+    private static String getBoundary() {
+        if (boundary == null) {
+            StringBuilder b = new StringBuilder();
+            Random random = new SecureRandom();
+            
+            for (int i = 0; i < 16; i++) {
+                b.append(BOUNDARY_CHARACTERS[random.nextInt(BOUNDARY_CHARACTERS.length)]);
+            }
+            boundary = String.format("------ClientFormBoundary%s--", b.toString());
+        }
+        return boundary;
+    }
 }

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Request.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Request.java?rev=1171142&r1=1171141&r2=1171142&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Request.java
(original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/client/Request.java
Thu Sep 15 15:36:48 2011
@@ -31,7 +31,7 @@ import org.apache.jackrabbit.mk.util.IOU
  */
 class Request implements Closeable {
     
-    private final HttpExecutor executor;
+    private HttpExecutor executor;
     
     private final String command;
     
@@ -54,24 +54,55 @@ class Request implements Closeable {
         this.command = command;
     }
     
+    /**
+     * Add a string parameter.
+     * 
+     * @param name name
+     * @param value value, if <code>null</code> the call is ignored
+     */
     public void addParameter(String name, String value) {
         if (value != null) {
             params.put(name, value);
         }
     }
 
+    /**
+     * Add an integer parameter, equivalent to 
+     * <code>addParameter(name, String.valueOf(value))</code>.
+     * 
+     * @param name name
+     * @param value value
+     */
     public void addParameter(String name, int value) {
         params.put(name, String.valueOf(value));
     }
     
+    /**
+     * Add a long parameter, equivalent to 
+     * <code>addParameter(name, String.valueOf(value))</code>.
+     * 
+     * @param name name
+     * @param value value
+     */
     public void addParameter(String name, long value) {
         params.put(name, String.valueOf(value));
     }
     
+    /**
+     * Add a file parameter that will be transmitted as form data. 
+     * 
+     * @param name name
+     * @param in input stream
+     */
     public void addFileParameter(String name, InputStream in) {
         this.in = in;
     }
     
+    /**
+     * Execute the request.
+     * 
+     * @throws IOException if an I/O error occurs
+     */
     public void execute() throws IOException {
         if (executed) {
             return;
@@ -83,24 +114,58 @@ class Request implements Closeable {
         }
     }
     
+    /**
+     * Return a string from the result stream. Automatically executes
+     * the request first.
+     * 
+     * @return string
+     * @throws IOException if an I/O error occurs
+     */
     public String getString() throws IOException {
         execute();
         
         return new String(toByteArray(resultIn), "8859_1");
     }
 
+    /**
+     * Return a boolean from the result stream, equivalent to 
+     * <code>Boolean.parseBoolean(getString())</code>.
+     * Automatically executes the request first.
+     * 
+     * @return boolean
+     * @throws IOException if an I/O error occurs
+     */
     public boolean getBoolean() throws IOException {
         execute();
         
         return Boolean.parseBoolean(getString());
     }
     
+    /**
+     * Return a long from the result stream, equivalent to 
+     * <code>Long.parseLong(getString())</code>.
+     * Automatically executes the request first.
+     * 
+     * @return boolean
+     * @throws IOException if an I/O error occurs
+     */
     public long getLong() throws IOException {
         execute();
         
         return Long.parseLong(getString());
     }
 
+    /**
+     * Read bytes from the result stream. Automatically executes the
+     * request first.
+     * 
+     * @param b buffer
+     * @param off offset
+     * @param len length
+     * @return number of bytes or <code>-1</code> if no more bytes are available
+     * 
+     * @throws IOException if an I/O error occurs
+     */
     public int read(byte[] b, int off, int len) throws IOException {
         execute();
         
@@ -116,9 +181,7 @@ class Request implements Closeable {
     }
     
     public void close() {
-        // TODO set conn reference to null and reuse it
-        
-        executor.close();
+        executor = null;
     }
     
     private static byte[] toByteArray(InputStream in) throws IOException {

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java?rev=1171142&r1=1171141&r2=1171142&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java
(original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java
Thu Sep 15 15:36:48 2011
@@ -21,7 +21,7 @@ import java.io.IOException;
 
 /**
  * Stream that reads bytes until it sees a given string boundary, preceded
- * by CR+LF, as used in multipart/form-data.
+ * by CR+LF, as used in multipart/form-data uploads.
  */
 class BoundaryInputStream extends InputStream {
 

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/HttpProcessor.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/HttpProcessor.java?rev=1171142&r1=1171141&r2=1171142&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/HttpProcessor.java
(original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/HttpProcessor.java
Thu Sep 15 15:36:48 2011
@@ -29,6 +29,10 @@ import org.apache.jackrabbit.mk.util.IOU
  * Process all HTTP requests on a single socket.
  */
 class HttpProcessor {
+    
+    private static final int INITIAL_SO_TIMEOUT = 1000;
+    
+    private static final int DEFAULT_SO_TIMEOUT = 15000; 
 
     private final Socket socket;
     
@@ -55,14 +59,21 @@ class HttpProcessor {
      * @throws IOException if an I/O error occurs
      */
     public void process() throws IOException {
-        try { 
+        try {
             socketIn = new BufferedInputStream(socket.getInputStream());
             socketOut = new BufferedOutputStream(socket.getOutputStream());
             
-            do {
-                process1();
-                
-            } while (false /* TODO: check for keep-alive and reuse */);
+            int timeout = INITIAL_SO_TIMEOUT;
+            socket.setSoTimeout(timeout);
+            
+            for (;;) {
+                if (!process1()) {
+                    break;
+                }
+                if (timeout != DEFAULT_SO_TIMEOUT) {
+                    socket.setSoTimeout(timeout = DEFAULT_SO_TIMEOUT);
+                }
+            }
         
         }  finally {
             IOUtils.closeQuietly(socketOut);
@@ -74,23 +85,27 @@ class HttpProcessor {
     /**
      * Process a single request.
      * 
+     * @return <code>true</code> if the connection should be kept alive;
+     *         <code>false</code> otherwise
+     *         
      * @throws IOException if an I/O error occurs
      */
-    private void process1() throws IOException {
+    private boolean process1() throws IOException {
         Request request = null;
-        Response response = new Response(socketOut);
+        Response response = null;
         
         try {
             request = Request.parse(socketIn);
-            if (request == null) {
-                response.setStatusCode(400);
-            } else {
+            if (request != null) {
+                boolean keepAlive = request.isKeepAlive();
+                response = new Response(socketOut, keepAlive);
                 servlet.service(request, response);
+                return keepAlive;
             }
         } finally {
             IOUtils.closeQuietly(request);
             IOUtils.closeQuietly(response);
         }
+        return false;
     }
-    
 }

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java?rev=1171142&r1=1171141&r2=1171142&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java
(original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java
Thu Sep 15 15:36:48 2011
@@ -135,7 +135,7 @@ class MicroKernelServlet implements Serv
             }
 
             response.setContentType("text/plain");
-            response.write(currentHead);
+            response.write(currentHead == null ? "null" : currentHead);
         }
     }
 
@@ -233,9 +233,6 @@ class MicroKernelServlet implements Serv
                 throws IOException, MicroKernelException {
 
             String blobId = request.getParameter("blob_id");
-            if (blobId == null) {
-                return;
-            }
             long pos = request.getParameter("pos", 0L);
             int length = request.getParameter("length", -1); 
             
@@ -261,12 +258,11 @@ class MicroKernelServlet implements Serv
                 throws IOException, MicroKernelException {
 
             InputStream in = request.getFileParameter("file");
-            if (in != null) {
-                String blobId = mk.write(in);
 
-                response.setContentType("text/plain");
-                response.write(blobId);
-            }
+            String blobId = mk.write(in);
+
+            response.setContentType("text/plain");
+            response.write(blobId);
         }        
     }
 }

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java?rev=1171142&r1=1171141&r2=1171142&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java
(original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java
Thu Sep 15 15:36:48 2011
@@ -34,6 +34,8 @@ import org.apache.jackrabbit.mk.util.IOU
  * HTTP Request implementation.
  */
 class Request implements Closeable {
+    
+    private static final String HTTP_11_PROTOCOL = "HTTP/1.1";
 
     private InputStream in;
     
@@ -41,6 +43,8 @@ class Request implements Closeable {
     
     private final String file;
     
+    private final String protocol;
+    
     private String queryString;
     
     private final Map<String,String> headers;
@@ -57,7 +61,8 @@ class Request implements Closeable {
      * @param headers request headers
      * @param in request body
      */
-    private Request(String method, String uri, Map<String,String> headers, InputStream
in) {
+    private Request(String method, String uri, String protocol,
+            Map<String,String> headers, InputStream in) {
         this.method = method;
         
         int index = uri.lastIndexOf('?');
@@ -68,6 +73,7 @@ class Request implements Closeable {
             queryString = uri.substring(index + 1);
         }
         
+        this.protocol = protocol;
         this.headers = headers;
         this.in = in;
     }
@@ -81,6 +87,7 @@ class Request implements Closeable {
         }
         String method = parts[0];
         String uri = parts[1];
+        String protocol = parts[2];
         
         Map<String, String> headers = new LinkedHashMap<String, String>();
         
@@ -94,7 +101,7 @@ class Request implements Closeable {
                 headers.put(parts[0].trim(), parts[1].trim());
             }
         }
-        return new Request(method, uri, headers, in);
+        return new Request(method, uri, protocol, headers, in);
     }
     
     /**
@@ -227,7 +234,7 @@ class Request implements Closeable {
         for (String param : s.split("&")) {
             String[] nv = param.split("=");
             if (nv.length == 2) {
-                map.put(URLDecoder.decode(nv[0], "8859_1"), URLDecoder.decode(nv[1], "8859_1"));
+                map.put(URLDecoder.decode(nv[0], "UTF-8"), URLDecoder.decode(nv[1], "UTF-8"));
             }
         }
     }
@@ -248,6 +255,10 @@ class Request implements Closeable {
         return reqIn;
     }
     
+    boolean isKeepAlive() {
+        return HTTP_11_PROTOCOL.equals(protocol);
+    }
+    
     public void close() {
         if (in != null) {
             IOUtils.closeQuietly(reqIn);

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Response.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Response.java?rev=1171142&r1=1171141&r2=1171142&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Response.java
(original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Response.java
Thu Sep 15 15:36:48 2011
@@ -19,6 +19,8 @@ package org.apache.jackrabbit.mk.server;
 import java.io.Closeable;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.LinkedHashMap;
+import java.util.Map;
 
 import org.apache.jackrabbit.mk.util.IOUtils;
 
@@ -29,6 +31,8 @@ class Response implements Closeable {
     
     private OutputStream out;
     
+    private boolean keepAlive;
+    
     private boolean headersSent;
     
     private boolean committed;
@@ -41,13 +45,17 @@ class Response implements Closeable {
     
     private BodyOutputStream respOut;
     
+    private Map<String,String> headers;
+    
     /**
      * Create a new instance of this class.
      * 
      * @param out output stream
+     * @param keepAlive whether to keep alive the connection
      */
-    public Response(OutputStream out) {
+    public Response(OutputStream out, boolean keepAlive) {
         this.out = out;
+        this.keepAlive = keepAlive;
     }
     
     /**
@@ -62,6 +70,8 @@ class Response implements Closeable {
             return "OK";
         case 400:
             return "Bad request";
+        case 401:
+            return "Unauthorized";
         case 404:
             return "Not found";
         default:
@@ -81,8 +91,8 @@ class Response implements Closeable {
             statusCode = 200;
         }
         String msg = getStatusMsg(statusCode);
-        if (statusCode != 200 && respOut == null) {
-            /* Generate standard message for errors */
+        if (respOut == null) {
+            /* Generate minimal body  */
             String body = String.format(
                     "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" +
                     "<html><head>" +
@@ -107,8 +117,20 @@ class Response implements Closeable {
         if (contentType != null) {
             writeLine(String.format("Content-Type: %s", contentType));
         }
-        writeLine("Connection: Close");
+        if (!keepAlive) {
+            writeLine("Connection: Close");
+        }
+        if (headers != null) {
+            for (Map.Entry<String, String> header : headers.entrySet()) {
+                writeLine(String.format("%s: %s", header.getKey(), header.getValue()));
+            }
+        }
+        
         writeLine("");
+        
+        if (out != null) {
+            out.flush();
+        }
     }
 
     public void close() throws IOException {
@@ -117,29 +139,43 @@ class Response implements Closeable {
         try {
             sendHeaders();
             IOUtils.closeQuietly(respOut);
+            
+            if (out != null) {
+                out.flush();
+            }
         } finally {
             out = null;
         }
     }
     
     private void writeLine(String s) throws IOException {
-        if (out != null) {
-            out.write(s.getBytes());
-            out.write("\r\n".getBytes());
+        if (out == null) {
+            return;
         }
+        out.write(s.getBytes());
+        out.write("\r\n".getBytes());
     }
 
-    private void writeChunk(byte[] b, int off, int len) throws IOException {
+    /**
+     * Write some bytes to the body of the response.
+     * @param b buffer
+     * @param off offset
+     * @param len length
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeBody(byte[] b, int off, int len) throws IOException {
+        if (out == null) {
+            return;
+        }
+
         sendHeaders();
 
-        if (out != null) {
-            if (chunked) {
-                out.write(String.format("%04X\r\n", len).getBytes());
-            }
-            out.write(b, off, len);
-            if (chunked) {
-                out.write(("\r\n").getBytes());
-            }
+        if (chunked) {
+            out.write(String.format("%04X\r\n", len).getBytes());
+        }
+        out.write(b, off, len);
+        if (chunked) {
+            out.write(("\r\n").getBytes());
         }
     }
     
@@ -158,6 +194,13 @@ class Response implements Closeable {
         this.statusCode = statusCode;
     }
     
+    public void addHeader(String name, String value) {
+        if (headers == null) {
+            headers = new LinkedHashMap<String, String>();
+        }
+        headers.put(name, value);
+    }
+    
     public void write(String s) throws IOException {
         getOutputStream().write(s.getBytes("8859_1"));
     }
@@ -167,9 +210,13 @@ class Response implements Closeable {
      */
     private class BodyOutputStream extends OutputStream {
         
-        private final byte[] buf = new byte[8192];
+        /**
+         * Buffer size chosen intentionally to need exceed maximum chunk
+         * size we'd like to transmit.
+         */
+        private final byte[] buf = new byte[0xFFFF];
         
-        private int count;
+        private int offset;
 
         /**
          * Return the number of valid bytes in the buffer.
@@ -177,39 +224,38 @@ class Response implements Closeable {
          * @return number of bytes 
          */
         public int getCount() {
-            return count;
+            return offset;
         }
 
         @Override
         public void write(int b) throws IOException {
-            if (count == buf.length) {
-                writeChunk(buf, 0, count);
-                count = 0;
+            if (offset == buf.length) {
+                writeBody(buf, 0, offset);
+                offset = 0;
             }
-            buf[count++] = (byte) b;
+            buf[offset++] = (byte) b;
         }
 
         @Override
         public void write(byte[] b, int off, int len) throws IOException {
-            if (len + count > buf.length) {
-                if (count > 0) {
-                    writeChunk(buf, 0, count);
-                    count = 0;
+            int count = 0;
+            while (count < len) {
+                if (offset == buf.length) {
+                    writeBody(buf, 0, offset);
+                    offset = 0;
                 }
-            }
-            if (len > buf.length) {
-                writeChunk(b, off, len);
-            } else {
-                System.arraycopy(b, off, buf, count, len);
-                count += len;
+                int n = Math.min(len - count, buf.length - offset);
+                System.arraycopy(b, off + count, buf, offset, n);
+                count += n;
+                offset += n;
             }
         }
         
         @Override
         public void flush() throws IOException {
-            if (count > 0) {
-                writeChunk(buf, 0, count);
-                count = 0;
+            if (offset > 0) {
+                writeBody(buf, 0, offset);
+                offset = 0;
             }
         }
         
@@ -217,7 +263,7 @@ class Response implements Closeable {
         public void close() throws IOException {
             flush();
             
-            writeChunk(buf, 0, 0);
+            writeBody(buf, 0, 0);
         }
     }
 }

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java?rev=1171142&r1=1171141&r2=1171142&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java
(original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java
Thu Sep 15 15:36:48 2011
@@ -16,9 +16,11 @@
  */
 package org.apache.jackrabbit.mk.server;
 
+import java.io.EOFException;
 import java.io.IOException;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.SocketTimeoutException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -79,8 +81,8 @@ public class Server {
         if (!started.compareAndSet(false, true)) {
             return;
         }
-        ss = new ServerSocket(port);
-        es = Executors.newFixedThreadPool(10);
+        ss = createServerSocket();
+        es = createExecutorService();
         
         new Thread(new Runnable() {
             public void run() {
@@ -95,11 +97,20 @@ public class Server {
                     }
                 } catch (IOException e) {
                     /* ignore */
+                    e.printStackTrace();
                 }
             }
         }, "Acceptor").start();
     }
     
+    private ServerSocket createServerSocket() throws IOException {
+        return new ServerSocket(port);
+    }
+    
+    private ExecutorService createExecutorService() {
+        return Executors.newFixedThreadPool(10);
+    }
+    
     /**
      * Handle a connection attempt by a client.
      * 
@@ -111,10 +122,17 @@ public class Server {
         } catch (IOException e) {
             /* ignore */
         }
+
+        HttpProcessor processor = new HttpProcessor(socket, new ServletImpl());
+
         try {
-            new HttpProcessor(socket, new ServletImpl()).process();
-        } catch (IOException e) {
+            processor.process();
+        } catch (SocketTimeoutException e) {
             /* ignore */
+        } catch (EOFException e) {
+            /* ignore */
+        } catch (IOException e) {
+            e.printStackTrace();
         }
     }
     



Mime
View raw message