Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
31a03cae
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看板
提交
31a03cae
编写于
12月 17, 2019
作者:
Y
yan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8185898: setRequestProperty(key, null) results in HTTP header without colon in request
Reviewed-by: phh, andrew
上级
c85b4e99
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
317 addition
and
4 deletion
+317
-4
src/share/classes/sun/net/www/MessageHeader.java
src/share/classes/sun/net/www/MessageHeader.java
+34
-4
test/sun/net/www/B8185898.java
test/sun/net/www/B8185898.java
+283
-0
未找到文件。
src/share/classes/sun/net/www/MessageHeader.java
浏览文件 @
31a03cae
...
...
@@ -288,14 +288,44 @@ class MessageHeader {
return
Collections
.
unmodifiableMap
(
m
);
}
/** Check if a line of message header looks like a request line.
* This method does not perform a full validation but simply
* returns false if the line does not end with 'HTTP/[1-9].[0-9]'
* @param line the line to check.
* @return true if the line might be a request line.
*/
private
boolean
isRequestline
(
String
line
)
{
String
k
=
line
.
trim
();
int
i
=
k
.
lastIndexOf
(
' '
);
if
(
i
<=
0
)
return
false
;
int
len
=
k
.
length
();
if
(
len
-
i
<
9
)
return
false
;
char
c1
=
k
.
charAt
(
len
-
3
);
char
c2
=
k
.
charAt
(
len
-
2
);
char
c3
=
k
.
charAt
(
len
-
1
);
if
(
c1
<
'1'
||
c1
>
'9'
)
return
false
;
if
(
c2
!=
'.'
)
return
false
;
if
(
c3
<
'0'
||
c3
>
'9'
)
return
false
;
return
(
k
.
substring
(
i
+
1
,
len
-
3
).
equalsIgnoreCase
(
"HTTP/"
));
}
/** Prints the key-value pairs represented by this
header. Also prints the RFC required blank line
at the end. Omits pairs with a null key. */
at the end. Omits pairs with a null key. Omits
colon if key-value pair is the requestline. */
public
synchronized
void
print
(
PrintStream
p
)
{
for
(
int
i
=
0
;
i
<
nkeys
;
i
++)
if
(
keys
[
i
]
!=
null
)
{
p
.
print
(
keys
[
i
]
+
(
values
[
i
]
!=
null
?
": "
+
values
[
i
]:
""
)
+
"\r\n"
);
StringBuilder
sb
=
new
StringBuilder
(
keys
[
i
]);
if
(
values
[
i
]
!=
null
)
{
sb
.
append
(
": "
+
values
[
i
]);
}
else
if
(
i
!=
0
||
!
isRequestline
(
keys
[
i
]))
{
sb
.
append
(
":"
);
}
p
.
print
(
sb
.
append
(
"\r\n"
));
}
p
.
print
(
"\r\n"
);
p
.
flush
();
...
...
test/sun/net/www/B8185898.java
0 → 100644
浏览文件 @
31a03cae
/*
* Copyright (c) 2019, 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 8185898
* @library /lib/testlibrary
* @run main/othervm B8185898
* @summary setRequestProperty(key, null) results in HTTP header without colon in request
*/
import
java.io.*
;
import
java.net.*
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.HashMap
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.stream.Collectors
;
import
java.util.Collections
;
import
jdk.testlibrary.net.URIBuilder
;
import
sun.net.www.MessageHeader
;
import
com.sun.net.httpserver.HttpContext
;
import
com.sun.net.httpserver.HttpExchange
;
import
com.sun.net.httpserver.HttpHandler
;
import
com.sun.net.httpserver.HttpServer
;
import
static
java
.
nio
.
charset
.
StandardCharsets
.
ISO_8859_1
;
import
static
java
.
nio
.
charset
.
StandardCharsets
.
UTF_8
;
/*
* Test checks that MessageHeader with key != null and value == null is set correctly
* and printed according to HTTP standard in the format <key>: <value>
* */
public
class
B8185898
{
static
HttpServer
server
;
static
final
String
RESPONSE_BODY
=
"Test response body"
;
static
final
String
H1
=
"X-header1"
;
static
final
String
H2
=
"X-header2"
;
static
final
String
VALUE
=
"This test value should appear"
;
static
final
List
<
String
>
oneList
=
Arrays
.
asList
(
VALUE
);
static
final
List
<
String
>
zeroList
=
Arrays
.
asList
(
""
);
static
int
port
;
static
URL
url
;
static
volatile
Map
<
String
,
List
<
String
>>
headers
;
static
class
Handler
implements
HttpHandler
{
public
void
handle
(
HttpExchange
t
)
throws
IOException
{
InputStream
is
=
t
.
getRequestBody
();
InetSocketAddress
rem
=
t
.
getRemoteAddress
();
headers
=
t
.
getRequestHeaders
();
// Get request headers on the server side
while
(
is
.
read
()
!=
-
1
){}
is
.
close
();
OutputStream
os
=
t
.
getResponseBody
();
t
.
sendResponseHeaders
(
200
,
RESPONSE_BODY
.
length
());
os
.
write
(
RESPONSE_BODY
.
getBytes
(
UTF_8
));
t
.
close
();
}
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
ExecutorService
exec
=
Executors
.
newCachedThreadPool
();
InetAddress
loopback
=
InetAddress
.
getLoopbackAddress
();
try
{
InetSocketAddress
addr
=
new
InetSocketAddress
(
loopback
,
0
);
server
=
HttpServer
.
create
(
addr
,
100
);
HttpHandler
handler
=
new
Handler
();
HttpContext
context
=
server
.
createContext
(
"/"
,
handler
);
server
.
setExecutor
(
exec
);
server
.
start
();
port
=
server
.
getAddress
().
getPort
();
System
.
out
.
println
(
"Server on port: "
+
port
);
url
=
URIBuilder
.
newBuilder
()
.
scheme
(
"http"
)
.
loopback
()
.
port
(
port
)
.
path
(
"/foo"
)
.
toURLUnchecked
();
System
.
out
.
println
(
"URL: "
+
url
);
testMessageHeader
();
testMessageHeaderMethods
();
testURLConnectionMethods
();
}
finally
{
server
.
stop
(
0
);
System
.
out
.
println
(
"After server shutdown"
);
exec
.
shutdown
();
}
}
// Test message header with malformed message header and fake request line
static
void
testMessageHeader
()
{
final
String
badHeader
=
"This is not a request line for HTTP/1.1"
;
final
String
fakeRequestLine
=
"This /is/a/fake/status/line HTTP/2.0"
;
final
String
expectedHeaders
=
fakeRequestLine
+
"\r\n"
+
H1
+
": "
+
VALUE
+
"\r\n"
+
H2
+
": "
+
VALUE
+
"\r\n"
+
badHeader
+
":\r\n\r\n"
;
MessageHeader
header
=
new
MessageHeader
();
header
.
add
(
H1
,
VALUE
);
header
.
add
(
H2
,
VALUE
);
header
.
add
(
badHeader
,
null
);
header
.
prepend
(
fakeRequestLine
,
null
);
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
();
header
.
print
(
new
PrintStream
(
out
));
if
(!
out
.
toString
().
equals
(
expectedHeaders
))
{
throw
new
AssertionError
(
"FAILED: expected: "
+
expectedHeaders
+
"\nReceived: "
+
out
.
toString
());
}
else
{
System
.
out
.
println
(
"PASSED: ::print returned correct "
+
"status line and headers:\n"
+
out
.
toString
());
}
}
// Test MessageHeader::print, ::toString, implicitly testing that
// MessageHeader::mergeHeader formats headers correctly for responses
static
void
testMessageHeaderMethods
()
throws
IOException
{
// {{inputString1, expectedToString1, expectedPrint1}, {...}}
String
[][]
strings
=
{
{
"HTTP/1.1 200 OK\r\n"
+
"Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+
"Connection: keep-alive\r\n"
+
"Host: 127.0.0.1:12345\r\n"
+
"User-agent: Java/12\r\n\r\nfoooo"
,
"pairs: {null: HTTP/1.1 200 OK}"
+
"{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}"
+
"{Connection: keep-alive}"
+
"{Host: 127.0.0.1:12345}"
+
"{User-agent: Java/12}"
,
"Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+
"Connection: keep-alive\r\n"
+
"Host: 127.0.0.1:12345\r\n"
+
"User-agent: Java/12\r\n\r\n"
},
{
"HTTP/1.1 200 OK\r\n"
+
"Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+
"Connection: keep-alive\r\n"
+
"Host: 127.0.0.1:12345\r\n"
+
"User-agent: Java/12\r\n"
+
"X-Header:\r\n\r\n"
,
"pairs: {null: HTTP/1.1 200 OK}"
+
"{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}"
+
"{Connection: keep-alive}"
+
"{Host: 127.0.0.1:12345}"
+
"{User-agent: Java/12}"
+
"{X-Header: }"
,
"Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n"
+
"Connection: keep-alive\r\n"
+
"Host: 127.0.0.1:12345\r\n"
+
"User-agent: Java/12\r\n"
+
"X-Header: \r\n\r\n"
},
};
System
.
out
.
println
(
"Test custom message headers"
);
for
(
String
[]
s
:
strings
)
{
// Test MessageHeader::toString
MessageHeader
header
=
new
MessageHeader
(
new
ByteArrayInputStream
(
s
[
0
].
getBytes
(
ISO_8859_1
)));
if
(!
header
.
toString
().
endsWith
(
s
[
1
]))
{
throw
new
AssertionError
(
"FAILED: expected: "
+
s
[
1
]
+
"\nReceived: "
+
header
);
}
else
{
System
.
out
.
println
(
"PASSED: ::toString returned correct "
+
"status line and headers:\n"
+
header
);
}
// Test MessageHeader::print
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
();
header
.
print
(
new
PrintStream
(
out
));
if
(!
out
.
toString
().
equals
(
s
[
2
]))
{
throw
new
AssertionError
(
"FAILED: expected: "
+
s
[
2
]
+
"\nReceived: "
+
out
.
toString
());
}
else
{
System
.
out
.
println
(
"PASSED: ::print returned correct "
+
"status line and headers:\n"
+
out
.
toString
());
}
}
}
// Test methods URLConnection::getRequestProperties,
// ::getHeaderField, ::getHeaderFieldKey
static
void
testURLConnectionMethods
()
throws
IOException
{
HttpURLConnection
urlConn
=
(
HttpURLConnection
)
url
.
openConnection
(
Proxy
.
NO_PROXY
);
urlConn
.
setRequestProperty
(
H1
,
""
);
urlConn
.
setRequestProperty
(
H1
,
VALUE
);
urlConn
.
setRequestProperty
(
H2
,
null
);
// Expected to contain ':' between key and value
Map
<
String
,
List
<
String
>>
props
=
urlConn
.
getRequestProperties
();
Map
<
String
,
List
<
String
>>
expectedMap
=
new
HashMap
<
String
,
List
<
String
>>();
expectedMap
.
put
(
H1
,
oneList
);
expectedMap
.
put
(
H2
,
Arrays
.
asList
((
String
)
null
));
// Test request properties
System
.
out
.
println
(
"Client request properties"
);
StringBuilder
sb
=
new
StringBuilder
();
props
.
forEach
((
k
,
v
)
->
sb
.
append
(
k
+
": "
+
v
.
stream
().
collect
(
Collectors
.
joining
())
+
"\n"
));
System
.
out
.
println
(
sb
);
if
(!
props
.
equals
(
expectedMap
))
{
throw
new
AssertionError
(
"Unexpected properties returned: "
+
props
);
}
else
{
System
.
out
.
println
(
"Properties returned as expected"
);
}
// Test header fields
String
headerField
=
urlConn
.
getHeaderField
(
0
);
if
(!
headerField
.
contains
(
"200 OK"
))
{
throw
new
AssertionError
(
"Expected headerField[0]: status line. "
+
"Received: "
+
headerField
);
}
else
{
System
.
out
.
println
(
"PASSED: headerField[0] contains status line: "
+
headerField
);
}
String
headerFieldKey
=
urlConn
.
getHeaderFieldKey
(
0
);
if
(
headerFieldKey
!=
null
)
{
throw
new
AssertionError
(
"Expected headerFieldKey[0]: null. "
+
"Received: "
+
headerFieldKey
);
}
else
{
System
.
out
.
println
(
"PASSED: headerFieldKey[0] is null"
);
}
// Check that test request headers are included with correct format
try
(
BufferedReader
in
=
new
BufferedReader
(
new
InputStreamReader
(
urlConn
.
getInputStream
()))
)
{
if
(!
headers
.
keySet
().
contains
(
H1
))
{
throw
new
AssertionError
(
"Expected key not found: "
+
H1
+
": "
+
VALUE
);
}
else
if
(!
headers
.
get
(
H1
).
equals
(
oneList
))
{
throw
new
AssertionError
(
"Unexpected key-value pair: "
+
H1
+
": "
+
headers
.
get
(
H1
));
}
else
{
System
.
out
.
println
(
"PASSED: "
+
H1
+
" included in request headers"
);
}
if
(!
headers
.
keySet
().
contains
(
H2
))
{
throw
new
AssertionError
(
"Expected key not found: "
+
H2
+
": "
);
// Check that empty list is returned
}
else
if
(!
headers
.
get
(
H2
).
equals
(
zeroList
))
{
throw
new
AssertionError
(
"Unexpected key-value pair: "
+
H2
+
": "
+
headers
.
get
(
H2
));
}
else
{
System
.
out
.
println
(
"PASSED: "
+
H2
+
" included in request headers"
);
}
String
inputLine
;
while
((
inputLine
=
in
.
readLine
())
!=
null
)
{
System
.
out
.
println
(
inputLine
);
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录