Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
ef144a90
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ef144a90
编写于
11月 17, 2010
作者:
M
michaelm
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6725892: Http server stability issues
Reviewed-by: chegar
上级
24acdd3f
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
669 addition
and
337 deletion
+669
-337
src/share/classes/com/sun/net/httpserver/HttpsConfigurator.java
...are/classes/com/sun/net/httpserver/HttpsConfigurator.java
+2
-0
src/share/classes/com/sun/net/httpserver/HttpsParameters.java
...share/classes/com/sun/net/httpserver/HttpsParameters.java
+4
-0
src/share/classes/sun/net/httpserver/ChunkedInputStream.java
src/share/classes/sun/net/httpserver/ChunkedInputStream.java
+1
-0
src/share/classes/sun/net/httpserver/Event.java
src/share/classes/sun/net/httpserver/Event.java
+2
-0
src/share/classes/sun/net/httpserver/ExchangeImpl.java
src/share/classes/sun/net/httpserver/ExchangeImpl.java
+1
-0
src/share/classes/sun/net/httpserver/FixedLengthInputStream.java
...re/classes/sun/net/httpserver/FixedLengthInputStream.java
+3
-0
src/share/classes/sun/net/httpserver/HttpConnection.java
src/share/classes/sun/net/httpserver/HttpConnection.java
+13
-0
src/share/classes/sun/net/httpserver/Request.java
src/share/classes/sun/net/httpserver/Request.java
+27
-81
src/share/classes/sun/net/httpserver/SSLStreams.java
src/share/classes/sun/net/httpserver/SSLStreams.java
+9
-32
src/share/classes/sun/net/httpserver/SelectorCache.java
src/share/classes/sun/net/httpserver/SelectorCache.java
+0
-134
src/share/classes/sun/net/httpserver/ServerConfig.java
src/share/classes/sun/net/httpserver/ServerConfig.java
+77
-34
src/share/classes/sun/net/httpserver/ServerImpl.java
src/share/classes/sun/net/httpserver/ServerImpl.java
+230
-52
test/com/sun/net/httpserver/Test.java
test/com/sun/net/httpserver/Test.java
+12
-0
test/com/sun/net/httpserver/Test1.java
test/com/sun/net/httpserver/Test1.java
+1
-0
test/com/sun/net/httpserver/Test13.java
test/com/sun/net/httpserver/Test13.java
+13
-3
test/com/sun/net/httpserver/bugs/6725892/Test.java
test/com/sun/net/httpserver/bugs/6725892/Test.java
+273
-0
test/com/sun/net/httpserver/bugs/B6401598.java
test/com/sun/net/httpserver/bugs/B6401598.java
+1
-1
未找到文件。
src/share/classes/com/sun/net/httpserver/HttpsConfigurator.java
浏览文件 @
ef144a90
...
...
@@ -91,6 +91,7 @@ public class HttpsConfigurator {
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 class HttpsConfigurator {
public
void
configure
(
HttpsParameters
params
)
{
params
.
setSSLParameters
(
getSSLContext
().
getDefaultSSLParameters
());
}
//END_TIGER_EXCLUDE
}
src/share/classes/com/sun/net/httpserver/HttpsParameters.java
浏览文件 @
ef144a90
...
...
@@ -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 class HttpsParameters {
*/
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 @@ public abstract class HttpsParameters {
* invalid or unsupported.
*/
public
abstract
void
setSSLParameters
(
SSLParameters
params
);
//END_TIGER_EXCLUDE
/**
* Returns a copy of the array of ciphersuites or null if none
...
...
src/share/classes/sun/net/httpserver/ChunkedInputStream.java
浏览文件 @
ef144a90
...
...
@@ -110,6 +110,7 @@ class ChunkedInputStream extends LeftOverInputStream {
if
(
remaining
==
0
)
{
eof
=
true
;
consumeCRLF
();
t
.
getServerImpl
().
requestCompleted
(
t
.
getConnection
());
return
-
1
;
}
needToReadHeader
=
false
;
...
...
src/share/classes/sun/net/httpserver/Event.java
浏览文件 @
ef144a90
...
...
@@ -40,5 +40,7 @@ class Event {
class
WriteFinishedEvent
extends
Event
{
WriteFinishedEvent
(
ExchangeImpl
t
)
{
super
(
t
);
assert
!
t
.
writefinished
;
t
.
writefinished
=
true
;
}
}
src/share/classes/sun/net/httpserver/ExchangeImpl.java
浏览文件 @
ef144a90
...
...
@@ -38,6 +38,7 @@ class ExchangeImpl {
Headers
reqHdrs
,
rspHdrs
;
Request
req
;
String
method
;
boolean
writefinished
;
URI
uri
;
HttpConnection
connection
;
long
reqContentLen
;
...
...
src/share/classes/sun/net/httpserver/FixedLengthInputStream.java
浏览文件 @
ef144a90
...
...
@@ -56,6 +56,9 @@ class FixedLengthInputStream extends LeftOverInputStream {
int
n
=
in
.
read
(
b
,
off
,
len
);
if
(
n
>
-
1
)
{
remaining
-=
n
;
if
(
remaining
==
0
)
{
t
.
getServerImpl
().
requestCompleted
(
t
.
getConnection
());
}
}
return
n
;
}
...
...
src/share/classes/sun/net/httpserver/HttpConnection.java
浏览文件 @
ef144a90
...
...
@@ -55,10 +55,15 @@ class HttpConnection {
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 @@ class HttpConnection {
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
,
...
...
src/share/classes/sun/net/httpserver/Request.java
浏览文件 @
ef144a90
...
...
@@ -201,32 +201,22 @@ class Request {
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 @@ class Request {
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 @@ class Request {
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 @@ class Request {
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 @@ class Request {
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 @@ class Request {
return
;
}
channel
.
close
();
selector
.
selectNow
();
sc
.
freeSelector
(
selector
);
closed
=
true
;
}
...
...
@@ -362,23 +334,14 @@ class Request {
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 @@ class Request {
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
;
}
}
...
...
src/share/classes/sun/net/httpserver/SSLStreams.java
浏览文件 @
ef144a90
...
...
@@ -53,8 +53,6 @@ class SSLStreams {
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 @@ class SSLStreams {
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 SSLStreams {
class
Parameters
extends
HttpsParameters
{
InetSocketAddress
addr
;
SSLParameters
params
;
HttpsConfigurator
cfg
;
Parameters
(
HttpsConfigurator
cfg
,
InetSocketAddress
addr
)
{
...
...
@@ -117,12 +117,15 @@ class SSLStreams {
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 @@ class SSLStreams {
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 @@ class SSLStreams {
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 @@ class SSLStreams {
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 @@ class SSLStreams {
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"
);
}
...
...
src/share/classes/sun/net/httpserver/SelectorCache.java
已删除
100644 → 0
浏览文件 @
24acdd3f
/*
* 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
);
}
}
}
}
}
}
}
src/share/classes/sun/net/httpserver/ServerConfig.java
浏览文件 @
ef144a90
...
...
@@ -27,6 +27,8 @@ package sun.net.httpserver;
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 @@ class ServerConfig {
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
final
long
DEFAULT_DRAIN_AMOUNT
=
64
*
1024
;
static
long
readTimeout
;
static
long
writeTimeout
;
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 @@ class ServerConfig {
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
();
DEFAULT_MAX_IDLE_CONNECTIONS
))).
intValue
();
readTimeou
t
=
((
Long
)
java
.
security
.
AccessController
.
doPrivileged
(
drainAmoun
t
=
((
Long
)
java
.
security
.
AccessController
.
doPrivileged
(
new
sun
.
security
.
action
.
GetLongAction
(
"sun.net.httpserver.
readTimeou
t"
,
defaultReadTimeout
))).
longValue
()*
1000
;
"sun.net.httpserver.
drainAmoun
t"
,
DEFAULT_DRAIN_AMOUNT
))).
longValue
()
;
selCacheTimeout
=
((
Long
)
java
.
security
.
AccessController
.
doPrivileged
(
maxReqTime
=
((
Long
)
java
.
security
.
AccessController
.
doPrivileged
(
new
sun
.
security
.
action
.
GetLongAction
(
"sun.net.httpserver.
selCacheTimeout
"
,
defaultSelCacheTimeout
))).
longValue
()*
1000
;
"sun.net.httpserver.
maxReqTime
"
,
DEFAULT_MAX_REQ_TIME
))).
longValue
()
;
writeTimeout
=
((
Long
)
java
.
security
.
AccessController
.
doPrivileged
(
maxRspTime
=
((
Long
)
java
.
security
.
AccessController
.
doPrivileged
(
new
sun
.
security
.
action
.
GetLongAction
(
"sun.net.httpserver.
writeTimeout
"
,
defaultWriteTimeout
))).
longValue
()*
1000
;
"sun.net.httpserver.
maxRspTime
"
,
DEFAULT_MAX_RSP_TIME
))).
longValue
()
;
drainAmount
=
((
Long
)
java
.
security
.
AccessController
.
doPrivileged
(
timerMillis
=
((
Long
)
java
.
security
.
AccessController
.
doPrivileged
(
new
sun
.
security
.
action
.
GetLongAction
(
"sun.net.httpserver.
drainAmount
"
,
defaultDrainAmount
))).
longValue
();
"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
long
getSelCacheTimeout
()
{
return
selCacheTimeout
;
static
void
checkLegacyProperties
(
final
Logger
logger
)
{
// legacy properties that are no longer used
// print a warning to logger if they are set.
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 @@ class ServerConfig {
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
;
}
}
src/share/classes/sun/net/httpserver/ServerImpl.java
浏览文件 @
ef144a90
...
...
@@ -37,6 +37,7 @@ import java.util.logging.Level;
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 @@ class ServerImpl implements TimeSource {
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 @@ class ServerImpl implements TimeSource {
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 @@ class ServerImpl implements TimeSource {
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 @@ class ServerImpl implements TimeSource {
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 @@ class ServerImpl implements TimeSource {
allConnections
.
clear
();
idleConnections
.
clear
();
timer
.
cancel
();
if
(
timer1Enabled
)
{
timer1
.
cancel
();
}
}
Dispatcher
dispatcher
;
...
...
@@ -236,13 +261,6 @@ class ServerImpl implements TimeSource {
}
}
int
resultSize
()
{
synchronized
(
lolock
)
{
return
events
.
size
();
}
}
/* main server listener task */
class
Dispatcher
implements
Runnable
{
...
...
@@ -257,7 +275,7 @@ class ServerImpl implements TimeSource {
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 @@ class ServerImpl implements TimeSource {
}
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 @@ class ServerImpl implements TimeSource {
}
}
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
{
ListIterator
<
HttpConnection
>
li
=
connsToRegister
.
listIterator
();
for
(
HttpConnection
c
:
connsToRegister
)
{
reRegister
(
c
);
}
connsToRegister
.
clear
();
/* process the events list first */
List
<
Event
>
list
=
null
;
selector
.
select
(
1000
);
synchronized
(
lolock
)
{
if
(
events
.
size
()
>
0
)
{
list
=
events
;
events
=
new
LinkedList
<
Event
>();
}
}
while
(
resultSize
()
>
0
)
{
Event
r
;
synchronized
(
lolock
)
{
r
=
events
.
remove
(
0
);
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 @@ class ServerImpl implements TimeSource {
c
.
selectionKey
=
newkey
;
c
.
setChannel
(
chan
);
newkey
.
attach
(
c
);
requestStarted
(
c
);
allConnections
.
add
(
c
);
}
else
{
try
{
...
...
@@ -334,27 +375,44 @@ class ServerImpl implements TimeSource {
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 @@ class ServerImpl implements TimeSource {
executor
.
execute
(
t
);
}
catch
(
HttpError
e1
)
{
logger
.
log
(
Level
.
FINER
,
"Dispatcher (4)"
,
e1
);
c
onn
.
close
(
);
c
loseConnection
(
conn
);
}
catch
(
IOException
e
)
{
logger
.
log
(
Level
.
FINER
,
"Dispatcher (5)"
,
e
);
c
onn
.
close
(
);
c
loseConnection
(
conn
);
}
}
}
...
...
@@ -390,7 +448,26 @@ class ServerImpl implements TimeSource {
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 @@ class ServerImpl implements TimeSource {
requestLine
=
req
.
requestLine
();
if
(
requestLine
==
null
)
{
/* connection closed */
connection
.
close
();
allConnections
.
remove
(
connection
);
closeConnection
(
connection
);
return
;
}
int
space
=
requestLine
.
indexOf
(
' '
);
...
...
@@ -482,6 +558,9 @@ class ServerImpl implements TimeSource {
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 @@ class ServerImpl implements TimeSource {
}
catch
(
IOException
e1
)
{
logger
.
log
(
Level
.
FINER
,
"ServerImpl.Exchange (1)"
,
e1
);
c
onnection
.
close
(
);
c
loseConnection
(
connection
);
}
catch
(
NumberFormatException
e3
)
{
reject
(
Code
.
HTTP_BAD_REQUEST
,
requestLine
,
"NumberFormatException thrown"
);
...
...
@@ -569,7 +648,7 @@ class ServerImpl implements TimeSource {
requestLine
,
"URISyntaxException thrown"
);
}
catch
(
Exception
e4
)
{
logger
.
log
(
Level
.
FINER
,
"ServerImpl.Exchange (2)"
,
e4
);
c
onnection
.
close
(
);
c
loseConnection
(
connection
);
}
}
...
...
@@ -591,47 +670,60 @@ class ServerImpl implements TimeSource {
rejected
=
true
;
logReply
(
code
,
requestStr
,
message
);
sendReply
(
code
,
tru
e
,
"<h1>"
+
code
+
Code
.
msg
(
code
)+
"</h1>"
+
message
code
,
fals
e
,
"<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
)
{
c
onnection
.
close
(
);
c
loseConnection
(
connection
);
}
}
catch
(
IOException
e
)
{
logger
.
log
(
Level
.
FINER
,
"ServerImpl.sendReply"
,
e
);
c
onnection
.
close
(
);
c
loseConnection
(
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 @@ class ServerImpl implements TimeSource {
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 ServerImpl implements TimeSource {
}
}
}
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
;
}
}
}
test/com/sun/net/httpserver/Test.java
浏览文件 @
ef144a90
...
...
@@ -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
);
...
...
test/com/sun/net/httpserver/Test1.java
浏览文件 @
ef144a90
...
...
@@ -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
*/
...
...
test/com/sun/net/httpserver/Test13.java
浏览文件 @
ef144a90
...
...
@@ -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 @@ public class Test13 extends Test {
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 @@ public class Test13 extends Test {
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"
,
https
port
,
"smallfile.txt"
,
23
);
}
start
(
r
);
join
(
r
);
...
...
@@ -91,6 +99,7 @@ public class Test13 extends Test {
static
void
start
(
Runner
[]
x
)
{
for
(
int
i
=
0
;
i
<
x
.
length
;
i
++)
{
if
(
x
[
i
]
!=
null
)
x
[
i
].
start
();
}
}
...
...
@@ -98,6 +107,7 @@ public class Test13 extends Test {
static
void
join
(
Runner
[]
x
)
{
for
(
int
i
=
0
;
i
<
x
.
length
;
i
++)
{
try
{
if
(
x
[
i
]
!=
null
)
x
[
i
].
join
();
}
catch
(
InterruptedException
e
)
{}
}
...
...
test/com/sun/net/httpserver/bugs/6725892/Test.java
0 → 100644
浏览文件 @
ef144a90
/*
* 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
;
}
}
test/com/sun/net/httpserver/bugs/B6401598.java
浏览文件 @
ef144a90
...
...
@@ -83,7 +83,7 @@ public class B6401598 {
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
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录