Showing the changes to java/pkg/com/sun/net/httpserver (18 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,125 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | +import java.net.*; | |
| 28 | +import java.io.*; | |
| 29 | +import java.util.*; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * Authenticator represents an implementation of an HTTP authentication | |
| 33 | + * mechanism. Sub-classes provide implementations of specific mechanisms | |
| 34 | + * such as Digest or Basic auth. Instances are invoked to provide verification | |
| 35 | + * of the authentication information provided in all incoming requests. | |
| 36 | + * Note. This implies that any caching of credentials or other authentication | |
| 37 | + * information must be done outside of this class. | |
| 38 | + */ | |
| 39 | +public abstract class Authenticator { | |
| 40 | + | |
| 41 | + /** | |
| 42 | + * Base class for return type from authenticate() method | |
| 43 | + */ | |
| 44 | + public abstract static class Result {} | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * Indicates an authentication failure. The authentication | |
| 48 | + * attempt has completed. | |
| 49 | + */ | |
| 50 | + public static class Failure extends Result { | |
| 51 | + | |
| 52 | + private int responseCode; | |
| 53 | + | |
| 54 | + public Failure (int responseCode) { | |
| 55 | + this.responseCode = responseCode; | |
| 56 | + } | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * returns the response code to send to the client | |
| 60 | + */ | |
| 61 | + public int getResponseCode() { | |
| 62 | + return responseCode; | |
| 63 | + } | |
| 64 | + } | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Indicates an authentication has succeeded and the | |
| 68 | + * authenticated user principal can be acquired by calling | |
| 69 | + * getPrincipal(). | |
| 70 | + */ | |
| 71 | + public static class Success extends Result { | |
| 72 | + private HttpPrincipal principal; | |
| 73 | + | |
| 74 | + public Success (HttpPrincipal p) { | |
| 75 | + principal = p; | |
| 76 | + } | |
| 77 | + /** | |
| 78 | + * returns the authenticated user Principal | |
| 79 | + */ | |
| 80 | + public HttpPrincipal getPrincipal() { | |
| 81 | + return principal; | |
| 82 | + } | |
| 83 | + } | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * Indicates an authentication must be retried. The | |
| 87 | + * response code to be sent back is as returned from | |
| 88 | + * getResponseCode(). The Authenticator must also have | |
| 89 | + * set any necessary response headers in the given HttpExchange | |
| 90 | + * before returning this Retry object. | |
| 91 | + */ | |
| 92 | + public static class Retry extends Result { | |
| 93 | + | |
| 94 | + private int responseCode; | |
| 95 | + | |
| 96 | + public Retry (int responseCode) { | |
| 97 | + this.responseCode = responseCode; | |
| 98 | + } | |
| 99 | + | |
| 100 | + /** | |
| 101 | + * returns the response code to send to the client | |
| 102 | + */ | |
| 103 | + public int getResponseCode() { | |
| 104 | + return responseCode; | |
| 105 | + } | |
| 106 | + } | |
| 107 | + | |
| 108 | + /** | |
| 109 | + * called to authenticate each incoming request. The implementation | |
| 110 | + * must return a Failure, Success or Retry object as appropriate :- | |
| 111 | + * <p> | |
| 112 | + * Failure means the authentication has completed, but has failed | |
| 113 | + * due to invalid credentials. | |
| 114 | + * <p> | |
| 115 | + * Sucess means that the authentication | |
| 116 | + * has succeeded, and a Principal object representing the user | |
| 117 | + * can be retrieved by calling Sucess.getPrincipal() . | |
| 118 | + * <p> | |
| 119 | + * Retry means that another HTTP exchange is required. Any response | |
| 120 | + * headers needing to be sent back to the client are set in the | |
| 121 | + * given HttpExchange. The response code to be returned must be provided | |
| 122 | + * in the Retry object. Retry may occur multiple times. | |
| 123 | + */ | |
| 124 | + public abstract Result authenticate (HttpExchange exch); | |
| 125 | +} | |
| @@ -0,0 +1,309 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * BasicAuthenticator provides an implementation of HTTP Basic | |
| 30 | + * authentication. It is an abstract class and must be extended | |
| 31 | + * to provide an implementation of {@link #checkCredentials(String,String)} | |
| 32 | + * which is called to verify each incoming request. | |
| 33 | + */ | |
| 34 | +public abstract class BasicAuthenticator extends Authenticator { | |
| 35 | + | |
| 36 | + protected String realm; | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Creates a BasicAuthenticator for the given HTTP realm | |
| 40 | + * @param realm The HTTP Basic authentication realm | |
| 41 | + * @throws NullPointerException if the realm is an empty string | |
| 42 | + */ | |
| 43 | + public BasicAuthenticator (String realm) { | |
| 44 | + this.realm = realm; | |
| 45 | + } | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * returns the realm this BasicAuthenticator was created with | |
| 49 | + * @return the authenticator's realm string. | |
| 50 | + */ | |
| 51 | + public String getRealm () { | |
| 52 | + return realm; | |
| 53 | + } | |
| 54 | + | |
| 55 | + public Result authenticate (HttpExchange t) | |
| 56 | + { | |
| 57 | + Headers rmap = (Headers) t.getRequestHeaders(); | |
| 58 | + /* | |
| 59 | + * look for auth token | |
| 60 | + */ | |
| 61 | + String auth = rmap.getFirst ("Authorization"); | |
| 62 | + if (auth == null) { | |
| 63 | + Headers map = (Headers) t.getResponseHeaders(); | |
| 64 | + map.set ("WWW-Authenticate", "Basic realm=" + "\""+realm+"\""); | |
| 65 | + return new Authenticator.Retry (401); | |
| 66 | + } | |
| 67 | + int sp = auth.indexOf (' '); | |
| 68 | + if (sp == -1 || !auth.substring(0, sp).equals ("Basic")) { | |
| 69 | + return new Authenticator.Failure (401); | |
| 70 | + } | |
| 71 | + byte[] b = Base64.base64ToByteArray (auth.substring(sp+1)); | |
| 72 | + String userpass = new String (b); | |
| 73 | + int colon = userpass.indexOf (':'); | |
| 74 | + String uname = userpass.substring (0, colon); | |
| 75 | + String pass = userpass.substring (colon+1); | |
| 76 | + | |
| 77 | + if (checkCredentials (uname, pass)) { | |
| 78 | + return new Authenticator.Success ( | |
| 79 | + new HttpPrincipal ( | |
| 80 | + uname, realm | |
| 81 | + ) | |
| 82 | + ); | |
| 83 | + } else { | |
| 84 | + /* reject the request again with 401 */ | |
| 85 | + | |
| 86 | + Headers map = (Headers) t.getResponseHeaders(); | |
| 87 | + map.set ("WWW-Authenticate", "Basic realm=" + "\""+realm+"\""); | |
| 88 | + return new Authenticator.Failure(401); | |
| 89 | + } | |
| 90 | + } | |
| 91 | + | |
| 92 | + /** | |
| 93 | + * called for each incoming request to verify the | |
| 94 | + * given name and password in the context of this | |
| 95 | + * Authenticator's realm. Any caching of credentials | |
| 96 | + * must be done by the implementation of this method | |
| 97 | + * @param username the username from the request | |
| 98 | + * @param password the password from the request | |
| 99 | + * @return <code>true</code> if the credentials are valid, | |
| 100 | + * <code>false</code> otherwise. | |
| 101 | + */ | |
| 102 | + public abstract boolean checkCredentials (String username, String password); | |
| 103 | +} | |
| 104 | + | |
| 105 | +class Base64 { | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Translates the specified byte array into a Base64 string as per | |
| 109 | + * Preferences.put(byte[]). | |
| 110 | + */ | |
| 111 | + static String byteArrayToBase64(byte[] a) { | |
| 112 | + return byteArrayToBase64(a, false); | |
| 113 | + } | |
| 114 | + | |
| 115 | + /** | |
| 116 | + * Translates the specified byte array into an "aternate representation" | |
| 117 | + * Base64 string. This non-standard variant uses an alphabet that does | |
| 118 | + * not contain the uppercase alphabetic characters, which makes it | |
| 119 | + * suitable for use in situations where case-folding occurs. | |
| 120 | + */ | |
| 121 | + static String byteArrayToAltBase64(byte[] a) { | |
| 122 | + return byteArrayToBase64(a, true); | |
| 123 | + } | |
| 124 | + | |
| 125 | + private static String byteArrayToBase64(byte[] a, boolean alternate) { | |
| 126 | + int aLen = a.length; | |
| 127 | + int numFullGroups = aLen/3; | |
| 128 | + int numBytesInPartialGroup = aLen - 3*numFullGroups; | |
| 129 | + int resultLen = 4*((aLen + 2)/3); | |
| 130 | + StringBuffer result = new StringBuffer(resultLen); | |
| 131 | + char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64); | |
| 132 | + | |
| 133 | + // Translate all full groups from byte array elements to Base64 | |
| 134 | + int inCursor = 0; | |
| 135 | + for (int i=0; i<numFullGroups; i++) { | |
| 136 | + int byte0 = a[inCursor++] & 0xff; | |
| 137 | + int byte1 = a[inCursor++] & 0xff; | |
| 138 | + int byte2 = a[inCursor++] & 0xff; | |
| 139 | + result.append(intToAlpha[byte0 >> 2]); | |
| 140 | + result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); | |
| 141 | + result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]); | |
| 142 | + result.append(intToAlpha[byte2 & 0x3f]); | |
| 143 | + } | |
| 144 | + | |
| 145 | + // Translate partial group if present | |
| 146 | + if (numBytesInPartialGroup != 0) { | |
| 147 | + int byte0 = a[inCursor++] & 0xff; | |
| 148 | + result.append(intToAlpha[byte0 >> 2]); | |
| 149 | + if (numBytesInPartialGroup == 1) { | |
| 150 | + result.append(intToAlpha[(byte0 << 4) & 0x3f]); | |
| 151 | + result.append("=="); | |
| 152 | + } else { | |
| 153 | + // assert numBytesInPartialGroup == 2; | |
| 154 | + int byte1 = a[inCursor++] & 0xff; | |
| 155 | + result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); | |
| 156 | + result.append(intToAlpha[(byte1 << 2)&0x3f]); | |
| 157 | + result.append('='); | |
| 158 | + } | |
| 159 | + } | |
| 160 | + // assert inCursor == a.length; | |
| 161 | + // assert result.length() == resultLen; | |
| 162 | + return result.toString(); | |
| 163 | + } | |
| 164 | + | |
| 165 | + /** | |
| 166 | + * This array is a lookup table that translates 6-bit positive integer | |
| 167 | + * index values into their "Base64 Alphabet" equivalents as specified | |
| 168 | + * in Table 1 of RFC 2045. | |
| 169 | + */ | |
| 170 | + private static final char intToBase64[] = { | |
| 171 | + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', | |
| 172 | + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', | |
| 173 | + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', | |
| 174 | + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', | |
| 175 | + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' | |
| 176 | + }; | |
| 177 | + | |
| 178 | + /** | |
| 179 | + * This array is a lookup table that translates 6-bit positive integer | |
| 180 | + * index values into their "Alternate Base64 Alphabet" equivalents. | |
| 181 | + * This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045. | |
| 182 | + * This alternate alphabet does not use the capital letters. It is | |
| 183 | + * designed for use in environments where "case folding" occurs. | |
| 184 | + */ | |
| 185 | + private static final char intToAltBase64[] = { | |
| 186 | + '!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':', | |
| 187 | + ';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~', | |
| 188 | + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', | |
| 189 | + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', | |
| 190 | + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?' | |
| 191 | + }; | |
| 192 | + | |
| 193 | + /** | |
| 194 | + * Translates the specified Base64 string (as per Preferences.get(byte[])) | |
| 195 | + * into a byte array. | |
| 196 | + * | |
| 197 | + * @throw IllegalArgumentException if <tt>s</tt> is not a valid Base64 | |
| 198 | + * string. | |
| 199 | + */ | |
| 200 | + static byte[] base64ToByteArray(String s) { | |
| 201 | + return base64ToByteArray(s, false); | |
| 202 | + } | |
| 203 | + | |
| 204 | + /** | |
| 205 | + * Translates the specified "aternate representation" Base64 string | |
| 206 | + * into a byte array. | |
| 207 | + * | |
| 208 | + * @throw IllegalArgumentException or ArrayOutOfBoundsException | |
| 209 | + * if <tt>s</tt> is not a valid alternate representation | |
| 210 | + * Base64 string. | |
| 211 | + */ | |
| 212 | + static byte[] altBase64ToByteArray(String s) { | |
| 213 | + return base64ToByteArray(s, true); | |
| 214 | + } | |
| 215 | + | |
| 216 | + private static byte[] base64ToByteArray(String s, boolean alternate) { | |
| 217 | + byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt); | |
| 218 | + int sLen = s.length(); | |
| 219 | + int numGroups = sLen/4; | |
| 220 | + if (4*numGroups != sLen) | |
| 221 | + throw new IllegalArgumentException( | |
| 222 | + "String length must be a multiple of four."); | |
| 223 | + int missingBytesInLastGroup = 0; | |
| 224 | + int numFullGroups = numGroups; | |
| 225 | + if (sLen != 0) { | |
| 226 | + if (s.charAt(sLen-1) == '=') { | |
| 227 | + missingBytesInLastGroup++; | |
| 228 | + numFullGroups--; | |
| 229 | + } | |
| 230 | + if (s.charAt(sLen-2) == '=') | |
| 231 | + missingBytesInLastGroup++; | |
| 232 | + } | |
| 233 | + byte[] result = new byte[3*numGroups - missingBytesInLastGroup]; | |
| 234 | + | |
| 235 | + // Translate all full groups from base64 to byte array elements | |
| 236 | + int inCursor = 0, outCursor = 0; | |
| 237 | + for (int i=0; i<numFullGroups; i++) { | |
| 238 | + int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); | |
| 239 | + int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); | |
| 240 | + int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); | |
| 241 | + int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt); | |
| 242 | + result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); | |
| 243 | + result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); | |
| 244 | + result[outCursor++] = (byte) ((ch2 << 6) | ch3); | |
| 245 | + } | |
| 246 | + | |
| 247 | + // Translate partial group, if present | |
| 248 | + if (missingBytesInLastGroup != 0) { | |
| 249 | + int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); | |
| 250 | + int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); | |
| 251 | + result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); | |
| 252 | + | |
| 253 | + if (missingBytesInLastGroup == 1) { | |
| 254 | + int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); | |
| 255 | + result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); | |
| 256 | + } | |
| 257 | + } | |
| 258 | + // assert inCursor == s.length()-missingBytesInLastGroup; | |
| 259 | + // assert outCursor == result.length; | |
| 260 | + return result; | |
| 261 | + } | |
| 262 | + | |
| 263 | + /** | |
| 264 | + * Translates the specified character, which is assumed to be in the | |
| 265 | + * "Base 64 Alphabet" into its equivalent 6-bit positive integer. | |
| 266 | + * | |
| 267 | + * @throw IllegalArgumentException or ArrayOutOfBoundsException if | |
| 268 | + * c is not in the Base64 Alphabet. | |
| 269 | + */ | |
| 270 | + private static int base64toInt(char c, byte[] alphaToInt) { | |
| 271 | + int result = alphaToInt[c]; | |
| 272 | + if (result < 0) | |
| 273 | + throw new IllegalArgumentException("Illegal character " + c); | |
| 274 | + return result; | |
| 275 | + } | |
| 276 | + | |
| 277 | + /** | |
| 278 | + * This array is a lookup table that translates unicode characters | |
| 279 | + * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) | |
| 280 | + * into their 6-bit positive integer equivalents. Characters that | |
| 281 | + * are not in the Base64 alphabet but fall within the bounds of the | |
| 282 | + * array are translated to -1. | |
| 283 | + */ | |
| 284 | + private static final byte base64ToInt[] = { | |
| 285 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
| 286 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
| 287 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, | |
| 288 | + 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, | |
| 289 | + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, | |
| 290 | + 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, | |
| 291 | + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 | |
| 292 | + }; | |
| 293 | + | |
| 294 | + /** | |
| 295 | + * This array is the analogue of base64ToInt, but for the nonstandard | |
| 296 | + * variant that avoids the use of uppercase alphabetic characters. | |
| 297 | + */ | |
| 298 | + private static final byte altBase64ToInt[] = { | |
| 299 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
| 300 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, | |
| 301 | + 2, 3, 4, 5, 6, 7, 8, -1, 62, 9, 10, 11, -1 , 52, 53, 54, 55, 56, 57, | |
| 302 | + 58, 59, 60, 61, 12, 13, 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1, | |
| 303 | + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
| 304 | + -1, -1, -1, 17, -1, 18, 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33, | |
| 305 | + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, | |
| 306 | + 51, 22, 23, 24, 25 | |
| 307 | + }; | |
| 308 | + | |
| 309 | +} | |
| @@ -0,0 +1,119 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.util.*; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * A filter used to pre- and post-process incoming requests. Pre-processing occurs | |
| 33 | + * before the application's exchange handler is invoked, and post-processing | |
| 34 | + * occurs after the exchange handler returns. Filters | |
| 35 | + * are organised in chains, and are associated with HttpContext instances. | |
| 36 | + * <p> | |
| 37 | + * Each Filter in the chain, invokes the next filter within its own | |
| 38 | + * doFilter() implementation. The final Filter in the chain invokes the applications | |
| 39 | + * exchange handler. | |
| 40 | + * @since 1.6 | |
| 41 | + */ | |
| 42 | +public abstract class Filter { | |
| 43 | + | |
| 44 | + protected Filter () {} | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * a chain of filters associated with a HttpServer. | |
| 48 | + * Each filter in the chain is given one of these | |
| 49 | + * so it can invoke the next filter in the chain | |
| 50 | + */ | |
| 51 | + public static class Chain { | |
| 52 | + /* the last element in the chain must invoke the users | |
| 53 | + * handler | |
| 54 | + */ | |
| 55 | + private ListIterator<Filter> iter; | |
| 56 | + private HttpHandler handler; | |
| 57 | + | |
| 58 | + public Chain (List<Filter> filters, HttpHandler handler) { | |
| 59 | + iter = filters.listIterator(); | |
| 60 | + this.handler = handler; | |
| 61 | + } | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * calls the next filter in the chain, or else | |
| 65 | + * the users exchange handler, if this is the | |
| 66 | + * final filter in the chain. The Filter may decide | |
| 67 | + * to terminate the chain, by not calling this method. | |
| 68 | + * In this case, the filter <b>must</b> send the | |
| 69 | + * response to the request, because the application's | |
| 70 | + * exchange handler will not be invoked. | |
| 71 | + * @param exchange the HttpExchange | |
| 72 | + * @throws IOException let exceptions pass up the stack | |
| 73 | + * @throws NullPointerException if exchange is <code>null</code> | |
| 74 | + */ | |
| 75 | + public void doFilter (HttpExchange exchange) throws IOException { | |
| 76 | + if (!iter.hasNext()) { | |
| 77 | + handler.handle (exchange); | |
| 78 | + } else { | |
| 79 | + Filter f = iter.next(); | |
| 80 | + f.doFilter (exchange, this); | |
| 81 | + } | |
| 82 | + } | |
| 83 | + } | |
| 84 | + | |
| 85 | + /** | |
| 86 | + * Asks this filter to pre/post-process the given exchange. The filter | |
| 87 | + * can :- | |
| 88 | + * <ul><li>examine or modify the request headers</li> | |
| 89 | + * <li>filter the request body or the response body, by creating suitable | |
| 90 | + * filter streams and calling | |
| 91 | + * {@link HttpExchange#setStreams(InputStream,OutputStream)}</li> | |
| 92 | + * <li>set attribute Objects in the exchange, which other filters or the | |
| 93 | + * exchange handler can access.</li> | |
| 94 | + * <li>decide to either :-<ol> | |
| 95 | + * <li>invoke the next filter in the chain, by calling | |
| 96 | + * {@link Filter.Chain#doFilter(HttpExchange)}</li> | |
| 97 | + * <li>terminate the chain of invocation, by <b>not</b> calling | |
| 98 | + * {@link Filter.Chain#doFilter(HttpExchange)}</li></ol> | |
| 99 | + * <li>if option 1. above taken, then when doFilter() returns all subsequent | |
| 100 | + * filters in the Chain have been called, and the response headers can be | |
| 101 | + * examined or modified.</li> | |
| 102 | + * <li>if option 2. above taken, then this Filter must use the HttpExchange | |
| 103 | + * to send back an appropriate response</li></ul><p> | |
| 104 | + * @param exchange the <code>HttpExchange</code> to be filtered. | |
| 105 | + * @param chain the Chain which allows the next filter to be invoked. | |
| 106 | + * @throws IOException may be thrown by any filter module, and if | |
| 107 | + * caught, must be rethrown again. | |
| 108 | + * @throws NullPointerException if either exchange or chain are <code>null</code> | |
| 109 | + */ | |
| 110 | + public abstract void doFilter (HttpExchange exchange, Chain chain) | |
| 111 | + throws IOException; | |
| 112 | + | |
| 113 | + /** | |
| 114 | + * returns a short description of this Filter | |
| 115 | + * @return a string describing the Filter | |
| 116 | + */ | |
| 117 | + public abstract String description (); | |
| 118 | + | |
| 119 | +} | |
| @@ -0,0 +1,183 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | + | |
| 28 | +import java.util.*; | |
| 29 | + | |
| 30 | +/** | |
| 31 | + * HTTP request and response headers are represented by this class which implements | |
| 32 | + * the interface {@link java.util.Map}< | |
| 33 | + * {@link java.lang.String},{@link java.util.List}<{@link java.lang.String}>>. | |
| 34 | + * The keys are case-insensitive Strings representing the header names and | |
| 35 | + * the value associated with each key is a {@link List}<{@link String}> with one | |
| 36 | + * element for each occurence of the header name in the request or response. | |
| 37 | + * <p> | |
| 38 | + * For example, if a response header instance contains one key "HeaderName" with two values "value1 and value2" | |
| 39 | + * then this object is output as two header lines: | |
| 40 | + * <blockquote><pre> | |
| 41 | + * HeaderName: value1 | |
| 42 | + * HeaderName: value2 | |
| 43 | + * </blockquote></pre> | |
| 44 | + * <p> | |
| 45 | + * All the normal {@link java.util.Map} methods are provided, but the following | |
| 46 | + * additional convenience methods are most likely to be used: | |
| 47 | + * <ul> | |
| 48 | + * <li>{@link #getFirst(String)} returns a single valued header or the first value of | |
| 49 | + * a multi-valued header.</li> | |
| 50 | + * <li>{@link #add(String,String)} adds the given header value to the list for the given key</li> | |
| 51 | + * <li>{@link #set(String,String)} sets the given header field to the single value given | |
| 52 | + * overwriting any existing values in the value list. | |
| 53 | + * </ul><p> | |
| 54 | + * All methods in this class accept <code>null</code> values for keys and values. However, null | |
| 55 | + * keys will never will be present in HTTP request headers, and will not be output/sent in response headers. | |
| 56 | + * Null values can be represented as either a null entry for the key (i.e. the list is null) or | |
| 57 | + * where the key has a list, but one (or more) of the list's values is null. Null values are output | |
| 58 | + * as a header line containing the key but no associated value. | |
| 59 | + * @since 1.6 | |
| 60 | + */ | |
| 61 | +public class Headers implements Map<String,List<String>> { | |
| 62 | + | |
| 63 | + HashMap<String,List<String>> map; | |
| 64 | + | |
| 65 | + public Headers () {map = new HashMap<String,List<String>>(32);} | |
| 66 | + | |
| 67 | + /* Normalize the key by converting to following form. | |
| 68 | + * First char upper case, rest lower case. | |
| 69 | + * key is presumed to be ASCII | |
| 70 | + */ | |
| 71 | + private String normalize (String key) { | |
| 72 | + if (key == null) { | |
| 73 | + return null; | |
| 74 | + } | |
| 75 | + int len = key.length(); | |
| 76 | + if (len == 0) { | |
| 77 | + return key; | |
| 78 | + } | |
| 79 | + char[] b = key.toCharArray(); | |
| 80 | + if (b[0] >= 'a' && b[0] <= 'z') { | |
| 81 | + b[0] = (char)(b[0] - ('a' - 'A')); | |
| 82 | + } | |
| 83 | + for (int i=1; i<len; i++) { | |
| 84 | + if (b[i] >= 'A' && b[i] <= 'Z') { | |
| 85 | + b[i] = (char) (b[i] + ('a' - 'A')); | |
| 86 | + } | |
| 87 | + } | |
| 88 | + return new String(b); | |
| 89 | + } | |
| 90 | + | |
| 91 | + public int size() {return map.size();} | |
| 92 | + | |
| 93 | + public boolean isEmpty() {return map.isEmpty();} | |
| 94 | + | |
| 95 | + public boolean containsKey(Object key) { | |
| 96 | + if (key == null) { | |
| 97 | + return false; | |
| 98 | + } | |
| 99 | + if (!(key instanceof String)) { | |
| 100 | + return false; | |
| 101 | + } | |
| 102 | + return map.containsKey (normalize((String)key)); | |
| 103 | + } | |
| 104 | + | |
| 105 | + public boolean containsValue(Object value) { | |
| 106 | + return map.containsValue(value); | |
| 107 | + } | |
| 108 | + | |
| 109 | + public List<String> get(Object key) { | |
| 110 | + return map.get(normalize((String)key)); | |
| 111 | + } | |
| 112 | + | |
| 113 | + /** | |
| 114 | + * returns the first value from the List of String values | |
| 115 | + * for the given key (if at least one exists). | |
| 116 | + * @param key the key to search for | |
| 117 | + * @return the first string value associated with the key | |
| 118 | + */ | |
| 119 | + public String getFirst (String key) { | |
| 120 | + List<String> l = map.get(normalize((String)key)); | |
| 121 | + if (l == null) { | |
| 122 | + return null; | |
| 123 | + } | |
| 124 | + return l.get(0); | |
| 125 | + } | |
| 126 | + | |
| 127 | + public List<String> put(String key, List<String> value) { | |
| 128 | + return map.put (normalize(key), value); | |
| 129 | + } | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * adds the given value to the list of headers | |
| 133 | + * for the given key. If the mapping does not | |
| 134 | + * already exist, then it is created | |
| 135 | + * @param key the header name | |
| 136 | + * @param value the header value to add to the header | |
| 137 | + */ | |
| 138 | + public void add (String key, String value) { | |
| 139 | + String k = normalize(key); | |
| 140 | + List<String> l = map.get(k); | |
| 141 | + if (l == null) { | |
| 142 | + l = new LinkedList<String>(); | |
| 143 | + map.put(k,l); | |
| 144 | + } | |
| 145 | + l.add (value); | |
| 146 | + } | |
| 147 | + | |
| 148 | + /** | |
| 149 | + * sets the given value as the sole header value | |
| 150 | + * for the given key. If the mapping does not | |
| 151 | + * already exist, then it is created | |
| 152 | + * @param key the header name | |
| 153 | + * @param value the header value to set. | |
| 154 | + */ | |
| 155 | + public void set (String key, String value) { | |
| 156 | + LinkedList<String> l = new LinkedList<String>(); | |
| 157 | + l.add (value); | |
| 158 | + put (key, l); | |
| 159 | + } | |
| 160 | + | |
| 161 | + | |
| 162 | + public List<String> remove(Object key) { | |
| 163 | + return map.remove(normalize((String)key)); | |
| 164 | + } | |
| 165 | + | |
| 166 | + public void putAll(Map<? extends String,? extends List<String>> t) { | |
| 167 | + map.putAll (t); | |
| 168 | + } | |
| 169 | + | |
| 170 | + public void clear() {map.clear();} | |
| 171 | + | |
| 172 | + public Set<String> keySet() {return map.keySet();} | |
| 173 | + | |
| 174 | + public Collection<List<String>> values() {return map.values();} | |
| 175 | + | |
| 176 | + public Set<Map.Entry<String, List<String>>> entrySet() { | |
| 177 | + return map.entrySet(); | |
| 178 | + } | |
| 179 | + | |
| 180 | + public boolean equals(Object o) {return map.equals(o);} | |
| 181 | + | |
| 182 | + public int hashCode() {return map.hashCode();} | |
| 183 | + } | |
| @@ -0,0 +1,112 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | +import java.net.*; | |
| 28 | +import java.io.*; | |
| 29 | +import java.util.*; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * HttpContext represents a mapping between the root URI path of an application | |
| 33 | + * to a {@link HttpHandler} which is invoked to handle requests destined | |
| 34 | + * for that path on the associated HttpServer or HttpsServer. | |
| 35 | + * <p> | |
| 36 | + * HttpContext instances are created by the create methods in HttpServer | |
| 37 | + * and HttpsServer | |
| 38 | + * <p> | |
| 39 | + * A chain of {@link Filter} objects can be added to a HttpContext. All exchanges processed by the | |
| 40 | + * context can be pre- and post-processed by each Filter in the chain. | |
| 41 | + * @since 1.6 | |
| 42 | + */ | |
| 43 | +public abstract class HttpContext { | |
| 44 | + | |
| 45 | + protected HttpContext () { | |
| 46 | + } | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * returns the handler for this context | |
| 50 | + * @return the HttpHandler for this context | |
| 51 | + */ | |
| 52 | + public abstract HttpHandler getHandler () ; | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * Sets the handler for this context, if not already set. | |
| 56 | + * @param h the handler to set for this context | |
| 57 | + * @throws IllegalArgumentException if this context's handler is already set. | |
| 58 | + * @throws NullPointerException if handler is <code>null</code> | |
| 59 | + */ | |
| 60 | + public abstract void setHandler (HttpHandler h) ; | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * returns the path this context was created with | |
| 64 | + * @return this context's path | |
| 65 | + */ | |
| 66 | + public abstract String getPath() ; | |
| 67 | + | |
| 68 | + /** | |
| 69 | + * returns the server this context was created with | |
| 70 | + * @return this context's server | |
| 71 | + */ | |
| 72 | + public abstract HttpServer getServer () ; | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * returns a mutable Map, which can be used to pass | |
| 76 | + * configuration and other data to Filter modules | |
| 77 | + * and to the context's exchange handler. | |
| 78 | + * <p> | |
| 79 | + * Every attribute stored in this Map will be visible to | |
| 80 | + * every HttpExchange processed by this context | |
| 81 | + */ | |
| 82 | + public abstract Map<String,Object> getAttributes() ; | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * returns this context's list of Filters. This is the | |
| 86 | + * actual list used by the server when dispatching requests | |
| 87 | + * so modifications to this list immediately affect the | |
| 88 | + * the handling of exchanges. | |
| 89 | + */ | |
| 90 | + public abstract List<Filter> getFilters(); | |
| 91 | + | |
| 92 | + /** | |
| 93 | + * Sets the Authenticator for this HttpContext. Once an authenticator | |
| 94 | + * is establised on a context, all client requests must be | |
| 95 | + * authenticated, and the given object will be invoked to validate each | |
| 96 | + * request. Each call to this method replaces any previous value set. | |
| 97 | + * @param auth the authenticator to set. If <code>null</code> then any | |
| 98 | + * previously set authenticator is removed, | |
| 99 | + * and client authentication will no longer be required. | |
| 100 | + * @return the previous Authenticator, if any set, or <code>null</code> | |
| 101 | + * otherwise. | |
| 102 | + */ | |
| 103 | + public abstract Authenticator setAuthenticator (Authenticator auth); | |
| 104 | + | |
| 105 | + /** | |
| 106 | + * Returns the currently set Authenticator for this context | |
| 107 | + * if one exists. | |
| 108 | + * @return this HttpContext's Authenticator, or <code>null</code> | |
| 109 | + * if none is set. | |
| 110 | + */ | |
| 111 | + public abstract Authenticator getAuthenticator (); | |
| 112 | +} | |
| @@ -0,0 +1,265 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | + | |
| 28 | +import java.io.*; | |
| 29 | +import java.nio.*; | |
| 30 | +import java.nio.channels.*; | |
| 31 | +import java.net.*; | |
| 32 | +import javax.net.ssl.*; | |
| 33 | +import java.util.*; | |
| 34 | +import sun.net.www.MessageHeader; | |
| 35 | + | |
| 36 | +/** | |
| 37 | + * This class encapsulates a HTTP request received and a | |
| 38 | + * response to be generated in one exchange. It provides methods | |
| 39 | + * for examining the request from the client, and for building and | |
| 40 | + * sending the response. | |
| 41 | + * <p> | |
| 42 | + * The typical life-cycle of a HttpExchange is shown in the sequence | |
| 43 | + * below. | |
| 44 | + * <ol><li>{@link #getRequestMethod()} to determine the command | |
| 45 | + * <li>{@link #getRequestHeaders()} to examine the request headers (if needed) | |
| 46 | + * <li>{@link #getRequestBody()} returns a {@link java.io.InputStream} for reading the request body. | |
| 47 | + * After reading the request body, the stream is close. | |
| 48 | + * <li>{@link #getResponseHeaders()} to set any response headers, except content-length | |
| 49 | + * <li>{@link #sendResponseHeaders(int,long)} to send the response headers. Must be called before | |
| 50 | + * next step. | |
| 51 | + * <li>{@link #getResponseBody()} to get a {@link java.io.OutputStream} to send the response body. | |
| 52 | + * When the response body has been written, the stream must be closed to terminate the exchange. | |
| 53 | + * </ol> | |
| 54 | + * <b>Terminating exchanges</b> | |
| 55 | + * <br> | |
| 56 | + * Exchanges are terminated when both the request InputStream and response OutputStream are closed. | |
| 57 | + * Closing the OutputStream, implicitly closes the InputStream (if it is not already closed). | |
| 58 | + * However, it is recommended | |
| 59 | + * to consume all the data from the InputStream before closing it. | |
| 60 | + * The convenience method {@link #close()} does all of these tasks. | |
| 61 | + * Closing an exchange without consuming all of the request body is not an error | |
| 62 | + * but may make the underlying TCP connection unusable for following exchanges. | |
| 63 | + * The effect of failing to terminate an exchange is undefined, but will typically | |
| 64 | + * result in resources failing to be freed/reused. | |
| 65 | + * @since 1.6 | |
| 66 | + */ | |
| 67 | + | |
| 68 | +public abstract class HttpExchange { | |
| 69 | + | |
| 70 | + protected HttpExchange () { | |
| 71 | + } | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * Returns an immutable Map containing the HTTP headers that were | |
| 75 | + * included with this request. The keys in this Map will be the header | |
| 76 | + * names, while the values will be a List of Strings containing each value | |
| 77 | + * that was included (either for a header that was listed several times, | |
| 78 | + * or one that accepts a comma-delimited list of values on a single line). | |
| 79 | + * In either of these cases, the values for the header name will be | |
| 80 | + * presented in the order that they were included in the request. | |
| 81 | + * <p> | |
| 82 | + * The keys in Map are case-insensitive. | |
| 83 | + * @return a read-only Map which can be used to access request headers | |
| 84 | + */ | |
| 85 | + public abstract Headers getRequestHeaders () ; | |
| 86 | + | |
| 87 | + /** | |
| 88 | + * Returns a mutable Map into which the HTTP response headers can be stored | |
| 89 | + * and which will be transmitted as part of this response. The keys in the | |
| 90 | + * Map will be the header names, while the values must be a List of Strings | |
| 91 | + * containing each value that should be included multiple times | |
| 92 | + * (in the order that they should be included). | |
| 93 | + * <p> | |
| 94 | + * The keys in Map are case-insensitive. | |
| 95 | + * @return a writable Map which can be used to set response headers. | |
| 96 | + */ | |
| 97 | + public abstract Headers getResponseHeaders () ; | |
| 98 | + | |
| 99 | + /** | |
| 100 | + * Get the request URI | |
| 101 | + * | |
| 102 | + * @return the request URI | |
| 103 | + */ | |
| 104 | + public abstract URI getRequestURI () ; | |
| 105 | + | |
| 106 | + /** | |
| 107 | + * Get the request method | |
| 108 | + * @return the request method | |
| 109 | + */ | |
| 110 | + public abstract String getRequestMethod (); | |
| 111 | + | |
| 112 | + /** | |
| 113 | + * Get the HttpContext for this exchange | |
| 114 | + * @return the HttpContext | |
| 115 | + */ | |
| 116 | + public abstract HttpContext getHttpContext (); | |
| 117 | + | |
| 118 | + /** | |
| 119 | + * Ends this exchange by doing the following in sequence:<p><ol> | |
| 120 | + * <li>close the request InputStream, if not already closed<p></li> | |
| 121 | + * <li>close the response OutputStream, if not already closed. </li> | |
| 122 | + * </ol> | |
| 123 | + */ | |
| 124 | + public abstract void close () ; | |
| 125 | + | |
| 126 | + /** | |
| 127 | + * returns a stream from which the request body can be read. | |
| 128 | + * Multiple calls to this method will return the same stream. | |
| 129 | + * It is recommended that applications should consume (read) all of the | |
| 130 | + * data from this stream before closing it. If a stream is closed | |
| 131 | + * before all data has been read, then the close() call will | |
| 132 | + * read and discard remaining data (up to an implementation specific | |
| 133 | + * number of bytes). | |
| 134 | + * @return the stream from which the request body can be read. | |
| 135 | + */ | |
| 136 | + public abstract InputStream getRequestBody () ; | |
| 137 | + | |
| 138 | + /** | |
| 139 | + * returns a stream to which the response body must be | |
| 140 | + * written. {@link #sendResponseHeaders(int,long)}) must be called prior to calling | |
| 141 | + * this method. Multiple calls to this method (for the same exchange) | |
| 142 | + * will return the same stream. In order to correctly terminate | |
| 143 | + * each exchange, the output stream must be closed, even if no | |
| 144 | + * response body is being sent. | |
| 145 | + * <p> | |
| 146 | + * Closing this stream implicitly | |
| 147 | + * closes the InputStream returned from {@link #getRequestBody()} | |
| 148 | + * (if it is not already closed). | |
| 149 | + * <P> | |
| 150 | + * If the call to sendResponseHeaders() specified a fixed response | |
| 151 | + * body length, then the exact number of bytes specified in that | |
| 152 | + * call must be written to this stream. If too many bytes are written, | |
| 153 | + * then write() will throw an IOException. If too few bytes are written | |
| 154 | + * then the stream close() will throw an IOException. In both cases, | |
| 155 | + * the exchange is aborted and the underlying TCP connection closed. | |
| 156 | + * @return the stream to which the response body is written | |
| 157 | + */ | |
| 158 | + public abstract OutputStream getResponseBody () ; | |
| 159 | + | |
| 160 | + | |
| 161 | + /** | |
| 162 | + * Starts sending the response back to the client using the current set of response headers | |
| 163 | + * and the numeric response code as specified in this method. The response body length is also specified | |
| 164 | + * as follows. If the response length parameter is greater than zero, this specifies an exact | |
| 165 | + * number of bytes to send and the application must send that exact amount of data. | |
| 166 | + * If the response length parameter is <code>zero</code>, then chunked transfer encoding is | |
| 167 | + * used and an arbitrary amount of data may be sent. The application terminates the | |
| 168 | + * response body by closing the OutputStream. If response length has the value <code>-1</code> | |
| 169 | + * then no response body is being sent. | |
| 170 | + * <p> | |
| 171 | + * If the content-length response header has not already been set then | |
| 172 | + * this is set to the apropriate value depending on the response length parameter. | |
| 173 | + * <p> | |
| 174 | + * This method must be called prior to calling {@link #getResponseBody()}. | |
| 175 | + * @param rCode the response code to send | |
| 176 | + * @param responseLength if > 0, specifies a fixed response body length | |
| 177 | + * and that exact number of bytes must be written | |
| 178 | + * to the stream acquired from getResponseBody(), or else | |
| 179 | + * if equal to 0, then chunked encoding is used, | |
| 180 | + * and an arbitrary number of bytes may be written. | |
| 181 | + * if <= -1, then no response body length is specified and | |
| 182 | + * no response body may be written. | |
| 183 | + * @see HttpExchange#getResponseBody() | |
| 184 | + */ | |
| 185 | + public abstract void sendResponseHeaders (int rCode, long responseLength) throws IOException ; | |
| 186 | + | |
| 187 | + /** | |
| 188 | + * Returns the address of the remote entity invoking this request | |
| 189 | + * @return the InetSocketAddress of the caller | |
| 190 | + */ | |
| 191 | + public abstract InetSocketAddress getRemoteAddress (); | |
| 192 | + | |
| 193 | + /** | |
| 194 | + * Returns the response code, if it has already been set | |
| 195 | + * @return the response code, if available. <code>-1</code> if not available yet. | |
| 196 | + */ | |
| 197 | + public abstract int getResponseCode (); | |
| 198 | + | |
| 199 | + /** | |
| 200 | + * Returns the local address on which the request was received | |
| 201 | + * @return the InetSocketAddress of the local interface | |
| 202 | + */ | |
| 203 | + public abstract InetSocketAddress getLocalAddress (); | |
| 204 | + | |
| 205 | + /** | |
| 206 | + * Returns the protocol string from the request in the form | |
| 207 | + * <i>protocol/majorVersion.minorVersion</i>. For example, | |
| 208 | + * "HTTP/1.1" | |
| 209 | + * @return the protocol string from the request | |
| 210 | + */ | |
| 211 | + public abstract String getProtocol (); | |
| 212 | + | |
| 213 | + /** | |
| 214 | + * Filter modules may store arbitrary objects with HttpExchange | |
| 215 | + * instances as an out-of-band communication mechanism. Other Filters | |
| 216 | + * or the exchange handler may then access these objects. | |
| 217 | + * <p> | |
| 218 | + * Each Filter class will document the attributes which they make | |
| 219 | + * available. | |
| 220 | + * @param name the name of the attribute to retrieve | |
| 221 | + * @return the attribute object, or null if it does not exist | |
| 222 | + * @throws NullPointerException if name is <code>null</code> | |
| 223 | + */ | |
| 224 | + public abstract Object getAttribute (String name) ; | |
| 225 | + | |
| 226 | + /** | |
| 227 | + * Filter modules may store arbitrary objects with HttpExchange | |
| 228 | + * instances as an out-of-band communication mechanism. Other Filters | |
| 229 | + * or the exchange handler may then access these objects. | |
| 230 | + * <p> | |
| 231 | + * Each Filter class will document the attributes which they make | |
| 232 | + * available. | |
| 233 | + * @param name the name to associate with the attribute value | |
| 234 | + * @param value the object to store as the attribute value. <code>null</code> | |
| 235 | + * value is permitted. | |
| 236 | + * @throws NullPointerException if name is <code>null</code> | |
| 237 | + */ | |
| 238 | + public abstract void setAttribute (String name, Object value) ; | |
| 239 | + | |
| 240 | + /** | |
| 241 | + * Used by Filters to wrap either (or both) of this exchange's InputStream | |
| 242 | + * and OutputStream, with the given filtered streams so | |
| 243 | + * that subsequent calls to {@link #getRequestBody()} will | |
| 244 | + * return the given {@link java.io.InputStream}, and calls to | |
| 245 | + * {@link #getResponseBody()} will return the given | |
| 246 | + * {@link java.io.OutputStream}. The streams provided to this | |
| 247 | + * call must wrap the original streams, and may be (but are not | |
| 248 | + * required to be) sub-classes of {@link java.io.FilterInputStream} | |
| 249 | + * and {@link java.io.FilterOutputStream}. | |
| 250 | + * @param i the filtered input stream to set as this object's inputstream, | |
| 251 | + * or <code>null</code> if no change. | |
| 252 | + * @param o the filtered output stream to set as this object's outputstream, | |
| 253 | + * or <code>null</code> if no change. | |
| 254 | + */ | |
| 255 | + public abstract void setStreams (InputStream i, OutputStream o); | |
| 256 | + | |
| 257 | + | |
| 258 | + /** | |
| 259 | + * If an authenticator is set on the HttpContext that owns this exchange, | |
| 260 | + * then this method will return the {@link HttpPrincipal} that represents | |
| 261 | + * the authenticated user for this HttpExchange. | |
| 262 | + * @return the HttpPrincipal, or <code>null</code> if no authenticator is set. | |
| 263 | + */ | |
| 264 | + public abstract HttpPrincipal getPrincipal (); | |
| 265 | +} | |
| @@ -0,0 +1,45 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | + | |
| 30 | +/** | |
| 31 | + * A handler which is invoked to process HTTP exchanges. Each | |
| 32 | + * HTTP exchange is handled by one of these handlers. | |
| 33 | + * @since 1.6 | |
| 34 | + */ | |
| 35 | +public interface HttpHandler { | |
| 36 | + /** | |
| 37 | + * Handle the given request and generate an appropriate response. | |
| 38 | + * See {@link HttpExchange} for a description of the steps | |
| 39 | + * involved in handling an exchange. | |
| 40 | + * @param exchange the exchange containing the request from the | |
| 41 | + * client and used to send the response | |
| 42 | + * @throws NullPointerException if exchange is <code>null</code> | |
| 43 | + */ | |
| 44 | + public abstract void handle (HttpExchange exchange) throws IOException; | |
| 45 | +} | |
| @@ -0,0 +1,104 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | +import java.net.*; | |
| 28 | +import java.io.*; | |
| 29 | +import java.util.*; | |
| 30 | +import java.security.Principal; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Represents a user authenticated by HTTP Basic or Digest | |
| 34 | + * authentication. | |
| 35 | + */ | |
| 36 | +public class HttpPrincipal implements Principal { | |
| 37 | + private String username, realm; | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * creates a HttpPrincipal from the given username and realm | |
| 41 | + * @param username The name of the user within the realm | |
| 42 | + * @param realm The realm. | |
| 43 | + * @throws NullPointerException if either username or realm are null | |
| 44 | + */ | |
| 45 | + public HttpPrincipal (String username, String realm) { | |
| 46 | + if (username == null || realm == null) { | |
| 47 | + throw new NullPointerException(); | |
| 48 | + } | |
| 49 | + this.username = username; | |
| 50 | + this.realm = realm; | |
| 51 | + } | |
| 52 | + | |
| 53 | + /** | |
| 54 | + * Compares two HttpPrincipal. Returns <code>true</code> | |
| 55 | + * if <i>another</i> is an instance of HttpPrincipal, and its | |
| 56 | + * username and realm are equal to this object's username | |
| 57 | + * and realm. Returns <code>false</code> otherwise. | |
| 58 | + */ | |
| 59 | + public boolean equals (Object another) { | |
| 60 | + if (!(another instanceof HttpPrincipal)) { | |
| 61 | + return false; | |
| 62 | + } | |
| 63 | + HttpPrincipal theother = (HttpPrincipal)another; | |
| 64 | + return (username.equals(theother.username) && | |
| 65 | + realm.equals(theother.realm)); | |
| 66 | + } | |
| 67 | + | |
| 68 | + /** | |
| 69 | + * returns the contents of this principal in the form | |
| 70 | + * <i>realm:username</i> | |
| 71 | + */ | |
| 72 | + public String getName() { | |
| 73 | + return username; | |
| 74 | + } | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * returns the username this object was created with. | |
| 78 | + */ | |
| 79 | + public String getUsername() { | |
| 80 | + return username; | |
| 81 | + } | |
| 82 | + | |
| 83 | + /** | |
| 84 | + * returns the realm this object was created with. | |
| 85 | + */ | |
| 86 | + public String getRealm() { | |
| 87 | + return realm; | |
| 88 | + } | |
| 89 | + | |
| 90 | + /** | |
| 91 | + * returns a hashcode for this HttpPrincipal. This is calculated | |
| 92 | + * as <code>(getUsername()+getRealm().hashCode()</code> | |
| 93 | + */ | |
| 94 | + public int hashCode() { | |
| 95 | + return (username+realm).hashCode(); | |
| 96 | + } | |
| 97 | + | |
| 98 | + /** | |
| 99 | + * returns the same string as getName() | |
| 100 | + */ | |
| 101 | + public String toString() { | |
| 102 | + return getName(); | |
| 103 | + } | |
| 104 | +} | |
| @@ -0,0 +1,254 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | + | |
| 28 | +import java.net.*; | |
| 29 | +import java.io.*; | |
| 30 | +import java.nio.*; | |
| 31 | +import java.security.*; | |
| 32 | +import java.nio.channels.*; | |
| 33 | +import java.util.*; | |
| 34 | +import java.util.concurrent.*; | |
| 35 | +import javax.net.ssl.*; | |
| 36 | +import com.sun.net.httpserver.spi.HttpServerProvider; | |
| 37 | + | |
| 38 | +/** | |
| 39 | + * This class implements a simple HTTP server. A HttpServer is bound to an IP address | |
| 40 | + * and port number and listens for incoming TCP connections from clients on this address. | |
| 41 | + * The sub-class {@link HttpsServer} implements a server which handles HTTPS requests. | |
| 42 | + * <p> | |
| 43 | + * One or more {@link HttpHandler} objects must be associated with a server | |
| 44 | + * in order to process requests. Each such HttpHandler is registered | |
| 45 | + * with a root URI path which represents the | |
| 46 | + * location of the application or service on this server. The mapping of a handler | |
| 47 | + * to a HttpServer is encapsulated by a {@link HttpContext} object. HttpContexts | |
| 48 | + * are created by calling {@link #createContext(String,HttpHandler)}. | |
| 49 | + * Any request for which no handler can be found is rejected with a 404 response. | |
| 50 | + * Management of threads can be done external to this object by providing a | |
| 51 | + * {@link java.util.concurrent.Executor} object. If none is provided a default | |
| 52 | + * implementation is used. | |
| 53 | + * <p> | |
| 54 | + * <a name="mapping_description"></a> | |
| 55 | + * <b>Mapping request URIs to HttpContext paths</b><p> | |
| 56 | + * When a HTTP request is received, | |
| 57 | + * the appropriate HttpContext (and handler) is located by finding the context | |
| 58 | + * whose path is the longest matching prefix of the request URI's path. | |
| 59 | + * Paths are matched literally, which means that the strings are compared | |
| 60 | + * case sensitively, and with no conversion to or from any encoded forms. | |
| 61 | + * For example. Given a HttpServer with the following HttpContexts configured.<p> | |
| 62 | + * <table > | |
| 63 | + * <tr><td><i>Context</i></td><td><i>Context path</i></td></tr> | |
| 64 | + * <tr><td>ctx1</td><td>"/"</td></tr> | |
| 65 | + * <tr><td>ctx2</td><td>"/apps/"</td></tr> | |
| 66 | + * <tr><td>ctx3</td><td>"/apps/foo/"</td></tr> | |
| 67 | + * </table> | |
| 68 | + * <p> | |
| 69 | + * the following table shows some request URIs and which, if any context they would | |
| 70 | + * match with.<p> | |
| 71 | + * <table> | |
| 72 | + * <tr><td><i>Request URI</i></td><td><i>Matches context</i></td></tr> | |
| 73 | + * <tr><td>"http://foo.com/apps/foo/bar"</td><td>ctx3</td></tr> | |
| 74 | + * <tr><td>"http://foo.com/apps/Foo/bar"</td><td>no match, wrong case</td></tr> | |
| 75 | + * <tr><td>"http://foo.com/apps/app1"</td><td>ctx2</td></tr> | |
| 76 | + * <tr><td>"http://foo.com/foo"</td><td>ctx1</td></tr> | |
| 77 | + * </table> | |
| 78 | + * <p> | |
| 79 | + * <b>Note about socket backlogs</b><p> | |
| 80 | + * When binding to an address and port number, the application can also specify an integer | |
| 81 | + * <i>backlog</i> parameter. This represents the maximum number of incoming TCP connections | |
| 82 | + * which the system will queue internally. Connections are queued while they are waiting to | |
| 83 | + * be accepted by the HttpServer. When the limit is reached, further connections may be | |
| 84 | + * rejected (or possibly ignored) by the underlying TCP implementation. Setting the right | |
| 85 | + * backlog value is a compromise between efficient resource usage in the TCP layer (not setting | |
| 86 | + * it too high) and allowing adequate throughput of incoming requests (not setting it too low). | |
| 87 | + * @since 1.6 | |
| 88 | + */ | |
| 89 | + | |
| 90 | +public abstract class HttpServer { | |
| 91 | + | |
| 92 | + /** | |
| 93 | + */ | |
| 94 | + protected HttpServer () { | |
| 95 | + } | |
| 96 | + | |
| 97 | + /** | |
| 98 | + * creates a HttpServer instance which is initially not bound to any local address/port. | |
| 99 | + * The HttpServer is acquired from the currently installed {@link HttpServerProvider} | |
| 100 | + * The server must be bound using {@link #bind(InetSocketAddress,int)} before it can be used. | |
| 101 | + * @throws IOException | |
| 102 | + */ | |
| 103 | + public static HttpServer create () throws IOException { | |
| 104 | + return create (null, 0); | |
| 105 | + } | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Create a <code>HttpServer</code> instance which will bind to the | |
| 109 | + * specified {@link java.net.InetSocketAddress} (IP address and port number) | |
| 110 | + * | |
| 111 | + * A maximum backlog can also be specified. This is the maximum number of | |
| 112 | + * queued incoming connections to allow on the listening socket. | |
| 113 | + * Queued TCP connections exceeding this limit may be rejected by the TCP implementation. | |
| 114 | + * The HttpServer is acquired from the currently installed {@link HttpServerProvider} | |
| 115 | + * | |
| 116 | + * @param addr the address to listen on, if <code>null</code> then bind() must be called | |
| 117 | + * to set the address | |
| 118 | + * @param backlog the socket backlog. If this value is less than or equal to zero, | |
| 119 | + * then a system default value is used. | |
| 120 | + * @throws BindException if the server cannot bind to the requested address, | |
| 121 | + * or if the server is already bound. | |
| 122 | + * @throws IOException | |
| 123 | + */ | |
| 124 | + | |
| 125 | + public static HttpServer create ( | |
| 126 | + InetSocketAddress addr, int backlog | |
| 127 | + ) throws IOException { | |
| 128 | + HttpServerProvider provider = HttpServerProvider.provider(); | |
| 129 | + return provider.createHttpServer (addr, backlog); | |
| 130 | + } | |
| 131 | + | |
| 132 | + /** | |
| 133 | + * Binds a currently unbound HttpServer to the given address and port number. | |
| 134 | + * A maximum backlog can also be specified. This is the maximum number of | |
| 135 | + * queued incoming connections to allow on the listening socket. | |
| 136 | + * Queued TCP connections exceeding this limit may be rejected by the TCP implementation. | |
| 137 | + * @param addr the address to listen on | |
| 138 | + * @param backlog the socket backlog. If this value is less than or equal to zero, | |
| 139 | + * then a system default value is used. | |
| 140 | + * @throws BindException if the server cannot bind to the requested address or if the server | |
| 141 | + * is already bound. | |
| 142 | + * @throws NullPointerException if addr is <code>null</code> | |
| 143 | + */ | |
| 144 | + public abstract void bind (InetSocketAddress addr, int backlog) throws IOException; | |
| 145 | + | |
| 146 | + /** | |
| 147 | + * Starts this server in a new background thread. The background thread | |
| 148 | + * inherits the priority, thread group and context class loader | |
| 149 | + * of the caller. | |
| 150 | + */ | |
| 151 | + public abstract void start () ; | |
| 152 | + | |
| 153 | + /** | |
| 154 | + * sets this server's {@link java.util.concurrent.Executor} object. An | |
| 155 | + * Executor must be established before {@link #start()} is called. | |
| 156 | + * All HTTP requests are handled in tasks given to the executor. | |
| 157 | + * If this method is not called (before start()) or if it is | |
| 158 | + * called with a <code>null</code> Executor, then | |
| 159 | + * a default implementation is used, which uses the thread | |
| 160 | + * which was created by the {@link #start()} method. | |
| 161 | + * @param executor the Executor to set, or <code>null</code> for default | |
| 162 | + * implementation | |
| 163 | + * @throws IllegalStateException if the server is already started | |
| 164 | + */ | |
| 165 | + public abstract void setExecutor (Executor executor); | |
| 166 | + | |
| 167 | + | |
| 168 | + /** | |
| 169 | + * returns this server's Executor object if one was specified with | |
| 170 | + * {@link #setExecutor(Executor)}, or <code>null</code> if none was | |
| 171 | + * specified. | |
| 172 | + * @return the Executor established for this server or <code>null</code> if not set. | |
| 173 | + */ | |
| 174 | + public abstract Executor getExecutor () ; | |
| 175 | + | |
| 176 | + /** | |
| 177 | + * stops this server by closing the listening socket and disallowing | |
| 178 | + * any new exchanges from being processed. The method will then block | |
| 179 | + * until all current exchange handlers have completed or else when | |
| 180 | + * approximately <i>delay</i> seconds have elapsed (whichever happens | |
| 181 | + * sooner). Then, all open TCP connections are closed, the background | |
| 182 | + * thread created by start() exits, and the method returns. | |
| 183 | + * Once stopped, a HttpServer cannot be re-used. <p> | |
| 184 | + * | |
| 185 | + * @param delay the maximum time in seconds to wait until exchanges have finished. | |
| 186 | + * @throws IllegalArgumentException if delay is less than zero. | |
| 187 | + */ | |
| 188 | + public abstract void stop (int delay); | |
| 189 | + | |
| 190 | + /** | |
| 191 | + * Creates a HttpContext. A HttpContext represents a mapping from a | |
| 192 | + * URI path to a exchange handler on this HttpServer. Once created, all requests | |
| 193 | + * received by the server for the path will be handled by calling | |
| 194 | + * the given handler object. The context is identified by the path, and | |
| 195 | + * can later be removed from the server using this with the {@link #removeContext(String)} method. | |
| 196 | + * <p> | |
| 197 | + * The path specifies the root URI path for this context. The first character of path must be | |
| 198 | + * '/'. <p> | |
| 199 | + * The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a> | |
| 200 | + * to HttpContext instances. | |
| 201 | + * @param path the root URI path to associate the context with | |
| 202 | + * @param handler the handler to invoke for incoming requests. | |
| 203 | + * @throws IllegalArgumentException if path is invalid, or if a context | |
| 204 | + * already exists for this path | |
| 205 | + * @throws NullPointerException if either path, or handler are <code>null</code> | |
| 206 | + */ | |
| 207 | + public abstract HttpContext createContext (String path, HttpHandler handler) ; | |
| 208 | + | |
| 209 | + /** | |
| 210 | + * Creates a HttpContext without initially specifying a handler. The handler must later be specified using | |
| 211 | + * {@link HttpContext#setHandler(HttpHandler)}. A HttpContext represents a mapping from a | |
| 212 | + * URI path to an exchange handler on this HttpServer. Once created, and when | |
| 213 | + * the handler has been set, all requests | |
| 214 | + * received by the server for the path will be handled by calling | |
| 215 | + * the handler object. The context is identified by the path, and | |
| 216 | + * can later be removed from the server using this with the {@link #removeContext(String)} method. | |
| 217 | + * <p> | |
| 218 | + * The path specifies the root URI path for this context. The first character of path must be | |
| 219 | + * '/'. <p> | |
| 220 | + * The class overview describes how incoming request URIs are <a href="#mapping_description">mapped</a> | |
| 221 | + * to HttpContext instances. | |
| 222 | + * @param path the root URI path to associate the context with | |
| 223 | + * @throws IllegalArgumentException if path is invalid, or if a context | |
| 224 | + * already exists for this path | |
| 225 | + * @throws NullPointerException if path is <code>null</code> | |
| 226 | + */ | |
| 227 | + public abstract HttpContext createContext (String path) ; | |
| 228 | + | |
| 229 | + /** | |
| 230 | + * Removes the context identified by the given path from the server. | |
| 231 | + * Removing a context does not affect exchanges currently being processed | |
| 232 | + * but prevents new ones from being accepted. | |
| 233 | + * @param path the path of the handler to remove | |
| 234 | + * @throws IllegalArgumentException if no handler corresponding to this | |
| 235 | + * path exists. | |
| 236 | + * @throws NullPointerException if path is <code>null</code> | |
| 237 | + */ | |
| 238 | + public abstract void removeContext (String path) throws IllegalArgumentException ; | |
| 239 | + | |
| 240 | + /** | |
| 241 | + * Removes the given context from the server. | |
| 242 | + * Removing a context does not affect exchanges currently being processed | |
| 243 | + * but prevents new ones from being accepted. | |
| 244 | + * @param context the context to remove | |
| 245 | + * @throws NullPointerException if context is <code>null</code> | |
| 246 | + */ | |
| 247 | + public abstract void removeContext (HttpContext context) ; | |
| 248 | + | |
| 249 | + /** | |
| 250 | + * returns the address this server is listening on | |
| 251 | + * @return the address/port number the server is listening on | |
| 252 | + */ | |
| 253 | + public abstract InetSocketAddress getAddress() ; | |
| 254 | +} | |
| @@ -0,0 +1,116 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | + | |
| 28 | +import java.net.*; | |
| 29 | +import java.io.*; | |
| 30 | +import java.nio.*; | |
| 31 | +import java.security.*; | |
| 32 | +import java.nio.channels.*; | |
| 33 | +import java.util.*; | |
| 34 | +import java.util.concurrent.*; | |
| 35 | +import javax.net.ssl.*; | |
| 36 | + | |
| 37 | + | |
| 38 | +/** | |
| 39 | + * This class is used to configure the https parameters for each incoming | |
| 40 | + * https connection on a HttpsServer. Applications need to override | |
| 41 | + * the {@link #configure(HttpsParameters)} method in order to change | |
| 42 | + * the default configuration. | |
| 43 | + * <p> | |
| 44 | + * The following <a name="example">example</a> shows how this may be done: | |
| 45 | + * <p> | |
| 46 | + * <pre><blockquote> | |
| 47 | + * SSLContext sslContext = SSLContext.getInstance (....); | |
| 48 | + * HttpsServer server = HttpsServer.create(); | |
| 49 | + * | |
| 50 | + * server.setHttpsConfigurator (new HttpsConfigurator(sslContext) { | |
| 51 | + * public void configure (HttpsParameters params) { | |
| 52 | + * | |
| 53 | + * // get the remote address if needed | |
| 54 | + * InetSocketAddress remote = params.getClientAddress(); | |
| 55 | + * | |
| 56 | + * SSLContext c = getSSLContext(); | |
| 57 | + * | |
| 58 | + * // get the default parameters | |
| 59 | + * SSLParameters sslparams = c.getDefaultSSLParameters(); | |
| 60 | + * if (remote.equals (...) ) { | |
| 61 | + * // modify the default set for client x | |
| 62 | + * } | |
| 63 | + * | |
| 64 | + * params.setSSLParameters(sslparams); | |
| 65 | + * } | |
| 66 | + * }); | |
| 67 | + * </blockquote></pre> | |
| 68 | + * @since 1.6 | |
| 69 | + */ | |
| 70 | +public class HttpsConfigurator { | |
| 71 | + | |
| 72 | + private SSLContext context; | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * Creates an Https configuration, with the given SSLContext. | |
| 76 | + * @param context the SSLContext to use for this configurator | |
| 77 | + * @throws NullPointerException if no SSLContext supplied | |
| 78 | + */ | |
| 79 | + public HttpsConfigurator (SSLContext context) { | |
| 80 | + if (context == null) { | |
| 81 | + throw new NullPointerException ("null SSLContext"); | |
| 82 | + } | |
| 83 | + this.context = context; | |
| 84 | + } | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * Returns the SSLContext for this HttpsConfigurator. | |
| 88 | + * @return the SSLContext | |
| 89 | + */ | |
| 90 | + public SSLContext getSSLContext() { | |
| 91 | + return context; | |
| 92 | + } | |
| 93 | + | |
| 94 | +//BEGIN_TIGER_EXCLUDE | |
| 95 | + /** | |
| 96 | + * Called by the HttpsServer to configure the parameters | |
| 97 | + * for a https connection currently being established. | |
| 98 | + * The implementation of configure() must call | |
| 99 | + * {@link HttpsParameters#setSSLParameters(SSLParameters)} | |
| 100 | + * in order to set the SSL parameters for the connection. | |
| 101 | + * <p> | |
| 102 | + * The default implementation of this method uses the | |
| 103 | + * SSLParameters returned from <p> | |
| 104 | + * <code>getSSLContext().getDefaultSSLParameters()</code> | |
| 105 | + * <p> | |
| 106 | + * configure() may be overridden in order to modify this behavior. | |
| 107 | + * See, the example <a href="#example">above</a>. | |
| 108 | + * @param params the HttpsParameters to be configured. | |
| 109 | + * | |
| 110 | + * @since 1.6 | |
| 111 | + */ | |
| 112 | + public void configure (HttpsParameters params) { | |
| 113 | + params.setSSLParameters (getSSLContext().getDefaultSSLParameters()); | |
| 114 | + } | |
| 115 | +//END_TIGER_EXCLUDE | |
| 116 | +} | |
| @@ -0,0 +1,52 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | + | |
| 28 | +import java.io.*; | |
| 29 | +import java.nio.*; | |
| 30 | +import java.nio.channels.*; | |
| 31 | +import java.net.*; | |
| 32 | +import javax.net.ssl.*; | |
| 33 | +import java.util.*; | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * This class encapsulates a HTTPS request received and a | |
| 37 | + * response to be generated in one exchange and defines | |
| 38 | + * the extensions to HttpExchange that are specific to the HTTPS protocol. | |
| 39 | + * @since 1.6 | |
| 40 | + */ | |
| 41 | + | |
| 42 | +public abstract class HttpsExchange extends HttpExchange { | |
| 43 | + | |
| 44 | + protected HttpsExchange () { | |
| 45 | + } | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * Get the SSLSession for this exchange. | |
| 49 | + * @return the SSLSession | |
| 50 | + */ | |
| 51 | + public abstract SSLSession getSSLSession (); | |
| 52 | +} | |
| @@ -0,0 +1,164 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | +import java.net.InetSocketAddress; | |
| 28 | +//BEGIN_TIGER_EXCLUDE | |
| 29 | +import javax.net.ssl.SSLParameters; | |
| 30 | +//END_TIGER_EXCLUDE | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Represents the set of parameters for each https | |
| 34 | + * connection negotiated with clients. One of these | |
| 35 | + * is created and passed to | |
| 36 | + * {@link HttpsConfigurator#configure(HttpsParameters)} | |
| 37 | + * for every incoming https connection, | |
| 38 | + * in order to determine the parameters to use. | |
| 39 | + * <p> | |
| 40 | + * The underlying SSL parameters may be established either | |
| 41 | + * via the set/get methods of this class, or else via | |
| 42 | + * a {@link javax.net.ssl.SSLParameters} object. SSLParameters | |
| 43 | + * is the preferred method, because in the future, | |
| 44 | + * additional configuration capabilities may be added to that class, and | |
| 45 | + * it is easier to determine the set of supported parameters and their | |
| 46 | + * default values with SSLParameters. Also, if an SSLParameters object is | |
| 47 | + * provided via | |
| 48 | + * {@link #setSSLParameters(SSLParameters)} then those parameter settings | |
| 49 | + * are used, and any settings made in this object are ignored. | |
| 50 | + * @since 1.6 | |
| 51 | + */ | |
| 52 | +public abstract class HttpsParameters { | |
| 53 | + | |
| 54 | + private String[] cipherSuites; | |
| 55 | + private String[] protocols; | |
| 56 | + private boolean wantClientAuth; | |
| 57 | + private boolean needClientAuth; | |
| 58 | + | |
| 59 | + protected HttpsParameters() {} | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * Returns the HttpsConfigurator for this HttpsParameters. | |
| 63 | + */ | |
| 64 | + public abstract HttpsConfigurator getHttpsConfigurator(); | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Returns the address of the remote client initiating the | |
| 68 | + * connection. | |
| 69 | + */ | |
| 70 | + public abstract InetSocketAddress getClientAddress(); | |
| 71 | + | |
| 72 | +//BEGIN_TIGER_EXCLUDE | |
| 73 | + /** | |
| 74 | + * Sets the SSLParameters to use for this HttpsParameters. | |
| 75 | + * The parameters must be supported by the SSLContext contained | |
| 76 | + * by the HttpsConfigurator associated with this HttpsParameters. | |
| 77 | + * If no parameters are set, then the default behavior is to use | |
| 78 | + * the default parameters from the associated SSLContext. | |
| 79 | + * @param params the SSLParameters to set. If <code>null</code> | |
| 80 | + * then the existing parameters (if any) remain unchanged. | |
| 81 | + * @throws IllegalArgumentException if any of the parameters are | |
| 82 | + * invalid or unsupported. | |
| 83 | + */ | |
| 84 | + public abstract void setSSLParameters (SSLParameters params); | |
| 85 | +//END_TIGER_EXCLUDE | |
| 86 | + | |
| 87 | + /** | |
| 88 | + * Returns a copy of the array of ciphersuites or null if none | |
| 89 | + * have been set. | |
| 90 | + * | |
| 91 | + * @return a copy of the array of ciphersuites or null if none | |
| 92 | + * have been set. | |
| 93 | + */ | |
| 94 | + public String[] getCipherSuites() { | |
| 95 | + return cipherSuites != null ? cipherSuites.clone() : null; | |
| 96 | + } | |
| 97 | + | |
| 98 | + /** | |
| 99 | + * Sets the array of ciphersuites. | |
| 100 | + * | |
| 101 | + * @param cipherSuites the array of ciphersuites (or null) | |
| 102 | + */ | |
| 103 | + public void setCipherSuites(String[] cipherSuites) { | |
| 104 | + this.cipherSuites = cipherSuites != null ? cipherSuites.clone() : null; | |
| 105 | + } | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Returns a copy of the array of protocols or null if none | |
| 109 | + * have been set. | |
| 110 | + * | |
| 111 | + * @return a copy of the array of protocols or null if none | |
| 112 | + * have been set. | |
| 113 | + */ | |
| 114 | + public String[] getProtocols() { | |
| 115 | + return protocols != null ? protocols.clone() : null; | |
| 116 | + } | |
| 117 | + | |
| 118 | + /** | |
| 119 | + * Sets the array of protocols. | |
| 120 | + * | |
| 121 | + * @param protocols the array of protocols (or null) | |
| 122 | + */ | |
| 123 | + public void setProtocols(String[] protocols) { | |
| 124 | + this.protocols = protocols != null ? protocols.clone() : null; | |
| 125 | + } | |
| 126 | + | |
| 127 | + /** | |
| 128 | + * Returns whether client authentication should be requested. | |
| 129 | + * | |
| 130 | + * @return whether client authentication should be requested. | |
| 131 | + */ | |
| 132 | + public boolean getWantClientAuth() { | |
| 133 | + return wantClientAuth; | |
| 134 | + } | |
| 135 | + | |
| 136 | + /** | |
| 137 | + * Sets whether client authentication should be requested. Calling | |
| 138 | + * this method clears the <code>needClientAuth</code> flag. | |
| 139 | + * | |
| 140 | + * @param wantClientAuth whether client authentication should be requested | |
| 141 | + */ | |
| 142 | + public void setWantClientAuth(boolean wantClientAuth) { | |
| 143 | + this.wantClientAuth = wantClientAuth; | |
| 144 | + } | |
| 145 | + | |
| 146 | + /** | |
| 147 | + * Returns whether client authentication should be required. | |
| 148 | + * | |
| 149 | + * @return whether client authentication should be required. | |
| 150 | + */ | |
| 151 | + public boolean getNeedClientAuth() { | |
| 152 | + return needClientAuth; | |
| 153 | + } | |
| 154 | + | |
| 155 | + /** | |
| 156 | + * Sets whether client authentication should be required. Calling | |
| 157 | + * this method clears the <code>wantClientAuth</code> flag. | |
| 158 | + * | |
| 159 | + * @param needClientAuth whether client authentication should be required | |
| 160 | + */ | |
| 161 | + public void setNeedClientAuth(boolean needClientAuth) { | |
| 162 | + this.needClientAuth = needClientAuth; | |
| 163 | + } | |
| 164 | +} | |
| @@ -0,0 +1,104 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver; | |
| 27 | + | |
| 28 | +import java.net.*; | |
| 29 | +import java.io.*; | |
| 30 | +import java.nio.*; | |
| 31 | +import java.security.*; | |
| 32 | +import java.nio.channels.*; | |
| 33 | +import java.util.*; | |
| 34 | +import java.util.concurrent.*; | |
| 35 | +import javax.net.ssl.*; | |
| 36 | +import com.sun.net.httpserver.spi.*; | |
| 37 | + | |
| 38 | +/** | |
| 39 | + * This class is an extension of {@link HttpServer} which provides | |
| 40 | + * support for HTTPS. <p> | |
| 41 | + * A HttpsServer must have an associated {@link HttpsConfigurator} object | |
| 42 | + * which is used to establish the SSL configuration for the SSL connections. | |
| 43 | + * <p> | |
| 44 | + * All other configuration is the same as for HttpServer. | |
| 45 | + * @since 1.6 | |
| 46 | + */ | |
| 47 | + | |
| 48 | +public abstract class HttpsServer extends HttpServer { | |
| 49 | + | |
| 50 | + /** | |
| 51 | + */ | |
| 52 | + protected HttpsServer () { | |
| 53 | + } | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * creates a HttpsServer instance which is initially not bound to any local address/port. | |
| 57 | + * The HttpsServer is acquired from the currently installed {@link HttpServerProvider} | |
| 58 | + * The server must be bound using {@link #bind(InetSocketAddress,int)} before it can be used. | |
| 59 | + * The server must also have a HttpsConfigurator established with {@link #setHttpsConfigurator(HttpsConfigurator)} | |
| 60 | + * @throws IOException | |
| 61 | + */ | |
| 62 | + public static HttpsServer create () throws IOException { | |
| 63 | + return create (null, 0); | |
| 64 | + } | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Create a <code>HttpsServer</code> instance which will bind to the | |
| 68 | + * specified {@link java.net.InetSocketAddress} (IP address and port number) | |
| 69 | + * | |
| 70 | + * A maximum backlog can also be specified. This is the maximum number of | |
| 71 | + * queued incoming connections to allow on the listening socket. | |
| 72 | + * Queued TCP connections exceeding this limit may be rejected by the TCP implementation. | |
| 73 | + * The HttpsServer is acquired from the currently installed {@link HttpServerProvider} | |
| 74 | + * The server must have a HttpsConfigurator established with {@link #setHttpsConfigurator(HttpsConfigurator)} | |
| 75 | + * | |
| 76 | + * @param addr the address to listen on, if <code>null</code> then bind() must be called | |
| 77 | + * to set the address | |
| 78 | + * @param backlog the socket backlog. If this value is less than or equal to zero, | |
| 79 | + * then a system default value is used. | |
| 80 | + * @throws BindException if the server cannot bind to the requested address, | |
| 81 | + * or if the server is already bound. | |
| 82 | + * @throws IOException | |
| 83 | + */ | |
| 84 | + | |
| 85 | + public static HttpsServer create ( | |
| 86 | + InetSocketAddress addr, int backlog | |
| 87 | + ) throws IOException { | |
| 88 | + HttpServerProvider provider = HttpServerProvider.provider(); | |
| 89 | + return provider.createHttpsServer (addr, backlog); | |
| 90 | + } | |
| 91 | + | |
| 92 | + /** | |
| 93 | + * Sets this server's {@link HttpsConfigurator} object. | |
| 94 | + * @param config the HttpsConfigurator to set | |
| 95 | + * @throws NullPointerException if config is null. | |
| 96 | + */ | |
| 97 | + public abstract void setHttpsConfigurator (HttpsConfigurator config) ; | |
| 98 | + | |
| 99 | + /** | |
| 100 | + * Gets this server's {@link HttpsConfigurator} object, if it has been set. | |
| 101 | + * @return the HttpsConfigurator for this server, or <code>null</code> if not set. | |
| 102 | + */ | |
| 103 | + public abstract HttpsConfigurator getHttpsConfigurator (); | |
| 104 | +} | |
| @@ -0,0 +1,25 @@ | ||
| 1 | +<../../../../../../mkconfig | |
| 2 | + | |
| 3 | +DIRS=\ | |
| 4 | + spi\ | |
| 5 | + | |
| 6 | +TARG=\ | |
| 7 | + Authenticator.dis\ | |
| 8 | + BasicAuthenticator.dis\ | |
| 9 | + Filter.dis\ | |
| 10 | + Headers.dis\ | |
| 11 | + HttpContext.dis\ | |
| 12 | + HttpExchange.dis\ | |
| 13 | + HttpHandler.dis\ | |
| 14 | + HttpPrincipal.dis\ | |
| 15 | + HttpsConfigurator.dis\ | |
| 16 | + HttpServer.dis\ | |
| 17 | + HttpsExchange.dis\ | |
| 18 | + HttpsParameters.dis\ | |
| 19 | + HttpsServer.dis\ | |
| 20 | + package-info.dis\ | |
| 21 | + | |
| 22 | +DISBIN=$ROOT/java/dis/java/java/com/sun/net/httpserver | |
| 23 | + | |
| 24 | +<$ROOT/mkfiles/mkjava | |
| 25 | +<$ROOT/mkfiles/mksubdirs | |
| @@ -0,0 +1,126 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +/** | |
| 27 | + Provides a simple high-level Http server API, which can be used to build | |
| 28 | + embedded HTTP servers. Both "http" and "https" are supported. The API provides | |
| 29 | + a partial implementation of RFC <a href="http://www.ietf.org/rfc/rfc2616.txt">2616</a> (HTTP 1.1) | |
| 30 | + and RFC <a href="http://www.ietf.org/rfc/rfc2818.txt">2818</a> (HTTP over TLS). | |
| 31 | + Any HTTP functionality not provided by this API can be implemented by application code | |
| 32 | + using the API. | |
| 33 | + <p> | |
| 34 | + Programmers must implement the {@link com.sun.net.httpserver.HttpHandler} interface. This interface | |
| 35 | + provides a callback which is invoked to handle incoming requests from clients. | |
| 36 | + A HTTP request and its response is known as an exchange. HTTP exchanges are | |
| 37 | + represented by the {@link com.sun.net.httpserver.HttpExchange} class. | |
| 38 | + The {@link com.sun.net.httpserver.HttpServer} class is used to listen for incoming TCP connections | |
| 39 | + and it dispatches requests on these connections to handlers which have been | |
| 40 | + registered with the server. | |
| 41 | + <p> | |
| 42 | + A minimal Http server example is shown below: | |
| 43 | + <blockquote><pre> | |
| 44 | + class MyHandler implements HttpHandler { | |
| 45 | + public void handle(HttpExchange t) throws IOException { | |
| 46 | + InputStream is = t.getRequestBody(); | |
| 47 | + read(is); // .. read the request body | |
| 48 | + String response = "This is the response"; | |
| 49 | + t.sendResponseHeaders(200, response.length()); | |
| 50 | + OutputStream os = t.getResponseBody(); | |
| 51 | + os.write(response.getBytes()); | |
| 52 | + os.close(); | |
| 53 | + } | |
| 54 | + } | |
| 55 | + ... | |
| 56 | + | |
| 57 | + HttpServer server = HttpServer.create(new InetSocketAddress(8000)); | |
| 58 | + server.createContext("/applications/myapp", new MyHandler()); | |
| 59 | + server.setExecutor(null); // creates a default executor | |
| 60 | + server.start(); | |
| 61 | + </blockquote></pre> | |
| 62 | + <p>The example above creates a simple HttpServer which uses the calling | |
| 63 | + application thread to invoke the handle() method for incoming http | |
| 64 | + requests directed to port 8000, and to the path /applications/myapp/. | |
| 65 | + <p> | |
| 66 | + The {@link com.sun.net.httpserver.HttpExchange} class encapsulates everything an application needs to | |
| 67 | + process incoming requests and to generate appropriate responses. | |
| 68 | + <p> | |
| 69 | + Registering a handler with a HttpServer creates a {@link com.sun.net.httpserver.HttpContext} object and | |
| 70 | + {@link com.sun.net.httpserver.Filter} | |
| 71 | + objects can be added to the returned context. Filters are used to perform automatic pre- and | |
| 72 | + post-processing of exchanges before they are passed to the exchange handler. | |
| 73 | + <p> | |
| 74 | + For sensitive information, a {@link com.sun.net.httpserver.HttpsServer} can | |
| 75 | + be used to process "https" requests secured by the SSL or TLS protocols. | |
| 76 | + A HttpsServer must be provided with a | |
| 77 | + {@link com.sun.net.httpserver.HttpsConfigurator} object, which contains an | |
| 78 | + initialized {@link javax.net.ssl.SSLContext}. | |
| 79 | + HttpsConfigurator can be used to configure the | |
| 80 | + cipher suites and other SSL operating parameters. | |
| 81 | + A simple example SSLContext could be created as follows: | |
| 82 | + <blockquote><pre> | |
| 83 | + char[] passphrase = "passphrase".toCharArray(); | |
| 84 | + KeyStore ks = KeyStore.getInstance("JKS"); | |
| 85 | + ks.load(new FileInputStream("testkeys"), passphrase); | |
| 86 | + | |
| 87 | + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); | |
| 88 | + kmf.init(ks, passphrase); | |
| 89 | + | |
| 90 | + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); | |
| 91 | + tmf.init(ks); | |
| 92 | + | |
| 93 | + SSLContext ssl = SSLContext.getInstance("TLS"); | |
| 94 | + ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); | |
| 95 | + </blockquote></pre> | |
| 96 | + <p> | |
| 97 | + In the example above, a keystore file called "testkeys", created with the keytool utility | |
| 98 | + is used as a certificate store for client and server certificates. | |
| 99 | + The following code shows how the SSLContext is then used in a HttpsConfigurator | |
| 100 | + and how the SSLContext and HttpsConfigurator are linked to the HttpsServer. | |
| 101 | + <blockquote><pre> | |
| 102 | + server.setHttpsConfigurator (new HttpsConfigurator(sslContext) { | |
| 103 | + public void configure (HttpsParameters params) { | |
| 104 | + | |
| 105 | + // get the remote address if needed | |
| 106 | + InetSocketAddress remote = params.getClientAddress(); | |
| 107 | + | |
| 108 | + SSLContext c = getSSLContext(); | |
| 109 | + | |
| 110 | + // get the default parameters | |
| 111 | + SSLParameters sslparams = c.getDefaultSSLParameters(); | |
| 112 | + if (remote.equals (...) ) { | |
| 113 | + // modify the default set for client x | |
| 114 | + } | |
| 115 | + | |
| 116 | + params.setSSLParameters(sslparams); | |
| 117 | + // statement above could throw IAE if any params invalid. | |
| 118 | + // eg. if app has a UI and parameters supplied by a user. | |
| 119 | + | |
| 120 | + } | |
| 121 | + }); | |
| 122 | + </blockquote></pre> | |
| 123 | + <p> | |
| 124 | + @since 1.6 | |
| 125 | + */ | |
| 126 | +package com.sun.net.httpserver; | |
| @@ -0,0 +1,171 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package com.sun.net.httpserver.spi; | |
| 27 | + | |
| 28 | +import java.io.FileDescriptor; | |
| 29 | +import java.io.IOException; | |
| 30 | +import java.net.*; | |
| 31 | +import java.security.AccessController; | |
| 32 | +import java.security.PrivilegedAction; | |
| 33 | +import java.util.Iterator; | |
| 34 | +import sun.misc.Service; | |
| 35 | +import sun.misc.ServiceConfigurationError; | |
| 36 | +import sun.security.action.GetPropertyAction; | |
| 37 | +import com.sun.net.httpserver.*; | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * Service provider class for HttpServer. | |
| 41 | + * Sub-classes of HttpServerProvider provide an implementation of {@link HttpServer} and | |
| 42 | + * associated classes. Applications do not normally use this class. | |
| 43 | + * See {@link #provider()} for how providers are found and loaded. | |
| 44 | + */ | |
| 45 | +public abstract class HttpServerProvider { | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * creates a HttpServer from this provider | |
| 49 | + * @param addr the address to bind to. May be <code>null</code> | |
| 50 | + * @param backlog the socket backlog. A value of <code>zero</code> means the systems default | |
| 51 | + */ | |
| 52 | + public abstract HttpServer createHttpServer (InetSocketAddress addr, int backlog) throws IOException; | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * creates a HttpsServer from this provider | |
| 56 | + * @param addr the address to bind to. May be <code>null</code> | |
| 57 | + * @param backlog the socket backlog. A value of <code>zero</code> means the systems default | |
| 58 | + */ | |
| 59 | + public abstract HttpsServer createHttpsServer (InetSocketAddress addr, int backlog) throws IOException; | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + private static final Object lock = new Object(); | |
| 64 | + private static HttpServerProvider provider = null; | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Initializes a new instance of this class. </p> | |
| 68 | + * | |
| 69 | + * @throws SecurityException | |
| 70 | + * If a security manager has been installed and it denies | |
| 71 | + * {@link RuntimePermission}<tt>("httpServerProvider")</tt> | |
| 72 | + */ | |
| 73 | + protected HttpServerProvider() { | |
| 74 | + SecurityManager sm = System.getSecurityManager(); | |
| 75 | + if (sm != null) | |
| 76 | + sm.checkPermission(new RuntimePermission("httpServerProvider")); | |
| 77 | + } | |
| 78 | + | |
| 79 | + private static boolean loadProviderFromProperty() { | |
| 80 | + String cn = System.getProperty("com.sun.net.httpserver.HttpServerProvider"); | |
| 81 | + if (cn == null) | |
| 82 | + return false; | |
| 83 | + try { | |
| 84 | + Class c = Class.forName(cn, true, | |
| 85 | + ClassLoader.getSystemClassLoader()); | |
| 86 | + provider = (HttpServerProvider)c.newInstance(); | |
| 87 | + return true; | |
| 88 | + } catch (ClassNotFoundException x) { | |
| 89 | + throw new ServiceConfigurationError(x); | |
| 90 | + } catch (IllegalAccessException x) { | |
| 91 | + throw new ServiceConfigurationError(x); | |
| 92 | + } catch (InstantiationException x) { | |
| 93 | + throw new ServiceConfigurationError(x); | |
| 94 | + } catch (SecurityException x) { | |
| 95 | + throw new ServiceConfigurationError(x); | |
| 96 | + } | |
| 97 | + } | |
| 98 | + | |
| 99 | + private static boolean loadProviderAsService() { | |
| 100 | + Iterator i = Service.providers(HttpServerProvider.class, | |
| 101 | + ClassLoader.getSystemClassLoader()); | |
| 102 | + for (;;) { | |
| 103 | + try { | |
| 104 | + if (!i.hasNext()) | |
| 105 | + return false; | |
| 106 | + provider = (HttpServerProvider)i.next(); | |
| 107 | + return true; | |
| 108 | + } catch (ServiceConfigurationError sce) { | |
| 109 | + if (sce.getCause() instanceof SecurityException) { | |
| 110 | + // Ignore the security exception, try the next provider | |
| 111 | + continue; | |
| 112 | + } | |
| 113 | + throw sce; | |
| 114 | + } | |
| 115 | + } | |
| 116 | + } | |
| 117 | + | |
| 118 | + /** | |
| 119 | + * Returns the system wide default HttpServerProvider for this invocation of | |
| 120 | + * the Java virtual machine. | |
| 121 | + * | |
| 122 | + * <p> The first invocation of this method locates the default provider | |
| 123 | + * object as follows: </p> | |
| 124 | + * | |
| 125 | + * <ol> | |
| 126 | + * | |
| 127 | + * <li><p> If the system property | |
| 128 | + * <tt>com.sun.net.httpserver.HttpServerProvider</tt> is defined then it is | |
| 129 | + * taken to be the fully-qualified name of a concrete provider class. | |
| 130 | + * The class is loaded and instantiated; if this process fails then an | |
| 131 | + * unspecified unchecked error or exception is thrown. </p></li> | |
| 132 | + * | |
| 133 | + * <li><p> If a provider class has been installed in a jar file that is | |
| 134 | + * visible to the system class loader, and that jar file contains a | |
| 135 | + * provider-configuration file named | |
| 136 | + * <tt>com.sun.net.httpserver.HttpServerProvider</tt> in the resource | |
| 137 | + * directory <tt>META-INF/services</tt>, then the first class name | |
| 138 | + * specified in that file is taken. The class is loaded and | |
| 139 | + * instantiated; if this process fails then an unspecified unchecked error or exception is | |
| 140 | + * thrown. </p></li> | |
| 141 | + * | |
| 142 | + * <li><p> Finally, if no provider has been specified by any of the above | |
| 143 | + * means then the system-default provider class is instantiated and the | |
| 144 | + * result is returned. </p></li> | |
| 145 | + * | |
| 146 | + * </ol> | |
| 147 | + * | |
| 148 | + * <p> Subsequent invocations of this method return the provider that was | |
| 149 | + * returned by the first invocation. </p> | |
| 150 | + * | |
| 151 | + * @return The system-wide default HttpServerProvider | |
| 152 | + */ | |
| 153 | + public static HttpServerProvider provider () { | |
| 154 | + synchronized (lock) { | |
| 155 | + if (provider != null) | |
| 156 | + return provider; | |
| 157 | + return (HttpServerProvider)AccessController | |
| 158 | + .doPrivileged(new PrivilegedAction<Object>() { | |
| 159 | + public Object run() { | |
| 160 | + if (loadProviderFromProperty()) | |
| 161 | + return provider; | |
| 162 | + if (loadProviderAsService()) | |
| 163 | + return provider; | |
| 164 | + provider = new sun.net.httpserver.DefaultHttpServerProvider(); | |
| 165 | + return provider; | |
| 166 | + } | |
| 167 | + }); | |
| 168 | + } | |
| 169 | + } | |
| 170 | + | |
| 171 | +} | |
| @@ -0,0 +1,9 @@ | ||
| 1 | +<../../../../../../../mkconfig | |
| 2 | + | |
| 3 | +TARG=\ | |
| 4 | + HttpServerProvider.dis\ | |
| 5 | + package-info.dis\ | |
| 6 | + | |
| 7 | +DISBIN=$ROOT/java/dis/java/java/com/sun/net/httpserver/spi | |
| 8 | + | |
| 9 | +<$ROOT/mkfiles/mkjava | |
| @@ -0,0 +1,30 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +/** | |
| 27 | + Provides a pluggable service provider interface, which allows the HTTP server | |
| 28 | + implementation to be replaced with other implementations. | |
| 29 | +*/ | |
| 30 | +package com.sun.net.httpserver.spi; | |