History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/net/httpserver (18 of 18352 files). Show all

Unified · Split

18 files
  1. java/pkg/com/sun/net/httpserver/Authenticator.java +125 −0
  2. java/pkg/com/sun/net/httpserver/BasicAuthenticator.java +309 −0
  3. java/pkg/com/sun/net/httpserver/Filter.java +119 −0
  4. java/pkg/com/sun/net/httpserver/Headers.java +183 −0
  5. java/pkg/com/sun/net/httpserver/HttpContext.java +112 −0
  6. java/pkg/com/sun/net/httpserver/HttpExchange.java +265 −0
  7. java/pkg/com/sun/net/httpserver/HttpHandler.java +45 −0
  8. java/pkg/com/sun/net/httpserver/HttpPrincipal.java +104 −0
  9. java/pkg/com/sun/net/httpserver/HttpServer.java +254 −0
  10. java/pkg/com/sun/net/httpserver/HttpsConfigurator.java +116 −0
  11. java/pkg/com/sun/net/httpserver/HttpsExchange.java +52 −0
  12. java/pkg/com/sun/net/httpserver/HttpsParameters.java +164 −0
  13. java/pkg/com/sun/net/httpserver/HttpsServer.java +104 −0
  14. java/pkg/com/sun/net/httpserver/mkfile +25 −0
  15. java/pkg/com/sun/net/httpserver/package-info.java +126 −0
  16. java/pkg/com/sun/net/httpserver/spi/HttpServerProvider.java +171 −0
  17. java/pkg/com/sun/net/httpserver/spi/mkfile +9 −0
  18. java/pkg/com/sun/net/httpserver/spi/package-info.java +30 −0
java/pkg/com/sun/net/httpserver/Authenticator.java+125−0
@@ -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+}
java/pkg/com/sun/net/httpserver/BasicAuthenticator.java+309−0
@@ -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+}
java/pkg/com/sun/net/httpserver/Filter.java+119−0
@@ -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+}
java/pkg/com/sun/net/httpserver/Headers.java+183−0
@@ -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}&lt;
33+ * {@link java.lang.String},{@link java.util.List}&lt;{@link java.lang.String}&gt;&gt;.
34+ * The keys are case-insensitive Strings representing the header names and
35+ * the value associated with each key is a {@link List}&lt;{@link String}&gt; 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+ }
java/pkg/com/sun/net/httpserver/HttpContext.java+112−0
@@ -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+}
java/pkg/com/sun/net/httpserver/HttpExchange.java+265−0
@@ -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+}
java/pkg/com/sun/net/httpserver/HttpHandler.java+45−0
@@ -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+}
java/pkg/com/sun/net/httpserver/HttpPrincipal.java+104−0
@@ -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+}
java/pkg/com/sun/net/httpserver/HttpServer.java+254−0
@@ -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+}
java/pkg/com/sun/net/httpserver/HttpsConfigurator.java+116−0
@@ -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+}
java/pkg/com/sun/net/httpserver/HttpsExchange.java+52−0
@@ -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+}
java/pkg/com/sun/net/httpserver/HttpsParameters.java+164−0
@@ -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+}
java/pkg/com/sun/net/httpserver/HttpsServer.java+104−0
@@ -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+}
java/pkg/com/sun/net/httpserver/mkfile+25−0
@@ -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
java/pkg/com/sun/net/httpserver/package-info.java+126−0
@@ -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;
java/pkg/com/sun/net/httpserver/spi/HttpServerProvider.java+171−0
@@ -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+}
java/pkg/com/sun/net/httpserver/spi/mkfile+9−0
@@ -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
java/pkg/com/sun/net/httpserver/spi/package-info.java+30−0
@@ -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;