--- a/jdk/make/sun/nio/cs/FILES_java.gmk Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/make/sun/nio/cs/FILES_java.gmk Thu Nov 18 19:17:43 2010 +0000
@@ -85,6 +85,7 @@
sun/io/ByteToCharCp500.java \
sun/io/ByteToCharCp737.java \
sun/io/ByteToCharCp775.java \
+ sun/io/ByteToCharCp833.java \
sun/io/ByteToCharCp834.java \
sun/io/ByteToCharCp838.java \
sun/io/ByteToCharCp850.java \
@@ -214,6 +215,7 @@
sun/io/CharToByteCp500.java \
sun/io/CharToByteCp737.java \
sun/io/CharToByteCp775.java \
+ sun/io/CharToByteCp833.java \
sun/io/CharToByteCp834.java \
sun/io/CharToByteCp838.java \
sun/io/CharToByteCp850.java \
@@ -331,6 +333,7 @@
sun/nio/cs/ext/IBM420.java \
sun/nio/cs/ext/IBM424.java \
sun/nio/cs/ext/IBM500.java \
+ sun/nio/cs/ext/IBM833.java \
sun/nio/cs/ext/IBM838.java \
sun/nio/cs/ext/IBM856.java \
sun/nio/cs/ext/IBM860.java \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/IBM833.c2b Thu Nov 18 19:17:43 2010 +0000
@@ -0,0 +1,94 @@
+0x5A U+FF01
+0x7F U+FF02
+0x7B U+FF03
+0x5B U+FF04
+0x6C U+FF05
+0x50 U+FF06
+0x7D U+FF07
+0x4D U+FF08
+0x5D U+FF09
+0x5C U+FF0A
+0x4E U+FF0B
+0x6B U+FF0C
+0x60 U+FF0D
+0x4B U+FF0E
+0x61 U+FF0F
+0xF0 U+FF10
+0xF1 U+FF11
+0xF2 U+FF12
+0xF3 U+FF13
+0xF4 U+FF14
+0xF5 U+FF15
+0xF6 U+FF16
+0xF7 U+FF17
+0xF8 U+FF18
+0xF9 U+FF19
+0x7A U+FF1A
+0x5E U+FF1B
+0x4C U+FF1C
+0x7E U+FF1D
+0x6E U+FF1E
+0x6F U+FF1F
+0x7C U+FF20
+0xC1 U+FF21
+0xC2 U+FF22
+0xC3 U+FF23
+0xC4 U+FF24
+0xC5 U+FF25
+0xC6 U+FF26
+0xC7 U+FF27
+0xC8 U+FF28
+0xC9 U+FF29
+0xD1 U+FF2A
+0xD2 U+FF2B
+0xD3 U+FF2C
+0xD4 U+FF2D
+0xD5 U+FF2E
+0xD6 U+FF2F
+0xD7 U+FF30
+0xD8 U+FF31
+0xD9 U+FF32
+0xE2 U+FF33
+0xE3 U+FF34
+0xE4 U+FF35
+0xE5 U+FF36
+0xE6 U+FF37
+0xE7 U+FF38
+0xE8 U+FF39
+0xE9 U+FF3A
+0x70 U+FF3B
+0xB2 U+FF3C
+0x80 U+FF3D
+0xB0 U+FF3E
+0x6D U+FF3F
+0x79 U+FF40
+0x81 U+FF41
+0x82 U+FF42
+0x83 U+FF43
+0x84 U+FF44
+0x85 U+FF45
+0x86 U+FF46
+0x87 U+FF47
+0x88 U+FF48
+0x89 U+FF49
+0x91 U+FF4A
+0x92 U+FF4B
+0x93 U+FF4C
+0x94 U+FF4D
+0x95 U+FF4E
+0x96 U+FF4F
+0x97 U+FF50
+0x98 U+FF51
+0x99 U+FF52
+0xA2 U+FF53
+0xA3 U+FF54
+0xA4 U+FF55
+0xA5 U+FF56
+0xA6 U+FF57
+0xA7 U+FF58
+0xA8 U+FF59
+0xA9 U+FF5A
+0xC0 U+FF5B
+0x4F U+FF5C
+0xD0 U+FF5D
+0xA1 U+FF5E
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/tools/CharsetMapping/IBM833.map Thu Nov 18 19:17:43 2010 +0000
@@ -0,0 +1,217 @@
+0x00 U+0000
+0x01 U+0001
+0x02 U+0002
+0x03 U+0003
+0x37 U+0004
+0x2D U+0005
+0x2E U+0006
+0x2F U+0007
+0x16 U+0008
+0x05 U+0009
+0x25 U+000A
+0x0B U+000B
+0x0C U+000C
+0x0D U+000D
+0x0E U+000E
+0x0F U+000F
+0x10 U+0010
+0x11 U+0011
+0x12 U+0012
+0x13 U+0013
+0x3C U+0014
+0x3D U+0015
+0x32 U+0016
+0x26 U+0017
+0x18 U+0018
+0x19 U+0019
+0x3F U+001A
+0x27 U+001B
+0x1C U+001C
+0x1D U+001D
+0x1E U+001E
+0x1F U+001F
+0x40 U+0020
+0x5A U+0021
+0x7F U+0022
+0x7B U+0023
+0x5B U+0024
+0x6C U+0025
+0x50 U+0026
+0x7D U+0027
+0x4D U+0028
+0x5D U+0029
+0x5C U+002A
+0x4E U+002B
+0x6B U+002C
+0x60 U+002D
+0x4B U+002E
+0x61 U+002F
+0xF0 U+0030
+0xF1 U+0031
+0xF2 U+0032
+0xF3 U+0033
+0xF4 U+0034
+0xF5 U+0035
+0xF6 U+0036
+0xF7 U+0037
+0xF8 U+0038
+0xF9 U+0039
+0x7A U+003A
+0x5E U+003B
+0x4C U+003C
+0x7E U+003D
+0x6E U+003E
+0x6F U+003F
+0x7C U+0040
+0xC1 U+0041
+0xC2 U+0042
+0xC3 U+0043
+0xC4 U+0044
+0xC5 U+0045
+0xC6 U+0046
+0xC7 U+0047
+0xC8 U+0048
+0xC9 U+0049
+0xD1 U+004A
+0xD2 U+004B
+0xD3 U+004C
+0xD4 U+004D
+0xD5 U+004E
+0xD6 U+004F
+0xD7 U+0050
+0xD8 U+0051
+0xD9 U+0052
+0xE2 U+0053
+0xE3 U+0054
+0xE4 U+0055
+0xE5 U+0056
+0xE6 U+0057
+0xE7 U+0058
+0xE8 U+0059
+0xE9 U+005A
+0x70 U+005B
+0xB2 U+005C
+0x80 U+005D
+0xB0 U+005E
+0x6D U+005F
+0x79 U+0060
+0x81 U+0061
+0x82 U+0062
+0x83 U+0063
+0x84 U+0064
+0x85 U+0065
+0x86 U+0066
+0x87 U+0067
+0x88 U+0068
+0x89 U+0069
+0x91 U+006A
+0x92 U+006B
+0x93 U+006C
+0x94 U+006D
+0x95 U+006E
+0x96 U+006F
+0x97 U+0070
+0x98 U+0071
+0x99 U+0072
+0xA2 U+0073
+0xA3 U+0074
+0xA4 U+0075
+0xA5 U+0076
+0xA6 U+0077
+0xA7 U+0078
+0xA8 U+0079
+0xA9 U+007A
+0xC0 U+007B
+0x4F U+007C
+0xD0 U+007D
+0xA1 U+007E
+0x07 U+007F
+0x20 U+0080
+0x21 U+0081
+0x22 U+0082
+0x23 U+0083
+0x24 U+0084
+0x15 U+0085
+0x06 U+0086
+0x17 U+0087
+0x28 U+0088
+0x29 U+0089
+0x2A U+008A
+0x2B U+008B
+0x2C U+008C
+0x09 U+008D
+0x0A U+008E
+0x1B U+008F
+0x30 U+0090
+0x31 U+0091
+0x1A U+0092
+0x33 U+0093
+0x34 U+0094
+0x35 U+0095
+0x36 U+0096
+0x08 U+0097
+0x38 U+0098
+0x39 U+0099
+0x3A U+009A
+0x3B U+009B
+0x04 U+009C
+0x14 U+009D
+0x3E U+009E
+0xFF U+009F
+0x4A U+00A2
+0x6A U+00A6
+0x5F U+00AC
+0xA0 U+203E
+0xE0 U+20A9
+0x42 U+FFA0
+0x43 U+FFA1
+0x44 U+FFA2
+0x45 U+FFA3
+0x46 U+FFA4
+0x47 U+FFA5
+0x48 U+FFA6
+0x49 U+FFA7
+0x52 U+FFA8
+0x53 U+FFA9
+0x54 U+FFAA
+0x55 U+FFAB
+0x56 U+FFAC
+0x57 U+FFAD
+0x58 U+FFAE
+0x59 U+FFAF
+0x62 U+FFB0
+0x63 U+FFB1
+0x64 U+FFB2
+0x65 U+FFB3
+0x66 U+FFB4
+0x67 U+FFB5
+0x68 U+FFB6
+0x69 U+FFB7
+0x72 U+FFB8
+0x73 U+FFB9
+0x74 U+FFBA
+0x75 U+FFBB
+0x76 U+FFBC
+0x77 U+FFBD
+0x78 U+FFBE
+0x8A U+FFC2
+0x8B U+FFC3
+0x8C U+FFC4
+0x8D U+FFC5
+0x8E U+FFC6
+0x8F U+FFC7
+0x9A U+FFCA
+0x9B U+FFCB
+0x9C U+FFCC
+0x9D U+FFCD
+0x9E U+FFCE
+0x9F U+FFCF
+0xAA U+FFD2
+0xAB U+FFD3
+0xAC U+FFD4
+0xAD U+FFD5
+0xAE U+FFD6
+0xAF U+FFD7
+0xBA U+FFDA
+0xBB U+FFDB
+0xBC U+FFDC
--- a/jdk/make/tools/CharsetMapping/extsbcs Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/make/tools/CharsetMapping/extsbcs Thu Nov 18 19:17:43 2010 +0000
@@ -32,6 +32,7 @@
IBM420 IBM420 Cp420 false sun.nio.cs.ext
IBM424 IBM424 Cp424 false sun.nio.cs.ext
IBM500 IBM500 Cp500 false sun.nio.cs.ext
+IBM833 IBM833 Cp833 false sun.nio.cs.ext
IBM838 IBM-Thai Cp838 false sun.nio.cs.ext
IBM856 x-IBM856 Cp856 false sun.nio.cs.ext
IBM860 IBM860 Cp860 false sun.nio.cs.ext
--- a/jdk/src/share/classes/com/sun/net/httpserver/HttpsConfigurator.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/com/sun/net/httpserver/HttpsConfigurator.java Thu Nov 18 19:17:43 2010 +0000
@@ -91,6 +91,7 @@
return context;
}
+//BEGIN_TIGER_EXCLUDE
/**
* Called by the HttpsServer to configure the parameters
* for a https connection currently being established.
@@ -111,4 +112,5 @@
public void configure (HttpsParameters params) {
params.setSSLParameters (getSSLContext().getDefaultSSLParameters());
}
+//END_TIGER_EXCLUDE
}
--- a/jdk/src/share/classes/com/sun/net/httpserver/HttpsParameters.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/com/sun/net/httpserver/HttpsParameters.java Thu Nov 18 19:17:43 2010 +0000
@@ -25,7 +25,9 @@
package com.sun.net.httpserver;
import java.net.InetSocketAddress;
+//BEGIN_TIGER_EXCLUDE
import javax.net.ssl.SSLParameters;
+//END_TIGER_EXCLUDE
/**
* Represents the set of parameters for each https
@@ -67,6 +69,7 @@
*/
public abstract InetSocketAddress getClientAddress();
+//BEGIN_TIGER_EXCLUDE
/**
* Sets the SSLParameters to use for this HttpsParameters.
* The parameters must be supported by the SSLContext contained
@@ -79,6 +82,7 @@
* invalid or unsupported.
*/
public abstract void setSSLParameters (SSLParameters params);
+//END_TIGER_EXCLUDE
/**
* Returns a copy of the array of ciphersuites or null if none
--- a/jdk/src/share/classes/java/util/Formatter.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/java/util/Formatter.java Thu Nov 18 19:17:43 2010 +0000
@@ -1581,6 +1581,7 @@
* instance of the Java virtual machine.
*
* <tr><td valign="top">{@code 'Z'}
+ * <td valign="top"> <tt>'\u005a'</tt>
* <td> A string representing the abbreviation for the time zone. This
* value will be adjusted as necessary for Daylight Saving Time. For
* {@code long}, {@link Long}, and {@link Date} the time zone used is
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/io/ByteToCharCp833.java Thu Nov 18 19:17:43 2010 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.io;
+
+import sun.nio.cs.ext.IBM833;
+
+public class ByteToCharCp833 extends ByteToCharSingleByte {
+
+ private final static IBM833 nioCoder = new IBM833();
+
+ public String getCharacterEncoding() {
+ return "Cp833";
+ }
+
+ public ByteToCharCp833() {
+ super.byteToCharTable = nioCoder.getDecoderSingleByteMappings();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/io/CharToByteCp833.java Thu Nov 18 19:17:43 2010 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.io;
+
+import sun.nio.cs.ext.IBM833;
+
+public class CharToByteCp833 extends CharToByteSingleByte {
+
+ private final static IBM833 nioCoder = new IBM833();
+
+ public String getCharacterEncoding() {
+ return "Cp833";
+ }
+
+ public CharToByteCp833() {
+ super.mask1 = 0xFF00;
+ super.mask2 = 0x00FF;
+ super.shift = 8;
+ super.index1 = nioCoder.getEncoderIndex1();
+ super.index2 = nioCoder.getEncoderIndex2();
+ }
+}
+
--- a/jdk/src/share/classes/sun/io/CharacterEncoding.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/io/CharacterEncoding.java Thu Nov 18 19:17:43 2010 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -406,6 +406,11 @@
aliasTable.put("cp775", "Cp775");
aliasTable.put("775", "Cp775");
+ aliasTable.put("ibm833", "Cp833");
+ aliasTable.put("ibm-833", "Cp833");
+ aliasTable.put("cp833", "Cp833");
+ aliasTable.put("833", "Cp833");
+
aliasTable.put("ibm834", "Cp834");
aliasTable.put("ibm-834", "Cp834");
aliasTable.put("cp834", "Cp834");
--- a/jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java Thu Nov 18 19:17:43 2010 +0000
@@ -110,6 +110,7 @@
if (remaining == 0) {
eof = true;
consumeCRLF();
+ t.getServerImpl().requestCompleted (t.getConnection());
return -1;
}
needToReadHeader = false;
--- a/jdk/src/share/classes/sun/net/httpserver/Event.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/net/httpserver/Event.java Thu Nov 18 19:17:43 2010 +0000
@@ -40,5 +40,7 @@
class WriteFinishedEvent extends Event {
WriteFinishedEvent (ExchangeImpl t) {
super (t);
+ assert !t.writefinished;
+ t.writefinished = true;
}
}
--- a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Thu Nov 18 19:17:43 2010 +0000
@@ -38,6 +38,7 @@
Headers reqHdrs, rspHdrs;
Request req;
String method;
+ boolean writefinished;
URI uri;
HttpConnection connection;
long reqContentLen;
--- a/jdk/src/share/classes/sun/net/httpserver/FixedLengthInputStream.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/net/httpserver/FixedLengthInputStream.java Thu Nov 18 19:17:43 2010 +0000
@@ -56,6 +56,9 @@
int n = in.read(b, off, len);
if (n > -1) {
remaining -= n;
+ if (remaining == 0) {
+ t.getServerImpl().requestCompleted (t.getConnection());
+ }
}
return n;
}
--- a/jdk/src/share/classes/sun/net/httpserver/HttpConnection.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/net/httpserver/HttpConnection.java Thu Nov 18 19:17:43 2010 +0000
@@ -55,10 +55,15 @@
SelectionKey selectionKey;
String protocol;
long time;
+ volatile long creationTime; // time this connection was created
+ volatile long rspStartedTime; // time we started writing the response
int remaining;
boolean closed = false;
Logger logger;
+ public enum State {IDLE, REQUEST, RESPONSE};
+ volatile State state;
+
public String toString() {
String s = null;
if (chan != null) {
@@ -78,6 +83,14 @@
context = ctx;
}
+ State getState() {
+ return state;
+ }
+
+ void setState (State s) {
+ state = s;
+ }
+
void setParameters (
InputStream in, OutputStream rawout, SocketChannel chan,
SSLEngine engine, SSLStreams sslStreams, SSLContext sslContext, String protocol,
--- a/jdk/src/share/classes/sun/net/httpserver/Request.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/net/httpserver/Request.java Thu Nov 18 19:17:43 2010 +0000
@@ -201,32 +201,22 @@
static class ReadStream extends InputStream {
SocketChannel channel;
- SelectorCache sc;
- Selector selector;
ByteBuffer chanbuf;
- SelectionKey key;
- int available;
byte[] one;
- boolean closed = false, eof = false;
+ private boolean closed = false, eof = false;
ByteBuffer markBuf; /* reads may be satisifed from this buffer */
boolean marked;
boolean reset;
int readlimit;
static long readTimeout;
ServerImpl server;
-
- static {
- readTimeout = ServerConfig.getReadTimeout();
- }
+ final static int BUFSIZE = 8 * 1024;
public ReadStream (ServerImpl server, SocketChannel chan) throws IOException {
this.channel = chan;
this.server = server;
- sc = SelectorCache.getSelectorCache();
- selector = sc.getSelector();
- chanbuf = ByteBuffer.allocate (8* 1024);
- key = chan.register (selector, SelectionKey.OP_READ);
- available = 0;
+ chanbuf = ByteBuffer.allocate (BUFSIZE);
+ chanbuf.clear();
one = new byte[1];
closed = marked = reset = false;
}
@@ -255,6 +245,12 @@
return -1;
}
+ assert channel.isBlocking();
+
+ if (off < 0 || srclen < 0|| srclen > (b.length-off)) {
+ throw new IndexOutOfBoundsException ();
+ }
+
if (reset) { /* satisfy from markBuf */
canreturn = markBuf.remaining ();
willreturn = canreturn>srclen ? srclen : canreturn;
@@ -263,17 +259,19 @@
reset = false;
}
} else { /* satisfy from channel */
- canreturn = available();
- while (canreturn == 0 && !eof) {
- block ();
- canreturn = available();
+ chanbuf.clear ();
+ if (srclen < BUFSIZE) {
+ chanbuf.limit (srclen);
}
- if (eof) {
+ do {
+ willreturn = channel.read (chanbuf);
+ } while (willreturn == 0);
+ if (willreturn == -1) {
+ eof = true;
return -1;
}
- willreturn = canreturn>srclen ? srclen : canreturn;
+ chanbuf.flip ();
chanbuf.get(b, off, willreturn);
- available -= willreturn;
if (marked) { /* copy into markBuf */
try {
@@ -286,6 +284,11 @@
return willreturn;
}
+ public boolean markSupported () {
+ return true;
+ }
+
+ /* Does not query the OS socket */
public synchronized int available () throws IOException {
if (closed)
throw new IOException ("Stream is closed");
@@ -296,36 +299,7 @@
if (reset)
return markBuf.remaining();
- if (available > 0)
- return available;
-
- chanbuf.clear ();
- available = channel.read (chanbuf);
- if (available > 0) {
- chanbuf.flip();
- } else if (available == -1) {
- eof = true;
- available = 0;
- }
- return available;
- }
-
- /**
- * block() only called when available==0 and buf is empty
- */
- private synchronized void block () throws IOException {
- long currtime = server.getTime();
- long maxtime = currtime + readTimeout;
-
- while (currtime < maxtime) {
- if (selector.select (readTimeout) == 1) {
- selector.selectedKeys().clear();
- available ();
- return;
- }
- currtime = server.getTime();
- }
- throw new SocketTimeoutException ("no data received");
+ return chanbuf.remaining();
}
public void close () throws IOException {
@@ -333,8 +307,6 @@
return;
}
channel.close ();
- selector.selectNow();
- sc.freeSelector(selector);
closed = true;
}
@@ -362,23 +334,14 @@
SocketChannel channel;
ByteBuffer buf;
SelectionKey key;
- SelectorCache sc;
- Selector selector;
boolean closed;
byte[] one;
ServerImpl server;
- static long writeTimeout;
-
- static {
- writeTimeout = ServerConfig.getWriteTimeout();
- }
public WriteStream (ServerImpl server, SocketChannel channel) throws IOException {
this.channel = channel;
this.server = server;
- sc = SelectorCache.getSelectorCache();
- selector = sc.getSelector();
- key = channel.register (selector, SelectionKey.OP_WRITE);
+ assert channel.isBlocking();
closed = false;
one = new byte [1];
buf = ByteBuffer.allocate (4096);
@@ -411,31 +374,14 @@
l -= n;
if (l == 0)
return;
- block();
}
}
- void block () throws IOException {
- long currtime = server.getTime();
- long maxtime = currtime + writeTimeout;
-
- while (currtime < maxtime) {
- if (selector.select (writeTimeout) == 1) {
- selector.selectedKeys().clear ();
- return;
- }
- currtime = server.getTime();
- }
- throw new SocketTimeoutException ("write blocked too long");
- }
-
-
public void close () throws IOException {
if (closed)
return;
+ //server.logStackTrace ("Request.OS.close: isOpen="+channel.isOpen());
channel.close ();
- selector.selectNow();
- sc.freeSelector(selector);
closed = true;
}
}
--- a/jdk/src/share/classes/sun/net/httpserver/SSLStreams.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/net/httpserver/SSLStreams.java Thu Nov 18 19:17:43 2010 +0000
@@ -53,8 +53,6 @@
EngineWrapper wrapper;
OutputStream os;
InputStream is;
- static long readTimeout = ServerConfig.getReadTimeout();
- static long writeTimeout = ServerConfig.getWriteTimeout();
/* held by thread doing the hand-shake on this connection */
Lock handshaking = new ReentrantLock();
@@ -77,10 +75,13 @@
if (cfg != null) {
Parameters params = new Parameters (cfg, addr);
cfg.configure (params);
+//BEGIN_TIGER_EXCLUDE
SSLParameters sslParams = params.getSSLParameters();
if (sslParams != null) {
engine.setSSLParameters (sslParams);
- } else {
+ } else
+//END_TIGER_EXCLUDE
+ {
/* tiger compatibility */
if (params.getCipherSuites() != null) {
try {
@@ -104,7 +105,6 @@
class Parameters extends HttpsParameters {
InetSocketAddress addr;
- SSLParameters params;
HttpsConfigurator cfg;
Parameters (HttpsConfigurator cfg, InetSocketAddress addr) {
@@ -117,12 +117,15 @@
public HttpsConfigurator getHttpsConfigurator() {
return cfg;
}
+//BEGIN_TIGER_EXCLUDE
+ SSLParameters params;
public void setSSLParameters (SSLParameters p) {
params = p;
}
SSLParameters getSSLParameters () {
return params;
}
+//END_TIGER_EXCLUDE
}
/**
@@ -245,9 +248,6 @@
SocketChannel chan;
SSLEngine engine;
- SelectorCache sc;
- Selector write_selector, read_selector;
- SelectionKey wkey, rkey;
Object wrapLock, unwrapLock;
ByteBuffer unwrap_src, wrap_dst;
boolean closed = false;
@@ -260,16 +260,9 @@
unwrapLock = new Object();
unwrap_src = allocate(BufType.PACKET);
wrap_dst = allocate(BufType.PACKET);
- sc = SelectorCache.getSelectorCache();
- write_selector = sc.getSelector();
- wkey = chan.register (write_selector, SelectionKey.OP_WRITE);
- read_selector = sc.getSelector();
- wkey = chan.register (read_selector, SelectionKey.OP_READ);
}
void close () throws IOException {
- sc.freeSelector (write_selector);
- sc.freeSelector (read_selector);
}
/* try to wrap and send the data in src. Handles OVERFLOW.
@@ -304,15 +297,7 @@
wrap_dst.flip();
int l = wrap_dst.remaining();
assert l == r.result.bytesProduced();
- long currtime = time.getTime();
- long maxtime = currtime + writeTimeout;
while (l>0) {
- write_selector.select(writeTimeout); // timeout
- currtime = time.getTime();
- if (currtime > maxtime) {
- throw new SocketTimeoutException ("write timed out");
- }
- write_selector.selectedKeys().clear();
l -= chan.write (wrap_dst);
}
}
@@ -342,20 +327,12 @@
needData = true;
}
synchronized (unwrapLock) {
- int x,y;
+ int x;
do {
if (needData) {
- long currTime = time.getTime();
- long maxtime = currTime + readTimeout;
do {
- if (currTime > maxtime) {
- throw new SocketTimeoutException ("read timedout");
- }
- y = read_selector.select (readTimeout);
- currTime = time.getTime();
- } while (y != 1);
- read_selector.selectedKeys().clear();
x = chan.read (unwrap_src);
+ } while (x == 0);
if (x == -1) {
throw new IOException ("connection closed for reading");
}
--- a/jdk/src/share/classes/sun/net/httpserver/SelectorCache.java Thu Nov 18 19:16:45 2010 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.net.httpserver;
-
-import java.util.*;
-import java.nio.*;
-import java.net.*;
-import java.io.*;
-import java.security.*;
-import java.nio.channels.*;
-
-/*
- * Implements a cache of java.nio.channels.Selector
- * where Selectors are allocated on demand and placed
- * in a temporary cache for a period of time, so they
- * can be reused. If a period of between 2 and 4 minutes
- * elapses without being used, then they are closed.
- */
-public class SelectorCache {
-
- static SelectorCache cache = null;
-
- private SelectorCache () {
- freeSelectors = new LinkedList<SelectorWrapper>();
- CacheCleaner c = AccessController.doPrivileged(
- new PrivilegedAction<CacheCleaner>() {
- public CacheCleaner run() {
- CacheCleaner cleaner = new CacheCleaner();
- cleaner.setDaemon (true);
- return cleaner;
- }
- });
- c.start();
- }
-
- /**
- * factory method for creating single instance
- */
- public static SelectorCache getSelectorCache () {
- synchronized (SelectorCache.class) {
- if (cache == null) {
- cache = new SelectorCache ();
- }
- }
- return cache;
- }
-
- private static class SelectorWrapper {
- private Selector sel;
- private boolean deleteFlag;
- private SelectorWrapper (Selector sel) {
- this.sel = sel;
- this.deleteFlag = false;
- }
- public Selector getSelector() { return sel;}
- public boolean getDeleteFlag () {return deleteFlag;}
- public void setDeleteFlag (boolean b) {deleteFlag = b;}
- }
-
- /* list of free selectors. Can be re-allocated for a period
- * of time, after which if not allocated will be closed
- * and removed from the list (by CacheCleaner thread)
- */
- LinkedList<SelectorWrapper> freeSelectors;
-
- synchronized Selector getSelector () throws IOException {
- SelectorWrapper wrapper = null;
- Selector selector;
-
- if (freeSelectors.size() > 0) {
- wrapper = freeSelectors.remove();
- selector = wrapper.getSelector();
- } else {
- selector = Selector.open();
- }
- return selector;
- }
-
- synchronized void freeSelector (Selector selector) {
- freeSelectors.add (new SelectorWrapper (selector));
- }
-
- /* Thread ensures that entries on freeSelector list
- * remain there for at least 2 minutes and no longer
- * than 4 minutes.
- */
- class CacheCleaner extends Thread {
- public void run () {
- long timeout = ServerConfig.getSelCacheTimeout() * 1000;
- while (true) {
- try {Thread.sleep (timeout); } catch (Exception e) {}
- synchronized (freeSelectors) {
- ListIterator<SelectorWrapper> l = freeSelectors.listIterator();
- while (l.hasNext()) {
- SelectorWrapper w = l.next();
- if (w.getDeleteFlag()) {
- /* 2nd pass. Close the selector */
- try {
- w.getSelector().close();
- } catch (IOException e) {}
- l.remove();
- } else {
- /* 1st pass. Set the flag */
- w.setDeleteFlag (true);
- }
- }
- }
- }
- }
- }
-}
--- a/jdk/src/share/classes/sun/net/httpserver/ServerConfig.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerConfig.java Thu Nov 18 19:17:43 2010 +0000
@@ -27,6 +27,8 @@
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
+import java.util.logging.Logger;
+import java.security.PrivilegedAction;
/**
* Parameters that users will not likely need to set
@@ -37,23 +39,26 @@
static int clockTick;
- static int defaultClockTick = 10000 ; // 10 sec.
+ static final int DEFAULT_CLOCK_TICK = 10000 ; // 10 sec.
/* These values must be a reasonable multiple of clockTick */
- static long defaultReadTimeout = 20 ; // 20 sec.
- static long defaultWriteTimeout = 60 ; // 60 sec.
- static long defaultIdleInterval = 300 ; // 5 min
- static long defaultSelCacheTimeout = 120 ; // seconds
- static int defaultMaxIdleConnections = 200 ;
+ static final long DEFAULT_IDLE_INTERVAL = 300 ; // 5 min
+ static final int DEFAULT_MAX_IDLE_CONNECTIONS = 200 ;
- static long defaultDrainAmount = 64 * 1024;
+ static final long DEFAULT_MAX_REQ_TIME = -1; // default: forever
+ static final long DEFAULT_MAX_RSP_TIME = -1; // default: forever
+ static final long DEFAULT_TIMER_MILLIS = 1000;
- static long readTimeout;
- static long writeTimeout;
+ static final long DEFAULT_DRAIN_AMOUNT = 64 * 1024;
+
static long idleInterval;
- static long selCacheTimeout;
static long drainAmount; // max # of bytes to drain from an inputstream
static int maxIdleConnections;
+
+ // max time a request or response is allowed to take
+ static long maxReqTime;
+ static long maxRspTime;
+ static long timerMillis;
static boolean debug = false;
static {
@@ -61,49 +66,79 @@
idleInterval = ((Long)java.security.AccessController.doPrivileged(
new sun.security.action.GetLongAction(
"sun.net.httpserver.idleInterval",
- defaultIdleInterval))).longValue() * 1000;
+ DEFAULT_IDLE_INTERVAL))).longValue() * 1000;
clockTick = ((Integer)java.security.AccessController.doPrivileged(
new sun.security.action.GetIntegerAction(
"sun.net.httpserver.clockTick",
- defaultClockTick))).intValue();
+ DEFAULT_CLOCK_TICK))).intValue();
maxIdleConnections = ((Integer)java.security.AccessController.doPrivileged(
new sun.security.action.GetIntegerAction(
"sun.net.httpserver.maxIdleConnections",
- defaultMaxIdleConnections))).intValue();
-
- readTimeout = ((Long)java.security.AccessController.doPrivileged(
- new sun.security.action.GetLongAction(
- "sun.net.httpserver.readTimeout",
- defaultReadTimeout))).longValue()* 1000;
-
- selCacheTimeout = ((Long)java.security.AccessController.doPrivileged(
- new sun.security.action.GetLongAction(
- "sun.net.httpserver.selCacheTimeout",
- defaultSelCacheTimeout))).longValue()* 1000;
-
- writeTimeout = ((Long)java.security.AccessController.doPrivileged(
- new sun.security.action.GetLongAction(
- "sun.net.httpserver.writeTimeout",
- defaultWriteTimeout))).longValue()* 1000;
+ DEFAULT_MAX_IDLE_CONNECTIONS))).intValue();
drainAmount = ((Long)java.security.AccessController.doPrivileged(
new sun.security.action.GetLongAction(
"sun.net.httpserver.drainAmount",
- defaultDrainAmount))).longValue();
+ DEFAULT_DRAIN_AMOUNT))).longValue();
+
+ maxReqTime = ((Long)java.security.AccessController.doPrivileged(
+ new sun.security.action.GetLongAction(
+ "sun.net.httpserver.maxReqTime",
+ DEFAULT_MAX_REQ_TIME))).longValue();
+
+ maxRspTime = ((Long)java.security.AccessController.doPrivileged(
+ new sun.security.action.GetLongAction(
+ "sun.net.httpserver.maxRspTime",
+ DEFAULT_MAX_RSP_TIME))).longValue();
+
+ timerMillis = ((Long)java.security.AccessController.doPrivileged(
+ new sun.security.action.GetLongAction(
+ "sun.net.httpserver.timerMillis",
+ DEFAULT_TIMER_MILLIS))).longValue();
debug = ((Boolean)java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction(
"sun.net.httpserver.debug"))).booleanValue();
}
- static long getReadTimeout () {
- return readTimeout;
- }
+
+ static void checkLegacyProperties (final Logger logger) {
+
+ // legacy properties that are no longer used
+ // print a warning to logger if they are set.
- static long getSelCacheTimeout () {
- return selCacheTimeout;
+ java.security.AccessController.doPrivileged(
+ new PrivilegedAction<Void>() {
+ public Void run () {
+ if (System.getProperty("sun.net.httpserver.readTimeout")
+ !=null)
+ {
+ logger.warning ("sun.net.httpserver.readTimeout "+
+ "property is no longer used. "+
+ "Use sun.net.httpserver.maxReqTime instead."
+ );
+ }
+ if (System.getProperty("sun.net.httpserver.writeTimeout")
+ !=null)
+ {
+ logger.warning ("sun.net.httpserver.writeTimeout "+
+ "property is no longer used. Use "+
+ "sun.net.httpserver.maxRspTime instead."
+ );
+ }
+ if (System.getProperty("sun.net.httpserver.selCacheTimeout")
+ !=null)
+ {
+ logger.warning ("sun.net.httpserver.selCacheTimeout "+
+ "property is no longer used."
+ );
+ }
+ return null;
+ }
+ }
+ );
}
static boolean debugEnabled () {
@@ -122,11 +157,19 @@
return maxIdleConnections;
}
- static long getWriteTimeout () {
- return writeTimeout;
- }
-
static long getDrainAmount () {
return drainAmount;
}
+
+ static long getMaxReqTime () {
+ return maxReqTime;
+ }
+
+ static long getMaxRspTime () {
+ return maxRspTime;
+ }
+
+ static long getTimerMillis () {
+ return timerMillis;
+ }
}
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Thu Nov 18 19:17:43 2010 +0000
@@ -37,6 +37,7 @@
import javax.net.ssl.*;
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
+import sun.net.httpserver.HttpConnection.State;
/**
* Provides implementation for both HTTP and HTTPS
@@ -55,6 +56,12 @@
private SelectionKey listenerKey;
private Set<HttpConnection> idleConnections;
private Set<HttpConnection> allConnections;
+ /* following two are used to keep track of the times
+ * when a connection/request is first received
+ * and when we start to send the response
+ */
+ private Set<HttpConnection> reqConnections;
+ private Set<HttpConnection> rspConnections;
private List<Event> events;
private Object lolock = new Object();
private volatile boolean finished = false;
@@ -62,14 +69,19 @@
private boolean bound = false;
private boolean started = false;
private volatile long time; /* current time */
+ private volatile long subticks = 0;
private volatile long ticks; /* number of clock ticks since server started */
private HttpServer wrapper;
final static int CLOCK_TICK = ServerConfig.getClockTick();
final static long IDLE_INTERVAL = ServerConfig.getIdleInterval();
final static int MAX_IDLE_CONNECTIONS = ServerConfig.getMaxIdleConnections();
+ final static long TIMER_MILLIS = ServerConfig.getTimerMillis ();
+ final static long MAX_REQ_TIME=getTimeMillis(ServerConfig.getMaxReqTime());
+ final static long MAX_RSP_TIME=getTimeMillis(ServerConfig.getMaxRspTime());
+ final static boolean timer1Enabled = MAX_REQ_TIME != -1 || MAX_RSP_TIME != -1;
- private Timer timer;
+ private Timer timer, timer1;
private Logger logger;
ServerImpl (
@@ -79,6 +91,7 @@
this.protocol = protocol;
this.wrapper = wrapper;
this.logger = Logger.getLogger ("com.sun.net.httpserver");
+ ServerConfig.checkLegacyProperties (logger);
https = protocol.equalsIgnoreCase ("https");
this.address = addr;
contexts = new ContextList();
@@ -94,9 +107,18 @@
dispatcher = new Dispatcher();
idleConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
allConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
+ reqConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
+ rspConnections = Collections.synchronizedSet (new HashSet<HttpConnection>());
time = System.currentTimeMillis();
timer = new Timer ("server-timer", true);
timer.schedule (new ServerTimerTask(), CLOCK_TICK, CLOCK_TICK);
+ if (timer1Enabled) {
+ timer1 = new Timer ("server-timer1", true);
+ timer1.schedule (new ServerTimerTask1(),TIMER_MILLIS,TIMER_MILLIS);
+ logger.config ("HttpServer timer1 enabled period in ms: "+TIMER_MILLIS);
+ logger.config ("MAX_REQ_TIME: "+MAX_REQ_TIME);
+ logger.config ("MAX_RSP_TIME: "+MAX_RSP_TIME);
+ }
events = new LinkedList<Event>();
logger.config ("HttpServer created "+protocol+" "+ addr);
}
@@ -181,6 +203,9 @@
allConnections.clear();
idleConnections.clear();
timer.cancel();
+ if (timer1Enabled) {
+ timer1.cancel();
+ }
}
Dispatcher dispatcher;
@@ -236,13 +261,6 @@
}
}
- int resultSize () {
- synchronized (lolock) {
- return events.size ();
- }
- }
-
-
/* main server listener task */
class Dispatcher implements Runnable {
@@ -257,7 +275,7 @@
if (terminating && exchanges == 0) {
finished = true;
}
- SocketChannel chan = c.getChannel();
+ responseCompleted (c);
LeftOverInputStream is = t.getOriginalInputStream();
if (!is.isEOF()) {
t.close = true;
@@ -268,17 +286,10 @@
} else {
if (is.isDataBuffered()) {
/* don't re-enable the interestops, just handle it */
+ requestStarted (c);
handle (c.getChannel(), c);
} else {
- /* re-enable interestops */
- SelectionKey key = c.getSelectionKey();
- if (key.isValid()) {
- key.interestOps (
- key.interestOps()|SelectionKey.OP_READ
- );
- }
- c.time = getTime() + IDLE_INTERVAL;
- idleConnections.add (c);
+ connsToRegister.add (c);
}
}
}
@@ -290,22 +301,51 @@
}
}
+ final LinkedList<HttpConnection> connsToRegister =
+ new LinkedList<HttpConnection>();
+
+ void reRegister (HttpConnection c) {
+ /* re-register with selector */
+ try {
+ SocketChannel chan = c.getChannel();
+ chan.configureBlocking (false);
+ SelectionKey key = chan.register (selector, SelectionKey.OP_READ);
+ key.attach (c);
+ c.selectionKey = key;
+ c.time = getTime() + IDLE_INTERVAL;
+ idleConnections.add (c);
+ } catch (IOException e) {
+ dprint(e);
+ logger.log(Level.FINER, "Dispatcher(8)", e);
+ c.close();
+ }
+ }
+
public void run() {
while (!finished) {
try {
-
- /* process the events list first */
+ ListIterator<HttpConnection> li =
+ connsToRegister.listIterator();
+ for (HttpConnection c : connsToRegister) {
+ reRegister(c);
+ }
+ connsToRegister.clear();
- while (resultSize() > 0) {
- Event r;
- synchronized (lolock) {
- r = events.remove(0);
+ List<Event> list = null;
+ selector.select(1000);
+ synchronized (lolock) {
+ if (events.size() > 0) {
+ list = events;
+ events = new LinkedList<Event>();
+ }
+ }
+
+ if (list != null) {
+ for (Event r: list) {
handleEvent (r);
}
}
- selector.select(1000);
-
/* process the selected list now */
Set<SelectionKey> selected = selector.selectedKeys();
@@ -327,6 +367,7 @@
c.selectionKey = newkey;
c.setChannel (chan);
newkey.attach (c);
+ requestStarted (c);
allConnections.add (c);
} else {
try {
@@ -334,27 +375,44 @@
boolean closed;
SocketChannel chan = (SocketChannel)key.channel();
HttpConnection conn = (HttpConnection)key.attachment();
- // interestOps will be restored at end of read
- key.interestOps (0);
+
+ key.cancel();
+ chan.configureBlocking (true);
+ if (idleConnections.remove(conn)) {
+ // was an idle connection so add it
+ // to reqConnections set.
+ requestStarted (conn);
+ }
handle (chan, conn);
} else {
assert false;
}
+ } catch (CancelledKeyException e) {
+ handleException(key, null);
} catch (IOException e) {
- HttpConnection conn = (HttpConnection)key.attachment();
- logger.log (
- Level.FINER, "Dispatcher (2)", e
- );
- conn.close();
+ handleException(key, e);
}
}
}
+ // call the selector just to process the cancelled keys
+ selector.selectNow();
+ } catch (IOException e) {
+ logger.log (Level.FINER, "Dispatcher (4)", e);
} catch (Exception e) {
- logger.log (Level.FINER, "Dispatcher (3)", e);
+ e.printStackTrace();
+ logger.log (Level.FINER, "Dispatcher (7)", e);
}
}
}
+ private void handleException (SelectionKey key, Exception e) {
+ HttpConnection conn = (HttpConnection)key.attachment();
+ if (e != null) {
+ logger.log (Level.FINER, "Dispatcher (2)", e);
+ }
+ closeConnection(conn);
+ }
+
public void handle (SocketChannel chan, HttpConnection conn)
throws IOException
{
@@ -363,10 +421,10 @@
executor.execute (t);
} catch (HttpError e1) {
logger.log (Level.FINER, "Dispatcher (4)", e1);
- conn.close();
+ closeConnection(conn);
} catch (IOException e) {
logger.log (Level.FINER, "Dispatcher (5)", e);
- conn.close();
+ closeConnection(conn);
}
}
}
@@ -390,7 +448,26 @@
return logger;
}
- /* per exchange task */
+ private void closeConnection(HttpConnection conn) {
+ conn.close();
+ allConnections.remove(conn);
+ switch (conn.getState()) {
+ case REQUEST:
+ reqConnections.remove(conn);
+ break;
+ case RESPONSE:
+ rspConnections.remove(conn);
+ break;
+ case IDLE:
+ idleConnections.remove(conn);
+ break;
+ }
+ assert !reqConnections.remove(conn);
+ assert !rspConnections.remove(conn);
+ assert !idleConnections.remove(conn);
+ }
+
+ /* per exchange task */
class Exchange implements Runnable {
SocketChannel chan;
@@ -450,8 +527,7 @@
requestLine = req.requestLine();
if (requestLine == null) {
/* connection closed */
- connection.close();
- allConnections.remove(connection);
+ closeConnection(connection);
return;
}
int space = requestLine.indexOf (' ');
@@ -482,6 +558,9 @@
if (s != null) {
clen = Long.parseLong(s);
}
+ if (clen == 0) {
+ requestCompleted (connection);
+ }
}
ctx = contexts.findContext (protocol, uri.getPath());
if (ctx == null) {
@@ -560,7 +639,7 @@
} catch (IOException e1) {
logger.log (Level.FINER, "ServerImpl.Exchange (1)", e1);
- connection.close();
+ closeConnection(connection);
} catch (NumberFormatException e3) {
reject (Code.HTTP_BAD_REQUEST,
requestLine, "NumberFormatException thrown");
@@ -569,7 +648,7 @@
requestLine, "URISyntaxException thrown");
} catch (Exception e4) {
logger.log (Level.FINER, "ServerImpl.Exchange (2)", e4);
- connection.close();
+ closeConnection(connection);
}
}
@@ -591,47 +670,60 @@
rejected = true;
logReply (code, requestStr, message);
sendReply (
- code, true, "<h1>"+code+Code.msg(code)+"</h1>"+message
+ code, false, "<h1>"+code+Code.msg(code)+"</h1>"+message
);
- /* connection is already closed by sendReply, now remove it */
- allConnections.remove(connection);
+ closeConnection(connection);
}
void sendReply (
int code, boolean closeNow, String text)
{
try {
- String s = "HTTP/1.1 " + code + Code.msg(code) + "\r\n";
+ StringBuilder builder = new StringBuilder (512);
+ builder.append ("HTTP/1.1 ")
+ .append (code).append (Code.msg(code)).append ("\r\n");
+
if (text != null && text.length() != 0) {
- s = s + "Content-Length: "+text.length()+"\r\n";
- s = s + "Content-Type: text/html\r\n";
+ builder.append ("Content-Length: ")
+ .append (text.length()).append ("\r\n")
+ .append ("Content-Type: text/html\r\n");
} else {
- s = s + "Content-Length: 0\r\n";
+ builder.append ("Content-Length: 0\r\n");
text = "";
}
if (closeNow) {
- s = s + "Connection: close\r\n";
+ builder.append ("Connection: close\r\n");
}
- s = s + "\r\n" + text;
+ builder.append ("\r\n").append (text);
+ String s = builder.toString();
byte[] b = s.getBytes("ISO8859_1");
rawout.write (b);
rawout.flush();
if (closeNow) {
- connection.close();
+ closeConnection(connection);
}
} catch (IOException e) {
logger.log (Level.FINER, "ServerImpl.sendReply", e);
- connection.close();
+ closeConnection(connection);
}
}
}
void logReply (int code, String requestStr, String text) {
+ if (!logger.isLoggable(Level.FINE)) {
+ return;
+ }
if (text == null) {
text = "";
}
- String message = requestStr + " [" + code + " " +
+ String r;
+ if (requestStr.length() > 80) {
+ r = requestStr.substring (0, 80) + "<TRUNCATED>";
+ } else {
+ r = requestStr;
+ }
+ String message = r + " [" + code + " " +
Code.msg(code) + "] ("+text+")";
logger.fine (message);
}
@@ -667,6 +759,34 @@
return wrapper;
}
+ void requestStarted (HttpConnection c) {
+ c.creationTime = getTime();
+ c.setState (State.REQUEST);
+ reqConnections.add (c);
+ }
+
+ // called after a request has been completely read
+ // by the server. This stops the timer which would
+ // close the connection if the request doesn't arrive
+ // quickly enough. It then starts the timer
+ // that ensures the client reads the response in a timely
+ // fashion.
+
+ void requestCompleted (HttpConnection c) {
+ assert c.getState() == State.REQUEST;
+ reqConnections.remove (c);
+ c.rspStartedTime = getTime();
+ rspConnections.add (c);
+ c.setState (State.RESPONSE);
+ }
+
+ // called after response has been sent
+ void responseCompleted (HttpConnection c) {
+ assert c.getState() == State.RESPONSE;
+ rspConnections.remove (c);
+ c.setState (State.IDLE);
+ }
+
/**
* TimerTask run every CLOCK_TICK ms
*/
@@ -689,4 +809,62 @@
}
}
}
+
+ class ServerTimerTask1 extends TimerTask {
+
+ // runs every TIMER_MILLIS
+ public void run () {
+ LinkedList<HttpConnection> toClose = new LinkedList<HttpConnection>();
+ time = System.currentTimeMillis();
+ synchronized (reqConnections) {
+ if (MAX_REQ_TIME != -1) {
+ for (HttpConnection c : reqConnections) {
+ if (c.creationTime + TIMER_MILLIS + MAX_REQ_TIME <= time) {
+ toClose.add (c);
+ }
+ }
+ for (HttpConnection c : toClose) {
+ logger.log (Level.FINE, "closing: no request: " + c);
+ reqConnections.remove (c);
+ allConnections.remove (c);
+ c.close();
+ }
+ }
+ }
+ toClose = new LinkedList<HttpConnection>();
+ synchronized (rspConnections) {
+ if (MAX_RSP_TIME != -1) {
+ for (HttpConnection c : rspConnections) {
+ if (c.rspStartedTime + TIMER_MILLIS +MAX_RSP_TIME <= time) {
+ toClose.add (c);
+ }
+ }
+ for (HttpConnection c : toClose) {
+ logger.log (Level.FINE, "closing: no response: " + c);
+ rspConnections.remove (c);
+ allConnections.remove (c);
+ c.close();
+ }
+ }
+ }
+ }
+ }
+
+ void logStackTrace (String s) {
+ logger.finest (s);
+ StringBuilder b = new StringBuilder ();
+ StackTraceElement[] e = Thread.currentThread().getStackTrace();
+ for (int i=0; i<e.length; i++) {
+ b.append (e[i].toString()).append("\n");
+ }
+ logger.finest (b.toString());
+ }
+
+ static long getTimeMillis(long secs) {
+ if (secs == -1) {
+ return -1;
+ } else {
+ return secs * 1000;
+ }
+ }
}
--- a/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java Thu Nov 18 19:17:43 2010 +0000
@@ -778,6 +778,13 @@
"csIBM500"
});
+ charset("x-IBM833", "IBM833",
+ new String[] {
+ "cp833",
+ "ibm833",
+ "ibm-833"
+ });
+
//EBCDIC DBCS-only Korean
charset("x-IBM834", "IBM834",
new String[] {
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Thu Nov 18 19:17:43 2010 +0000
@@ -74,7 +74,7 @@
// DEC: return the length of trailing padding bytes given the specified
// padded data
int unpad(byte[] paddedData, int len)
- throws BadPaddingException;
+ throws BadPaddingException, IllegalBlockSizeException;
}
private static class PKCS5Padding implements Padding {
@@ -96,9 +96,10 @@
}
public int unpad(byte[] paddedData, int len)
- throws BadPaddingException {
- if (len < 1 || len > paddedData.length) {
- throw new BadPaddingException("Invalid pad array length!");
+ throws BadPaddingException, IllegalBlockSizeException {
+ if ((len < 1) || (len % blockSize != 0)) {
+ throw new IllegalBlockSizeException
+ ("Input length must be multiples of " + blockSize);
}
byte padValue = paddedData[len - 1];
if (padValue < 1 || padValue > blockSize) {
--- a/jdk/src/share/lib/security/sunpkcs11-solaris.cfg Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/src/share/lib/security/sunpkcs11-solaris.cfg Thu Nov 18 19:17:43 2010 +0000
@@ -31,5 +31,9 @@
CKM_SHA256_RSA_PKCS
CKM_SHA384_RSA_PKCS
CKM_SHA512_RSA_PKCS
+# the following mechanisms are disabled to ensure backward compatibility (Solaris bug 6545046)
+ CKM_DES_CBC_PAD
+ CKM_DES3_CBC_PAD
+ CKM_AES_CBC_PAD
}
--- a/jdk/test/com/sun/net/httpserver/Test.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/test/com/sun/net/httpserver/Test.java Thu Nov 18 19:17:43 2010 +0000
@@ -22,8 +22,20 @@
*/
import com.sun.net.httpserver.*;
+import java.util.logging.*;
public class Test {
+
+ static Logger logger;
+
+ static void enableLogging() {
+ logger = Logger.getLogger("com.sun.net.httpserver");
+ Handler h = new ConsoleHandler();
+ h.setLevel(Level.ALL);
+ logger.setLevel(Level.ALL);
+ logger.addHandler(h);
+ }
+
static void delay () {
try {
Thread.sleep (1000);
--- a/jdk/test/com/sun/net/httpserver/Test1.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/test/com/sun/net/httpserver/Test1.java Thu Nov 18 19:17:43 2010 +0000
@@ -25,6 +25,7 @@
* @test
* @bug 6270015
* @run main/othervm Test1
+ * @run main/othervm -Dsun.net.httpserver.maxReqTime=10 Test1
* @summary Light weight HTTP server
*/
--- a/jdk/test/com/sun/net/httpserver/Test13.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/test/com/sun/net/httpserver/Test13.java Thu Nov 18 19:17:43 2010 +0000
@@ -31,6 +31,7 @@
import com.sun.net.httpserver.*;
import java.util.concurrent.*;
+import java.util.logging.*;
import java.io.*;
import java.net.*;
@@ -45,12 +46,19 @@
static SSLContext ctx;
+ final static int NUM = 32; // was 32
+
static boolean fail = false;
public static void main (String[] args) throws Exception {
HttpServer s1 = null;
HttpsServer s2 = null;
ExecutorService executor=null;
+ Logger l = Logger.getLogger ("com.sun.net.httpserver");
+ Handler ha = new ConsoleHandler();
+ ha.setLevel(Level.ALL);
+ l.setLevel(Level.ALL);
+ l.addHandler(ha);
try {
String root = System.getProperty ("test.src")+ "/docs";
System.out.print ("Test13: ");
@@ -70,10 +78,10 @@
int port = s1.getAddress().getPort();
int httpsport = s2.getAddress().getPort();
- Runner r[] = new Runner[64];
- for (int i=0; i<32; i++) {
+ Runner r[] = new Runner[NUM*2];
+ for (int i=0; i<NUM; i++) {
r[i] = new Runner (true, "http", root+"/test1", port, "smallfile.txt", 23);
- r[i+32] = new Runner (true, "https", root+"/test1", port, "smallfile.txt", 23);
+ r[i+NUM] = new Runner (true, "https", root+"/test1", httpsport, "smallfile.txt", 23);
}
start (r);
join (r);
@@ -91,6 +99,7 @@
static void start (Runner[] x) {
for (int i=0; i<x.length; i++) {
+ if (x[i] != null)
x[i].start();
}
}
@@ -98,6 +107,7 @@
static void join (Runner[] x) {
for (int i=0; i<x.length; i++) {
try {
+ if (x[i] != null)
x[i].join();
} catch (InterruptedException e) {}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/net/httpserver/bugs/6725892/Test.java Thu Nov 18 19:17:43 2010 +0000
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6725892
+ * @run main/othervm -Dsun.net.httpserver.maxReqTime=2 Test
+ * @summary
+ */
+
+import com.sun.net.httpserver.*;
+
+import java.util.concurrent.*;
+import java.util.logging.*;
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class Test {
+
+ static HttpServer s1;
+ static int port;
+ static URL url;
+ static final String RESPONSE_BODY = "response";
+ static boolean failed = false;
+
+ static class Handler implements HttpHandler {
+
+ public void handle (HttpExchange t)
+ throws IOException
+ {
+ InputStream is = t.getRequestBody();
+ InetSocketAddress rem = t.getRemoteAddress();
+ System.out.println ("Request from: " + rem);
+ while (is.read () != -1) ;
+ is.close();
+ String requrl = t.getRequestURI().toString();
+ OutputStream os = t.getResponseBody();
+ t.sendResponseHeaders (200, RESPONSE_BODY.length());
+ os.write (RESPONSE_BODY.getBytes());
+ t.close();
+ }
+ }
+
+ public static void main (String[] args) throws Exception {
+
+ ExecutorService exec = Executors.newCachedThreadPool();
+ //Logger log = Logger.getLogger ("com.sun.net.httpserver");
+ //log.setLevel(Level.ALL);
+ //ConsoleHandler hg = new ConsoleHandler();
+ //hg.setLevel (Level.ALL);
+ //log.addHandler(hg);
+
+ sun.net.httpserver.HttpServerImpl x = null;
+ try {
+ InetSocketAddress addr = new InetSocketAddress (0);
+ s1 = HttpServer.create (addr, 0);
+ HttpHandler h = new Handler ();
+ HttpContext c1 = s1.createContext ("/", h);
+ s1.setExecutor(exec);
+ s1.start();
+
+ port = s1.getAddress().getPort();
+ System.out.println ("Server on port " + port);
+ url = new URL ("http://rialto.ireland:"+port+"/foo");
+ test1();
+ test2();
+ test3();
+ x = (sun.net.httpserver.HttpServerImpl)s1;
+ Thread.sleep (2000);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println ("FAIL");
+ throw new RuntimeException ();
+ } finally {
+ s1.stop(0);
+ System.out.println ("After Shutdown");
+ exec.shutdown();
+ }
+ }
+
+ // open TCP connection without sending anything. Check server closes it.
+
+ static void test1() throws IOException {
+ failed = false;
+ Socket s = new Socket ("127.0.0.1", port);
+ InputStream is = s.getInputStream();
+ // server should close connection after 2 seconds. We wait up to 10
+ s.setSoTimeout (10000);
+ try {
+ is.read();
+ } catch (SocketTimeoutException e) {
+ failed = true;
+ }
+ s.close();
+ if (failed) {
+ System.out.println ("test1: FAIL");
+ throw new RuntimeException ();
+ } else {
+ System.out.println ("test1: OK");
+ }
+ }
+
+ // send request and don't read response. Check server closes connection
+
+ static void test2() throws IOException {
+ HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
+ urlc.setReadTimeout (20 * 1000);
+ InputStream is = urlc.getInputStream();
+ // we won't read response and check if it times out
+ // on server. If it timesout at client then there is a problem
+ try {
+ Thread.sleep (10 * 1000);
+ while (is.read() != -1) ;
+ } catch (InterruptedException e) {
+ System.out.println (e);
+ System.out.println ("test2: FAIL");
+ throw new RuntimeException ("unexpected error");
+ } catch (SocketTimeoutException e1) {
+ System.out.println (e1);
+ System.out.println ("test2: FAIL");
+ throw new RuntimeException ("client timedout");
+ } finally {
+ is.close();
+ }
+ System.out.println ("test2: OK");
+ }
+
+ // same as test2, but repeated with multiple connections
+ // including a number of valid request/responses
+
+ // Worker: a thread opens a connection to the server in one of three modes.
+ // NORMAL - sends a request, waits for response, and checks valid response
+ // REQUEST - sends a partial request, and blocks, to see if
+ // server closes the connection.
+ // RESPONSE - sends a request, partially reads response and blocks,
+ // to see if server closes the connection.
+
+ static class Worker extends Thread {
+ CountDownLatch latch;
+ Mode mode;
+
+ enum Mode {
+ REQUEST, // block during sending of request
+ RESPONSE, // block during reading of response
+ NORMAL // don't block
+ };
+
+ Worker (CountDownLatch latch, Mode mode) {
+ this.latch = latch;
+ this.mode = mode;
+ }
+
+ void fail(String msg) {
+ System.out.println (msg);
+ failed = true;
+ }
+
+ public void run () {
+ HttpURLConnection urlc;
+ InputStream is = null;
+
+ try {
+ urlc = (HttpURLConnection) url.openConnection();
+ urlc.setReadTimeout (20 * 1000);
+ urlc.setDoOutput(true);
+ } catch (IOException e) {
+ fail("Worker: failed to connect to server");
+ latch.countDown();
+ return;
+ }
+ try {
+ OutputStream os = urlc.getOutputStream();
+ os.write ("foo".getBytes());
+ if (mode == Mode.REQUEST) {
+ Thread.sleep (3000);
+ }
+ os.close();
+ is = urlc.getInputStream();
+ if (mode == Mode.RESPONSE) {
+ Thread.sleep (3000);
+ }
+ if (!checkResponse (is, RESPONSE_BODY)) {
+ fail ("Worker: response");
+ }
+ is.close();
+ return;
+ } catch (InterruptedException e0) {
+ fail("Worker: timedout");
+ } catch (SocketTimeoutException e1) {
+ fail("Worker: timedout");
+ } catch (IOException e2) {
+ switch (mode) {
+ case NORMAL:
+ fail ("Worker: " + e2.getMessage());
+ break;
+ case RESPONSE:
+ if (is == null) {
+ fail ("Worker: " + e2.getMessage());
+ break;
+ }
+ // default: is ok
+ }
+ } finally {
+ latch.countDown();
+ }
+ }
+ }
+
+ static final int NUM = 20;
+
+ static void test3() throws Exception {
+ failed = false;
+ CountDownLatch l = new CountDownLatch (NUM*3);
+ Worker[] workers = new Worker[NUM*3];
+ for (int i=0; i<NUM; i++) {
+ workers[i*3] = new Worker (l, Worker.Mode.NORMAL);
+ workers[i*3+1] = new Worker (l, Worker.Mode.REQUEST);
+ workers[i*3+2] = new Worker (l, Worker.Mode.RESPONSE);
+ workers[i*3].start();
+ workers[i*3+1].start();
+ workers[i*3+2].start();
+ }
+ l.await();
+ for (int i=0; i<NUM*3; i++) {
+ workers[i].join();
+ }
+ if (failed) {
+ throw new RuntimeException ("test3: failed");
+ }
+ System.out.println ("test3: OK");
+ }
+
+ static boolean checkResponse (InputStream is, String resp) {
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ byte[] buf = new byte [64];
+ int c;
+ while ((c=is.read(buf)) != -1) {
+ bos.write (buf, 0, c);
+ }
+ bos.close();
+ if (!bos.toString().equals(resp)) {
+ System.out.println ("Wrong response: " + bos.toString());
+ return false;
+ }
+ } catch (IOException e) {
+ System.out.println (e);
+ return false;
+ }
+ return true;
+ }
+}
--- a/jdk/test/com/sun/net/httpserver/bugs/B6401598.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/test/com/sun/net/httpserver/bugs/B6401598.java Thu Nov 18 19:17:43 2010 +0000
@@ -83,7 +83,7 @@
server = HttpServer.create(new InetSocketAddress(0), 400);
server.createContext("/server/", new MyHandler());
exec = Executors.newFixedThreadPool(3);
- server.setExecutor(null);
+ server.setExecutor(exec);
port = server.getAddress().getPort();
server.start();
--- a/jdk/test/sun/nio/cs/CheckHistoricalNames.java Thu Nov 18 19:16:45 2010 +0000
+++ b/jdk/test/sun/nio/cs/CheckHistoricalNames.java Thu Nov 18 19:17:43 2010 +0000
@@ -22,7 +22,7 @@
*/
/* @test
- @bug 4513767 4961027
+ @bug 4513767 4961027 6217210
@summary Checks canonical names match between old and (NIO) core charsets
*/
import java.io.InputStreamReader;
@@ -154,6 +154,7 @@
checkHistoricalName("Cp500");
checkHistoricalName("Cp737");
checkHistoricalName("Cp775");
+ checkHistoricalName("Cp833");
checkHistoricalName("Cp838");
checkHistoricalName("Cp850");
checkHistoricalName("Cp852");
@@ -228,6 +229,7 @@
checkMappedName("IBM856", "Cp856");
checkMappedName("IBM857", "Cp857");
checkMappedName("IBM00858", "Cp858");
+ checkMappedName("IBM833", "Cp833");
checkMappedName("IBM860", "Cp860");
checkMappedName("IBM861", "Cp861");
checkMappedName("IBM862", "Cp862");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java Thu Nov 18 19:17:43 2010 +0000
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6687725
+ * @summary Test internal PKCS5Padding impl with various error conditions.
+ * @author Valerie Peng
+ * @library ..
+ */
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.*;
+import javax.crypto.spec.IvParameterSpec;
+
+public class TestPKCS5PaddingError extends PKCS11Test {
+ private static class CI { // class for holding Cipher Information
+ String transformation;
+ String keyAlgo;
+
+ CI(String transformation, String keyAlgo) {
+ this.transformation = transformation;
+ this.keyAlgo = keyAlgo;
+ }
+ }
+
+ private static final CI[] TEST_LIST = {
+ // algorithms which use the native padding impl
+ new CI("DES/CBC/PKCS5Padding", "DES"),
+ new CI("DESede/CBC/PKCS5Padding", "DESede"),
+ new CI("AES/CBC/PKCS5Padding", "AES"),
+ // algorithms which use SunPKCS11's own padding impl
+ new CI("DES/ECB/PKCS5Padding", "DES"),
+ new CI("DESede/ECB/PKCS5Padding", "DESede"),
+ new CI("AES/ECB/PKCS5Padding", "AES"),
+ };
+
+ private static StringBuffer debugBuf = new StringBuffer();
+
+ public void main(Provider p) throws Exception {
+ boolean status = true;
+ Random random = new Random();
+
+ try {
+ byte[] plainText = new byte[200];
+
+ for (int i = 0; i < TEST_LIST.length; i++) {
+ CI currTest = TEST_LIST[i];
+ System.out.println("===" + currTest.transformation + "===");
+ try {
+ KeyGenerator kg =
+ KeyGenerator.getInstance(currTest.keyAlgo, p);
+ SecretKey key = kg.generateKey();
+ Cipher c1 = Cipher.getInstance(currTest.transformation,
+ "SunJCE");
+ c1.init(Cipher.ENCRYPT_MODE, key);
+ byte[] cipherText = c1.doFinal(plainText);
+ AlgorithmParameters params = c1.getParameters();
+ Cipher c2 = Cipher.getInstance(currTest.transformation, p);
+ c2.init(Cipher.DECRYPT_MODE, key, params);
+
+ // 1st test: wrong output length
+ // NOTE: Skip NSS since it reports CKR_DEVICE_ERROR when
+ // the data passed to its EncryptUpdate/DecryptUpdate is
+ // not multiple of blocks
+ if (!p.getName().equals("SunPKCS11-NSS")) {
+ try {
+ System.out.println("Testing with wrong cipherText length");
+ c2.doFinal(cipherText, 0, cipherText.length - 2);
+ } catch (IllegalBlockSizeException ibe) {
+ // expected
+ } catch (Exception ex) {
+ System.out.println("Error: Unexpected Ex " + ex);
+ ex.printStackTrace();
+ }
+ }
+ // 2nd test: wrong padding value
+ try {
+ System.out.println("Testing with wrong padding bytes");
+ cipherText[cipherText.length - 1]++;
+ c2.doFinal(cipherText);
+ } catch (BadPaddingException bpe) {
+ // expected
+ } catch (Exception ex) {
+ System.out.println("Error: Unexpected Ex " + ex);
+ ex.printStackTrace();
+ }
+ System.out.println("DONE");
+ } catch (NoSuchAlgorithmException nsae) {
+ System.out.println("Skipping unsupported algorithm: " +
+ nsae);
+ }
+ }
+ } catch (Exception ex) {
+ // print out debug info when exception is encountered
+ if (debugBuf != null) {
+ System.out.println(debugBuf.toString());
+ debugBuf = new StringBuffer();
+ }
+ throw ex;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ main(new TestPKCS5PaddingError());
+ }
+}