|
From: <ls...@us...> - 2007-06-25 08:14:02
|
Revision: 3303
http://jnode.svn.sourceforge.net/jnode/?rev=3303&view=rev
Author: lsantha
Date: 2007-06-25 01:14:00 -0700 (Mon, 25 Jun 2007)
Log Message:
-----------
Openjdk integration.
Added Paths:
-----------
trunk/core/src/openjdk/com/com/sun/net/
trunk/core/src/openjdk/com/com/sun/net/httpserver/
trunk/core/src/openjdk/com/com/sun/net/httpserver/Authenticator.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/BasicAuthenticator.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/Filter.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/Headers.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpContext.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpExchange.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpHandler.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpPrincipal.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpServer.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpsConfigurator.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpsExchange.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpsParameters.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpsServer.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/package-info.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/spi/
trunk/core/src/openjdk/com/com/sun/net/httpserver/spi/HttpServerProvider.java
trunk/core/src/openjdk/com/com/sun/net/httpserver/spi/package-info.java
trunk/core/src/openjdk/com/com/sun/net/ssl/
trunk/core/src/openjdk/com/com/sun/net/ssl/HostnameVerifier.java
trunk/core/src/openjdk/com/com/sun/net/ssl/HttpsURLConnection.java
trunk/core/src/openjdk/com/com/sun/net/ssl/KeyManager.java
trunk/core/src/openjdk/com/com/sun/net/ssl/KeyManagerFactory.java
trunk/core/src/openjdk/com/com/sun/net/ssl/KeyManagerFactorySpi.java
trunk/core/src/openjdk/com/com/sun/net/ssl/SSLContextSpi.java
trunk/core/src/openjdk/com/com/sun/net/ssl/SSLPermission.java
trunk/core/src/openjdk/com/com/sun/net/ssl/SSLSecurity.java
trunk/core/src/openjdk/com/com/sun/net/ssl/TrustManager.java
trunk/core/src/openjdk/com/com/sun/net/ssl/TrustManagerFactory.java
trunk/core/src/openjdk/com/com/sun/net/ssl/TrustManagerFactorySpi.java
trunk/core/src/openjdk/com/com/sun/net/ssl/X509KeyManager.java
trunk/core/src/openjdk/com/com/sun/net/ssl/X509TrustManager.java
trunk/core/src/openjdk/com/com/sun/net/ssl/internal/
trunk/core/src/openjdk/com/com/sun/net/ssl/internal/ssl/
trunk/core/src/openjdk/com/com/sun/net/ssl/internal/ssl/X509ExtendedTrustManager.java
trunk/core/src/openjdk/com/com/sun/net/ssl/package.html
Added: trunk/core/src/openjdk/com/com/sun/net/httpserver/Authenticator.java
===================================================================
--- trunk/core/src/openjdk/com/com/sun/net/httpserver/Authenticator.java (rev 0)
+++ trunk/core/src/openjdk/com/com/sun/net/httpserver/Authenticator.java 2007-06-25 08:14:00 UTC (rev 3303)
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Authenticator represents an implementation of an HTTP authentication
+ * mechanism. Sub-classes provide implementations of specific mechanisms
+ * such as Digest or Basic auth. Instances are invoked to provide verification
+ * of the authentication information provided in all incoming requests.
+ * Note. This implies that any caching of credentials or other authentication
+ * information must be done outside of this class.
+ */
+public abstract class Authenticator {
+
+ /**
+ * Base class for return type from authenticate() method
+ */
+ public abstract static class Result {}
+
+ /**
+ * Indicates an authentication failure. The authentication
+ * attempt has completed.
+ */
+ public static class Failure extends Result {
+
+ private int responseCode;
+
+ public Failure (int responseCode) {
+ this.responseCode = responseCode;
+ }
+
+ /**
+ * returns the response code to send to the client
+ */
+ public int getResponseCode() {
+ return responseCode;
+ }
+ }
+
+ /**
+ * Indicates an authentication has succeeded and the
+ * authenticated user principal can be acquired by calling
+ * getPrincipal().
+ */
+ public static class Success extends Result {
+ private HttpPrincipal principal;
+
+ public Success (HttpPrincipal p) {
+ principal = p;
+ }
+ /**
+ * returns the authenticated user Principal
+ */
+ public HttpPrincipal getPrincipal() {
+ return principal;
+ }
+ }
+
+ /**
+ * Indicates an authentication must be retried. The
+ * response code to be sent back is as returned from
+ * getResponseCode(). The Authenticator must also have
+ * set any necessary response headers in the given HttpExchange
+ * before returning this Retry object.
+ */
+ public static class Retry extends Result {
+
+ private int responseCode;
+
+ public Retry (int responseCode) {
+ this.responseCode = responseCode;
+ }
+
+ /**
+ * returns the response code to send to the client
+ */
+ public int getResponseCode() {
+ return responseCode;
+ }
+ }
+
+ /**
+ * called to authenticate each incoming request. The implementation
+ * must return a Failure, Success or Retry object as appropriate :-
+ * <p>
+ * Failure means the authentication has completed, but has failed
+ * due to invalid credentials.
+ * <p>
+ * Sucess means that the authentication
+ * has succeeded, and a Principal object representing the user
+ * can be retrieved by calling Sucess.getPrincipal() .
+ * <p>
+ * Retry means that another HTTP exchange is required. Any response
+ * headers needing to be sent back to the client are set in the
+ * given HttpExchange. The response code to be returned must be provided
+ * in the Retry object. Retry may occur multiple times.
+ */
+ public abstract Result authenticate (HttpExchange exch);
+}
+
Added: trunk/core/src/openjdk/com/com/sun/net/httpserver/BasicAuthenticator.java
===================================================================
--- trunk/core/src/openjdk/com/com/sun/net/httpserver/BasicAuthenticator.java (rev 0)
+++ trunk/core/src/openjdk/com/com/sun/net/httpserver/BasicAuthenticator.java 2007-06-25 08:14:00 UTC (rev 3303)
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * BasicAuthenticator provides an implementation of HTTP Basic
+ * authentication. It is an abstract class and must be extended
+ * to provide an implementation of {@link #checkCredentials(String,String)}
+ * which is called to verify each incoming request.
+ */
+public abstract class BasicAuthenticator extends Authenticator {
+
+ protected String realm;
+
+ /**
+ * Creates a BasicAuthenticator for the given HTTP realm
+ * @param realm The HTTP Basic authentication realm
+ * @throws NullPointerException if the realm is an empty string
+ */
+ public BasicAuthenticator (String realm) {
+ this.realm = realm;
+ }
+
+ /**
+ * returns the realm this BasicAuthenticator was created with
+ * @return the authenticator's realm string.
+ */
+ public String getRealm () {
+ return realm;
+ }
+
+ public Result authenticate (HttpExchange t)
+ {
+ HttpContext context = t.getHttpContext();
+ Headers rmap = (Headers) t.getRequestHeaders();
+ /*
+ * look for auth token
+ */
+ String auth = rmap.getFirst ("Authorization");
+ if (auth == null) {
+ Headers map = (Headers) t.getResponseHeaders();
+ map.set ("WWW-Authenticate", "Basic realm=" + "\""+realm+"\"");
+ return new Authenticator.Retry (401);
+ }
+ int sp = auth.indexOf (' ');
+ if (sp == -1 || !auth.substring(0, sp).equals ("Basic")) {
+ return new Authenticator.Failure (401);
+ }
+ byte[] b = Base64.base64ToByteArray (auth.substring(sp+1));
+ String userpass = new String (b);
+ int colon = userpass.indexOf (':');
+ String uname = userpass.substring (0, colon);
+ String pass = userpass.substring (colon+1);
+
+ if (checkCredentials (uname, pass)) {
+ return new Authenticator.Success (
+ new HttpPrincipal (
+ uname, realm
+ )
+ );
+ } else {
+ /* reject the request again with 401 */
+
+ Headers map = (Headers) t.getResponseHeaders();
+ map.set ("WWW-Authenticate", "Basic realm=" + "\""+realm+"\"");
+ return new Authenticator.Failure(401);
+ }
+ }
+
+ /**
+ * called for each incoming request to verify the
+ * given name and password in the context of this
+ * Authenticator's realm. Any caching of credentials
+ * must be done by the implementation of this method
+ * @param username the username from the request
+ * @param password the password from the request
+ * @return <code>true</code> if the credentials are valid,
+ * <code>false</code> otherwise.
+ */
+ public abstract boolean checkCredentials (String username, String password);
+}
+
+class Base64 {
+
+ /**
+ * Translates the specified byte array into a Base64 string as per
+ * Preferences.put(byte[]).
+ */
+ static String byteArrayToBase64(byte[] a) {
+ return byteArrayToBase64(a, false);
+ }
+
+ /**
+ * Translates the specified byte array into an "aternate representation"
+ * Base64 string. This non-standard variant uses an alphabet that does
+ * not contain the uppercase alphabetic characters, which makes it
+ * suitable for use in situations where case-folding occurs.
+ */
+ static String byteArrayToAltBase64(byte[] a) {
+ return byteArrayToBase64(a, true);
+ }
+
+ private static String byteArrayToBase64(byte[] a, boolean alternate) {
+ int aLen = a.length;
+ int numFullGroups = aLen/3;
+ int numBytesInPartialGroup = aLen - 3*numFullGroups;
+ int resultLen = 4*((aLen + 2)/3);
+ StringBuffer result = new StringBuffer(resultLen);
+ char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64);
+
+ // Translate all full groups from byte array elements to Base64
+ int inCursor = 0;
+ for (int i=0; i<numFullGroups; i++) {
+ int byte0 = a[inCursor++] & 0xff;
+ int byte1 = a[inCursor++] & 0xff;
+ int byte2 = a[inCursor++] & 0xff;
+ result.append(intToAlpha[byte0 >> 2]);
+ result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
+ result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
+ result.append(intToAlpha[byte2 & 0x3f]);
+ }
+
+ // Translate partial group if present
+ if (numBytesInPartialGroup != 0) {
+ int byte0 = a[inCursor++] & 0xff;
+ result.append(intToAlpha[byte0 >> 2]);
+ if (numBytesInPartialGroup == 1) {
+ result.append(intToAlpha[(byte0 << 4) & 0x3f]);
+ result.append("==");
+ } else {
+ // assert numBytesInPartialGroup == 2;
+ int byte1 = a[inCursor++] & 0xff;
+ result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
+ result.append(intToAlpha[(byte1 << 2)&0x3f]);
+ result.append('=');
+ }
+ }
+ // assert inCursor == a.length;
+ // assert result.length() == resultLen;
+ return result.toString();
+ }
+
+ /**
+ * This array is a lookup table that translates 6-bit positive integer
+ * index values into their "Base64 Alphabet" equivalents as specified
+ * in Table 1 of RFC 2045.
+ */
+ private static final char intToBase64[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+ };
+
+ /**
+ * This array is a lookup table that translates 6-bit positive integer
+ * index values into their "Alternate Base64 Alphabet" equivalents.
+ * This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045.
+ * This alternate alphabet does not use the capital letters. It is
+ * designed for use in environments where "case folding" occurs.
+ */
+ private static final char intToAltBase64[] = {
+ '!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':',
+ ';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?'
+ };
+
+ /**
+ * Translates the specified Base64 string (as per Preferences.get(byte[]))
+ * into a byte array.
+ *
+ * @throw IllegalArgumentException if <tt>s</tt> is not a valid Base64
+ * string.
+ */
+ static byte[] base64ToByteArray(String s) {
+ return base64ToByteArray(s, false);
+ }
+
+ /**
+ * Translates the specified "aternate representation" Base64 string
+ * into a byte array.
+ *
+ * @throw IllegalArgumentException or ArrayOutOfBoundsException
+ * if <tt>s</tt> is not a valid alternate representation
+ * Base64 string.
+ */
+ static byte[] altBase64ToByteArray(String s) {
+ return base64ToByteArray(s, true);
+ }
+
+ private static byte[] base64ToByteArray(String s, boolean alternate) {
+ byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt);
+ int sLen = s.length();
+ int numGroups = sLen/4;
+ if (4*numGroups != sLen)
+ throw new IllegalArgumentException(
+ "String length must be a multiple of four.");
+ int missingBytesInLastGroup = 0;
+ int numFullGroups = numGroups;
+ if (sLen != 0) {
+ if (s.charAt(sLen-1) == '=') {
+ missingBytesInLastGroup++;
+ numFullGroups--;
+ }
+ if (s.charAt(sLen-2) == '=')
+ missingBytesInLastGroup++;
+ }
+ byte[] result = new byte[3*numGroups - missingBytesInLastGroup];
+
+ // Translate all full groups from base64 to byte array elements
+ int inCursor = 0, outCursor = 0;
+ for (int i=0; i<numFullGroups; i++) {
+ int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
+ int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
+ int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
+ int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt);
+ result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
+ result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
+ result[outCursor++] = (byte) ((ch2 << 6) | ch3);
+ }
+
+ // Translate partial group, if present
+ if (missingBytesInLastGroup != 0) {
+ int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
+ int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
+ result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
+
+ if (missingBytesInLastGroup == 1) {
+ int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
+ result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
+ }
+ }
+ // assert inCursor == s.length()-missingBytesInLastGroup;
+ // assert outCursor == result.length;
+ return result;
+ }
+
+ /**
+ * Translates the specified character, which is assumed to be in the
+ * "Base 64 Alphabet" into its equivalent 6-bit positive integer.
+ *
+ * @throw IllegalArgumentException or ArrayOutOfBoundsException if
+ * c is not in the Base64 Alphabet.
+ */
+ private static int base64toInt(char c, byte[] alphaToInt) {
+ int result = alphaToInt[c];
+ if (result < 0)
+ throw new IllegalArgumentException("Illegal character " + c);
+ return result;
+ }
+
+ /**
+ * This array is a lookup table that translates unicode characters
+ * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
+ * into their 6-bit positive integer equivalents. Characters that
+ * are not in the Base64 alphabet but fall within the bounds of the
+ * array are translated to -1.
+ */
+ private static final byte base64ToInt[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
+ };
+
+ /**
+ * This array is the analogue of base64ToInt, but for the nonstandard
+ * variant that avoids the use of uppercase alphabetic characters.
+ */
+ private static final byte altBase64ToInt[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, -1, 62, 9, 10, 11, -1 , 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 12, 13, 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 17, -1, 18, 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 22, 23, 24, 25
+ };
+
+}
Added: trunk/core/src/openjdk/com/com/sun/net/httpserver/Filter.java
===================================================================
--- trunk/core/src/openjdk/com/com/sun/net/httpserver/Filter.java (rev 0)
+++ trunk/core/src/openjdk/com/com/sun/net/httpserver/Filter.java 2007-06-25 08:14:00 UTC (rev 3303)
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+
+import java.net.*;
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import sun.net.www.MessageHeader;
+import java.util.*;
+
+/**
+ * A filter used to pre- and post-process incoming requests. Pre-processing occurs
+ * before the application's exchange handler is invoked, and post-processing
+ * occurs after the exchange handler returns. Filters
+ * are organised in chains, and are associated with HttpContext instances.
+ * <p>
+ * Each Filter in the chain, invokes the next filter within its own
+ * doFilter() implementation. The final Filter in the chain invokes the applications
+ * exchange handler.
+ * @since 1.6
+ */
+public abstract class Filter {
+
+ protected Filter () {}
+
+ /**
+ * a chain of filters associated with a HttpServer.
+ * Each filter in the chain is given one of these
+ * so it can invoke the next filter in the chain
+ */
+ public static class Chain {
+ /* the last element in the chain must invoke the users
+ * handler
+ */
+ private List<Filter> filters;
+ private ListIterator<Filter> iter;
+ private HttpHandler handler;
+
+ public Chain (List<Filter> filters, HttpHandler handler) {
+ this.filters = filters;
+ iter = filters.listIterator();
+ this.handler = handler;
+ }
+
+ /**
+ * calls the next filter in the chain, or else
+ * the users exchange handler, if this is the
+ * final filter in the chain. The Filter may decide
+ * to terminate the chain, by not calling this method.
+ * In this case, the filter <b>must</b> send the
+ * response to the request, because the application's
+ * exchange handler will not be invoked.
+ * @param exchange the HttpExchange
+ * @throws IOException let exceptions pass up the stack
+ * @throws NullPointerException if exchange is <code>null</code>
+ */
+ public void doFilter (HttpExchange exchange) throws IOException {
+ if (!iter.hasNext()) {
+ handler.handle (exchange);
+ } else {
+ Filter f = iter.next();
+ f.doFilter (exchange, this);
+ }
+ }
+ }
+
+ /**
+ * Asks this filter to pre/post-process the given exchange. The filter
+ * can :-
+ * <ul><li>examine or modify the request headers</li>
+ * <li>filter the request body or the response body, by creating suitable
+ * filter streams and calling
+ * {@link HttpExchange#setStreams(InputStream,OutputStream)}</li>
+ * <li>set attribute Objects in the exchange, which other filters or the
+ * exchange handler can access.</li>
+ * <li>decide to either :-<ol>
+ * <li>invoke the next filter in the chain, by calling
+ * {@link Filter.Chain#doFilter(HttpExchange)}</li>
+ * <li>terminate the chain of invocation, by <b>not</b> calling
+ * {@link Filter.Chain#doFilter(HttpExchange)}</li></ol>
+ * <li>if option 1. above taken, then when doFilter() returns all subsequent
+ * filters in the Chain have been called, and the response headers can be
+ * examined or modified.</li>
+ * <li>if option 2. above taken, then this Filter must use the HttpExchange
+ * to send back an appropriate response</li></ul><p>
+ * @param exchange the <code>HttpExchange</code> to be filtered.
+ * @param chain the Chain which allows the next filter to be invoked.
+ * @throws IOException may be thrown by any filter module, and if
+ * caught, must be rethrown again.
+ * @throws NullPointerException if either exchange or chain are <code>null</code>
+ */
+ public abstract void doFilter (HttpExchange exchange, Chain chain)
+ throws IOException;
+
+ /**
+ * returns a short description of this Filter
+ * @return a string describing the Filter
+ */
+ public abstract String description ();
+
+}
Added: trunk/core/src/openjdk/com/com/sun/net/httpserver/Headers.java
===================================================================
--- trunk/core/src/openjdk/com/com/sun/net/httpserver/Headers.java (rev 0)
+++ trunk/core/src/openjdk/com/com/sun/net/httpserver/Headers.java 2007-06-25 08:14:00 UTC (rev 3303)
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * HTTP request and response headers are represented by this class which implements
+ * the interface {@link java.util.Map}<
+ * {@link java.lang.String},{@link java.util.List}<{@link java.lang.String}>>.
+ * The keys are case-insensitive Strings representing the header names and
+ * the value associated with each key is a {@link List}<{@link String}> with one
+ * element for each occurence of the header name in the request or response.
+ * <p>
+ * For example, if a response header instance contains one key "HeaderName" with two values "value1 and value2"
+ * then this object is output as two header lines:
+ * <blockquote><pre>
+ * HeaderName: value1
+ * HeaderName: value2
+ * </blockquote></pre>
+ * <p>
+ * All the normal {@link java.util.Map} methods are provided, but the following
+ * additional convenience methods are most likely to be used:
+ * <ul>
+ * <li>{@link #getFirst(String)} returns a single valued header or the first value of
+ * a multi-valued header.</li>
+ * <li>{@link #add(String,String)} adds the given header value to the list for the given key</li>
+ * <li>{@link #set(String,String)} sets the given header field to the single value given
+ * overwriting any existing values in the value list.
+ * </ul><p>
+ * All methods in this class accept <code>null</code> values for keys and values. However, null
+ * keys will never will be present in HTTP request headers, and will not be output/sent in response headers.
+ * Null values can be represented as either a null entry for the key (i.e. the list is null) or
+ * where the key has a list, but one (or more) of the list's values is null. Null values are output
+ * as a header line containing the key but no associated value.
+ * @since 1.6
+ */
+public class Headers implements Map<String,List<String>> {
+
+ HashMap<String,List<String>> map;
+
+ public Headers () {map = new HashMap<String,List<String>>(32);}
+
+ /* Normalize the key by converting to following form.
+ * First char upper case, rest lower case.
+ * key is presumed to be ASCII
+ */
+ private String normalize (String key) {
+ if (key == null) {
+ return null;
+ }
+ int len = key.length();
+ if (len == 0) {
+ return key;
+ }
+ char[] b = new char [len];
+ String s = null;
+ b = key.toCharArray();
+ if (b[0] >= 'a' && b[0] <= 'z') {
+ b[0] = (char)(b[0] - ('a' - 'A'));
+ }
+ for (int i=1; i<len; i++) {
+ if (b[i] >= 'A' && b[i] <= 'Z') {
+ b[i] = (char) (b[i] + ('a' - 'A'));
+ }
+ }
+ s = new String (b);
+ return s;
+ }
+
+ public int size() {return map.size();}
+
+ public boolean isEmpty() {return map.isEmpty();}
+
+ public boolean containsKey(Object key) {
+ if (key == null) {
+ return false;
+ }
+ if (!(key instanceof String)) {
+ return false;
+ }
+ return map.containsKey (normalize((String)key));
+ }
+
+ public boolean containsValue(Object value) {
+ return map.containsValue(value);
+ }
+
+ public List<String> get(Object key) {
+ return map.get(normalize((String)key));
+ }
+
+ /**
+ * returns the first value from the List of String values
+ * for the given key (if at least one exists).
+ * @param key the key to search for
+ * @return the first string value associated with the key
+ */
+ public String getFirst (String key) {
+ List<String> l = map.get(normalize((String)key));
+ if (l == null) {
+ return null;
+ }
+ return l.get(0);
+ }
+
+ public List<String> put(String key, List<String> value) {
+ return map.put (normalize(key), value);
+ }
+
+ /**
+ * adds the given value to the list of headers
+ * for the given key. If the mapping does not
+ * already exist, then it is created
+ * @param key the header name
+ * @param value the header value to add to the header
+ */
+ public void add (String key, String value) {
+ String k = normalize(key);
+ List<String> l = map.get(k);
+ if (l == null) {
+ l = new LinkedList<String>();
+ map.put(k,l);
+ }
+ l.add (value);
+ }
+
+ /**
+ * sets the given value as the sole header value
+ * for the given key. If the mapping does not
+ * already exist, then it is created
+ * @param key the header name
+ * @param value the header value to set.
+ */
+ public void set (String key, String value) {
+ LinkedList<String> l = new LinkedList<String>();
+ l.add (value);
+ put (key, l);
+ }
+
+
+ public List<String> remove(Object key) {
+ return map.remove(normalize((String)key));
+ }
+
+ public void putAll(Map<? extends String,? extends List<String>> t) {
+ map.putAll (t);
+ }
+
+ public void clear() {map.clear();}
+
+ public Set<String> keySet() {return map.keySet();}
+
+ public Collection<List<String>> values() {return map.values();}
+
+ public Set<Map.Entry<String, List<String>>> entrySet() {
+ return map.entrySet();
+ }
+
+ public boolean equals(Object o) {return map.equals(o);}
+
+ public int hashCode() {return map.hashCode();}
+ }
Added: trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpContext.java
===================================================================
--- trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpContext.java (rev 0)
+++ trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpContext.java 2007-06-25 08:14:00 UTC (rev 3303)
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * HttpContext represents a mapping between the root URI path of an application
+ * to a {@link HttpHandler} which is invoked to handle requests destined
+ * for that path on the associated HttpServer or HttpsServer.
+ * <p>
+ * HttpContext instances are created by the create methods in HttpServer
+ * and HttpsServer
+ * <p>
+ * A chain of {@link Filter} objects can be added to a HttpContext. All exchanges processed by the
+ * context can be pre- and post-processed by each Filter in the chain.
+ * @since 1.6
+ */
+public abstract class HttpContext {
+
+ protected HttpContext () {
+ }
+
+ /**
+ * returns the handler for this context
+ * @return the HttpHandler for this context
+ */
+ public abstract HttpHandler getHandler () ;
+
+ /**
+ * Sets the handler for this context, if not already set.
+ * @param h the handler to set for this context
+ * @throws IllegalArgumentException if this context's handler is already set.
+ * @throws NullPointerException if handler is <code>null</code>
+ */
+ public abstract void setHandler (HttpHandler h) ;
+
+ /**
+ * returns the path this context was created with
+ * @return this context's path
+ */
+ public abstract String getPath() ;
+
+ /**
+ * returns the server this context was created with
+ * @return this context's server
+ */
+ public abstract HttpServer getServer () ;
+
+ /**
+ * returns a mutable Map, which can be used to pass
+ * configuration and other data to Filter modules
+ * and to the context's exchange handler.
+ * <p>
+ * Every attribute stored in this Map will be visible to
+ * every HttpExchange processed by this context
+ */
+ public abstract Map<String,Object> getAttributes() ;
+
+ /**
+ * returns this context's list of Filters. This is the
+ * actual list used by the server when dispatching requests
+ * so modifications to this list immediately affect the
+ * the handling of exchanges.
+ */
+ public abstract List<Filter> getFilters();
+
+ /**
+ * Sets the Authenticator for this HttpContext. Once an authenticator
+ * is establised on a context, all client requests must be
+ * authenticated, and the given object will be invoked to validate each
+ * request. Each call to this method replaces any previous value set.
+ * @param auth the authenticator to set. If <code>null</code> then any
+ * previously set authenticator is removed,
+ * and client authentication will no longer be required.
+ * @return the previous Authenticator, if any set, or <code>null</code>
+ * otherwise.
+ */
+ public abstract Authenticator setAuthenticator (Authenticator auth);
+
+ /**
+ * Returns the currently set Authenticator for this context
+ * if one exists.
+ * @return this HttpContext's Authenticator, or <code>null</code>
+ * if none is set.
+ */
+ public abstract Authenticator getAuthenticator ();
+}
Added: trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpExchange.java
===================================================================
--- trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpExchange.java (rev 0)
+++ trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpExchange.java 2007-06-25 08:14:00 UTC (rev 3303)
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.net.*;
+import javax.net.ssl.*;
+import java.util.*;
+import sun.net.www.MessageHeader;
+
+/**
+ * This class encapsulates a HTTP request received and a
+ * response to be generated in one exchange. It provides methods
+ * for examining the request from the client, and for building and
+ * sending the response.
+ * <p>
+ * The typical life-cycle of a HttpExchange is shown in the sequence
+ * below.
+ * <ol><li>{@link #getRequestMethod()} to determine the command
+ * <li>{@link #getRequestHeaders()} to examine the request headers (if needed)
+ * <li>{@link #getRequestBody()} returns a {@link java.io.InputStream} for reading the request body.
+ * After reading the request body, the stream is close.
+ * <li>{@link #getResponseHeaders()} to set any response headers, except content-length
+ * <li>{@link #sendResponseHeaders(int,long)} to send the response headers. Must be called before
+ * next step.
+ * <li>{@link #getResponseBody()} to get a {@link java.io.OutputStream} to send the response body.
+ * When the response body has been written, the stream must be closed to terminate the exchange.
+ * </ol>
+ * <b>Terminating exchanges</b>
+ * <br>
+ * Exchanges are terminated when both the request InputStream and response OutputStream are closed.
+ * Closing the OutputStream, implicitly closes the InputStream (if it is not already closed).
+ * However, it is recommended
+ * to consume all the data from the InputStream before closing it.
+ * The convenience method {@link #close()} does all of these tasks.
+ * Closing an exchange without consuming all of the request body is not an error
+ * but may make the underlying TCP connection unusable for following exchanges.
+ * The effect of failing to terminate an exchange is undefined, but will typically
+ * result in resources failing to be freed/reused.
+ * @since 1.6
+ */
+
+public abstract class HttpExchange {
+
+ protected HttpExchange () {
+ }
+
+ /**
+ * Returns an immutable Map containing the HTTP headers that were
+ * included with this request. The keys in this Map will be the header
+ * names, while the values will be a List of Strings containing each value
+ * that was included (either for a header that was listed several times,
+ * or one that accepts a comma-delimited list of values on a single line).
+ * In either of these cases, the values for the header name will be
+ * presented in the order that they were included in the request.
+ * <p>
+ * The keys in Map are case-insensitive.
+ * @return a read-only Map which can be used to access request headers
+ */
+ public abstract Headers getRequestHeaders () ;
+
+ /**
+ * Returns a mutable Map into which the HTTP response headers can be stored
+ * and which will be transmitted as part of this response. The keys in the
+ * Map will be the header names, while the values must be a List of Strings
+ * containing each value that should be included multiple times
+ * (in the order that they should be included).
+ * <p>
+ * The keys in Map are case-insensitive.
+ * @return a writable Map which can be used to set response headers.
+ */
+ public abstract Headers getResponseHeaders () ;
+
+ /**
+ * Get the request URI
+ *
+ * @return the request URI
+ */
+ public abstract URI getRequestURI () ;
+
+ /**
+ * Get the request method
+ * @return the request method
+ */
+ public abstract String getRequestMethod ();
+
+ /**
+ * Get the HttpContext for this exchange
+ * @return the HttpContext
+ */
+ public abstract HttpContext getHttpContext ();
+
+ /**
+ * Ends this exchange by doing the following in sequence:<p><ol>
+ * <li>close the request InputStream, if not already closed<p></li>
+ * <li>close the response OutputStream, if not already closed. </li>
+ * </ol>
+ */
+ public abstract void close () ;
+
+ /**
+ * returns a stream from which the request body can be read.
+ * Multiple calls to this method will return the same stream.
+ * It is recommended that applications should consume (read) all of the
+ * data from this stream before closing it. If a stream is closed
+ * before all data has been read, then the close() call will
+ * read and discard remaining data (up to an implementation specific
+ * number of bytes).
+ * @return the stream from which the request body can be read.
+ */
+ public abstract InputStream getRequestBody () ;
+
+ /**
+ * returns a stream to which the response body must be
+ * written. {@link #sendResponseHeaders(int,long)}) must be called prior to calling
+ * this method. Multiple calls to this method (for the same exchange)
+ * will return the same stream. In order to correctly terminate
+ * each exchange, the output stream must be closed, even if no
+ * response body is being sent.
+ * <p>
+ * Closing this stream implicitly
+ * closes the InputStream returned from {@link #getRequestBody()}
+ * (if it is not already closed).
+ * <P>
+ * If the call to sendResponseHeaders() specified a fixed response
+ * body length, then the exact number of bytes specified in that
+ * call must be written to this stream. If too many bytes are written,
+ * then write() will throw an IOException. If too few bytes are written
+ * then the stream close() will throw an IOException. In both cases,
+ * the exchange is aborted and the underlying TCP connection closed.
+ * @return the stream to which the response body is written
+ */
+ public abstract OutputStream getResponseBody () ;
+
+
+ /**
+ * Starts sending the response back to the client using the current set of response headers
+ * and the numeric response code as specified in this method. The response body length is also specified
+ * as follows. If the response length parameter is greater than zero, this specifies an exact
+ * number of bytes to send and the application must send that exact amount of data.
+ * If the response length parameter is <code>zero</code>, then chunked transfer encoding is
+ * used and an arbitrary amount of data may be sent. The application terminates the
+ * response body by closing the OutputStream. If response length has the value <code>-1</code>
+ * then no response body is being sent.
+ * <p>
+ * If the content-length response header has not already been set then
+ * this is set to the apropriate value depending on the response length parameter.
+ * <p>
+ * This method must be called prior to calling {@link #getResponseBody()}.
+ * @param rCode the response code to send
+ * @param responseLength if > 0, specifies a fixed response body length
+ * and that exact number of bytes must be written
+ * to the stream acquired from getResponseBody(), or else
+ * if equal to 0, then chunked encoding is used,
+ * and an arbitrary number of bytes may be written.
+ * if <= -1, then no response body length is specified and
+ * no response body may be written.
+ * @see HttpExchange#getResponseBody()
+ */
+ public abstract void sendResponseHeaders (int rCode, long responseLength) throws IOException ;
+
+ /**
+ * Returns the address of the remote entity invoking this request
+ * @return the InetSocketAddress of the caller
+ */
+ public abstract InetSocketAddress getRemoteAddress ();
+
+ /**
+ * Returns the response code, if it has already been set
+ * @return the response code, if available. <code>-1</code> if not available yet.
+ */
+ public abstract int getResponseCode ();
+
+ /**
+ * Returns the local address on which the request was received
+ * @return the InetSocketAddress of the local interface
+ */
+ public abstract InetSocketAddress getLocalAddress ();
+
+ /**
+ * Returns the protocol string from the request in the form
+ * <i>protocol/majorVersion.minorVersion</i>. For example,
+ * "HTTP/1.1"
+ * @return the protocol string from the request
+ */
+ public abstract String getProtocol ();
+
+ /**
+ * Filter modules may store arbitrary objects with HttpExchange
+ * instances as an out-of-band communication mechanism. Other Filters
+ * or the exchange handler may then access these objects.
+ * <p>
+ * Each Filter class will document the attributes which they make
+ * available.
+ * @param name the name of the attribute to retrieve
+ * @return the attribute object, or null if it does not exist
+ * @throws NullPointerException if name is <code>null</code>
+ */
+ public abstract Object getAttribute (String name) ;
+
+ /**
+ * Filter modules may store arbitrary objects with HttpExchange
+ * instances as an out-of-band communication mechanism. Other Filters
+ * or the exchange handler may then access these objects.
+ * <p>
+ * Each Filter class will document the attributes which they make
+ * available.
+ * @param name the name to associate with the attribute value
+ * @param value the object to store as the attribute value. <code>null</code>
+ * value is permitted.
+ * @throws NullPointerException if name is <code>null</code>
+ */
+ public abstract void setAttribute (String name, Object value) ;
+
+ /**
+ * Used by Filters to wrap either (or both) of this exchange's InputStream
+ * and OutputStream, with the given filtered streams so
+ * that subsequent calls to {@link #getRequestBody()} will
+ * return the given {@link java.io.InputStream}, and calls to
+ * {@link #getResponseBody()} will return the given
+ * {@link java.io.OutputStream}. The streams provided to this
+ * call must wrap the original streams, and may be (but are not
+ * required to be) sub-classes of {@link java.io.FilterInputStream}
+ * and {@link java.io.FilterOutputStream}.
+ * @param i the filtered input stream to set as this object's inputstream,
+ * or <code>null</code> if no change.
+ * @param o the filtered output stream to set as this object's outputstream,
+ * or <code>null</code> if no change.
+ */
+ public abstract void setStreams (InputStream i, OutputStream o);
+
+
+ /**
+ * If an authenticator is set on the HttpContext that owns this exchange,
+ * then this method will return the {@link HttpPrincipal} that represents
+ * the authenticated user for this HttpExchange.
+ * @return the HttpPrincipal, or <code>null</code> if no authenticator is set.
+ */
+ public abstract HttpPrincipal getPrincipal ();
+}
Added: trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpHandler.java
===================================================================
--- trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpHandler.java (rev 0)
+++ trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpHandler.java 2007-06-25 08:14:00 UTC (rev 3303)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+
+import java.io.IOException;
+
+/**
+ * A handler which is invoked to process HTTP exchanges. Each
+ * HTTP exchange is handled by one of these handlers.
+ * @since 1.6
+ */
+public interface HttpHandler {
+ /**
+ * Handle the given request and generate an appropriate response.
+ * See {@link HttpExchange} for a description of the steps
+ * involved in handling an exchange.
+ * @param exchange the exchange containing the request from the
+ * client and used to send the response
+ * @throws NullPointerException if exchange is <code>null</code>
+ */
+ public abstract void handle (HttpExchange exchange) throws IOException;
+}
Added: trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpPrincipal.java
===================================================================
--- trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpPrincipal.java (rev 0)
+++ trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpPrincipal.java 2007-06-25 08:14:00 UTC (rev 3303)
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.security.Principal;
+
+/**
+ * Represents a user authenticated by HTTP Basic or Digest
+ * authentication.
+ */
+public class HttpPrincipal implements Principal {
+ private String username, realm;
+
+ /**
+ * creates a HttpPrincipal from the given username and realm
+ * @param username The name of the user within the realm
+ * @param realm The realm.
+ * @throws NullPointerException if either username or realm are null
+ */
+ public HttpPrincipal (String username, String realm) {
+ if (username == null || realm == null) {
+ throw new NullPointerException();
+ }
+ this.username = username;
+ this.realm = realm;
+ }
+
+ /**
+ * Compares two HttpPrincipal. Returns <code>true</code>
+ * if <i>another</i> is an instance of HttpPrincipal, and its
+ * username and realm are equal to this object's username
+ * and realm. Returns <code>false</code> otherwise.
+ */
+ public boolean equals (Object another) {
+ if (!(another instanceof HttpPrincipal)) {
+ return false;
+ }
+ HttpPrincipal theother = (HttpPrincipal)another;
+ return (username.equals(theother.username) &&
+ realm.equals(theother.realm));
+ }
+
+ /**
+ * returns the contents of this principal in the form
+ * <i>realm:username</i>
+ */
+ public String getName() {
+ return username;
+ }
+
+ /**
+ * returns the username this object was created with.
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * returns the realm this object was created with.
+ */
+ public String getRealm() {
+ return realm;
+ }
+
+ /**
+ * returns a hashcode for this HttpPrincipal. This is calculated
+ * as <code>(getUsername()+getRealm().hashCode()</code>
+ */
+ public int hashCode() {
+ return (username+realm).hashCode();
+ }
+
+ /**
+ * returns the same string as getName()
+ */
+ public String toString() {
+ return getName();
+ }
+}
+
Added: trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpServer.java
===================================================================
--- trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpServer.java (rev 0)
+++ trunk/core/src/openjdk/com/com/sun/net/httpserver/HttpServer.java 2007-06-25 08:14:00 UTC (rev 3303)
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.net.httpserver;
+
+import java.net.*;
+import java.io.*;
+import java.nio.*;
+import java.security.*;
+import java.nio.channels.*;
+import java.util.*;
+import java.util.concurrent.*;
+import javax.net.ssl.*;
+import com.sun.net.httpserver.spi.HttpServerProvider;
+
+/**
+ * This class implements a simple HTTP server. A HttpServer is bound to an IP address
+ * and port number and listens for incoming TCP connections from clients on this address.
+ * The sub-class {@link HttpsServer} implements a server which handles HTTPS requests.
+ * <p>
+ * One or more {@link HttpHandler} objects must be associated with a server
+ * in order to process requests. Each such HttpHandler is registered
+ * with a root URI path which represents the
+ * location of the application or service on this server. The mapping of a handler
+ * to a HttpServer is encapsulated by a {@link HttpContext} object. HttpContexts
+ * are created by calling {@link #createContext(String,HttpHandler)}.
+ * Any request for which no handler can be found is rejected with a 404 response.
+ * Management of threads can be done external to this object by providing a
+ * {@link java.util.concurrent.Executor} object. If none is provided a default
+ * implementation is used.
+ * <p>
+ * <a name="mapping_description"></a>
+ * <b>Mapping request URIs to HttpContext paths</b><p>
+ * When a HTTP request is received,
+ * the appropriate HttpContext (and handler) is located by finding the context
+ * whose path is the longest matching prefix of the request URI's path.
+ * Paths are matched literally, which means that the strings are compared
+ * case sensitively, and with no conversion to or from any encoded forms.
+ * For example. Given a HttpServer with the following HttpContexts configured.<p>
+ * <table >
+ * <tr><td><i>Context</i></td><td><i>Context path</i></td></tr>
+ * <tr><td>ctx1</td><td>"/"</td></tr>
+ * <tr><td>ctx2</td><td>"/apps/"</td></tr>
+ * <tr><td>ctx3</td><td>"/apps/foo/"</td></tr>
+ * </table>
+ * <p>
+ * the following table shows some request URIs and which, if any context they would
+ * match with.<p>
+ * <table>
+ * <tr><td><i>Request URI</i></td><td><i>Matches context</i></td></tr>
+ * <tr><td>"http://foo.com/apps/foo/bar"</td><td>ctx3</td></tr>
+ * <tr><td>"http://foo.com/apps/Foo/bar"</td><td>no match, wrong case</td></tr>
+ * <tr><td>"http://foo.com/apps/app1"</td><td>ctx2</td></tr>
+ * <tr><td>"http://foo.com/foo"</td><td>ctx1</td></tr>
+ * </table>
+ * <p>
+ * <b>Note about socket backlogs</b><p>
+ * When binding to an address and port number, the application can also specify an integer
+ * <i>backlog</i> parameter. This represents the maximum number of incoming TCP connections
+ * which the system will queue internally. Connections are queued while they are waiting to
+ * be accepted by the HttpServer. When the limit is reached, further connections may be
+ * rejected (or possibly ignored...
[truncated message content] |