You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2011/09/08 17:49:43 UTC
svn commit: r1166763 - in
/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk:
server/ server/Server.java server/SocketHandler.java util/IOUtils.java
Author: dpfister
Date: Thu Sep 8 15:49:42 2011
New Revision: 1166763
URL: http://svn.apache.org/viewvc?rev=1166763&view=rev
Log:
HTTP interface to microkernel
Added:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java (with props)
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/SocketHandler.java (with props)
Modified:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/IOUtils.java
Added: 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=1166763&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java Thu Sep 8 15:49:42 2011
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.mk.server;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.jackrabbit.mk.MicroKernelFactory;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+
+/**
+ * Server exposing a <code>MicroKernel</code>.
+ */
+public class Server {
+
+ private AtomicReference<MicroKernel> mk;
+ private AtomicBoolean started = new AtomicBoolean();
+ private AtomicBoolean stopped = new AtomicBoolean();
+ private ServerSocket ss;
+ private ExecutorService es;
+
+ public Server(MicroKernel mk) {
+ this.mk = new AtomicReference<MicroKernel>(mk);
+ }
+
+ public void start() throws IOException {
+ if (!started.compareAndSet(false, true)) {
+ return;
+ }
+ ss = new ServerSocket(28080);
+ es = Executors.newFixedThreadPool(10);
+
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ while (!stopped.get()) {
+ final Socket s = ss.accept();
+ es.execute(new Runnable() {
+ public void run() {
+ handle(s);
+ }
+ });
+ }
+ } catch (IOException e) {
+ /* ignore */
+ }
+ }
+ }, "Acceptor").start();
+ }
+
+ void handle(Socket s) {
+ try {
+ s.setTcpNoDelay(true);
+ } catch (IOException e) {
+ /* ignore */
+ }
+ try {
+ new SocketHandler(s).process();
+ } catch (IOException e) {
+ /* ignore */
+ }
+ }
+
+ public void stop() {
+ if (!stopped.compareAndSet(false, true)) {
+ return;
+ }
+ MicroKernel mk = this.mk.getAndSet(null);
+ if (mk != null) {
+ mk.dispose();
+ }
+ if (es != null) {
+ es.shutdown();
+ }
+ if (ss != null) {
+ try {
+ ss.close();
+ } catch (IOException e) {
+ /* ignore */
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (args.length == 0) {
+ System.out.println(String.format("usage: %s microkernel-url",
+ Server.class.getName()));
+ return;
+ }
+
+ MicroKernel mk = MicroKernelFactory.getInstance(args[0]);
+
+ final Server server = new Server(mk);
+ server.start();
+
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+ public void run() {
+ server.stop();
+ }
+ }, "ShutdownHook"));
+ }
+}
Propchange: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/SocketHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/SocketHandler.java?rev=1166763&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/SocketHandler.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/SocketHandler.java Thu Sep 8 15:49:42 2011
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.mk.server;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.Socket;
+
+import org.apache.jackrabbit.mk.util.IOUtils;
+
+/**
+ * Socket handler for HTTP requests directed at a server.
+ */
+class SocketHandler {
+
+ private final Socket sock;
+ private boolean keepAlive;
+ private BufferedInputStream in;
+ private BufferedOutputStream out;
+ private int sc;
+ private String ctype;
+ private StringBuilder body;
+
+ public SocketHandler(Socket sock) {
+ this.sock = sock;
+ }
+
+ public void process() throws IOException {
+ in = new BufferedInputStream(sock.getInputStream());
+ out = new BufferedOutputStream(sock.getOutputStream());
+ body = new StringBuilder();
+
+ do {
+ String requestLine = readLine();
+ for (;;) {
+ String header = readLine();
+ if (header.length() == 0) {
+ break;
+ }
+ }
+ try {
+ // TODO handle
+
+ sendNotFound();
+ } finally {
+ sendHeaders();
+ }
+
+ } while (keepAlive);
+
+ IOUtils.closeQuietly(out);
+ IOUtils.closeQuietly(in);
+ IOUtils.closeQuietly(sock);
+ }
+
+ private String readLine() throws IOException {
+ StringBuilder line = new StringBuilder(128);
+
+ for (;;) {
+ int c = in.read();
+ switch (c) {
+ case '\r':
+ break;
+ case '\n':
+ return line.toString();
+ case -1:
+ throw new EOFException();
+ default:
+ line.append((char) c);
+ }
+ }
+ }
+
+ private void sendNotFound() throws IOException {
+ sc = 404;
+
+ body.append("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" +
+ "<html><head>" +
+ "<title>404 Not Found</title>" +
+ "</head><body>" +
+ "<h1>Not Found</h1>" +
+ "<p>The requested URL /test.html was not found on this server.</p>" +
+ "</body></html>");
+ }
+
+ private void sendHeaders() throws IOException {
+ String msg = (sc == 404 ? "Not found" : "OK");
+
+ writeLine(String.format("HTTP/1.1 %d %s", sc, msg));
+ writeLine(String.format("Content-Length: %d", body.length()));
+ if (!keepAlive) {
+ writeLine("Connection: Close");
+ }
+ writeLine("");
+ out.write(body.toString().getBytes());
+ }
+
+ private void writeLine(String s) throws IOException {
+ out.write(s.getBytes());
+ out.write("\r\n".getBytes());
+ }
+}
Propchange: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/SocketHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/SocketHandler.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/IOUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/IOUtils.java?rev=1166763&r1=1166762&r2=1166763&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/IOUtils.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/IOUtils.java Thu Sep 8 15:49:42 2011
@@ -16,10 +16,12 @@
*/
package org.apache.jackrabbit.mk.util;
+import java.io.Closeable;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.Socket;
/**
* Input/output utility methods.
@@ -237,4 +239,39 @@ public class IOUtils {
return (int) i;
}
+ /**
+ * Unconditionally close a <code>Closeable</code>.
+ * <p>
+ * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
+ * This is typically used in finally blocks.
+ *
+ * @param closeable the object to close, may be null or already closed
+ */
+ public static void closeQuietly(Closeable closeable) {
+ try {
+ if (closeable != null) {
+ closeable.close();
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ /**
+ * Unconditionally close a <code>Socket</code>.
+ * <p>
+ * Equivalent to {@link Socket#close()}, except any exceptions will be ignored.
+ * This is typically used in finally blocks.
+ *
+ * @param sock the Socket to close, may be null or already closed
+ */
+ public static void closeQuietly(Socket sock){
+ if (sock != null){
+ try {
+ sock.close();
+ } catch (IOException ioe) {
+ // ignored
+ }
+ }
+ }
}