mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-15 13:39:06 +00:00
8011719: Properties.loadFromXML fails with a chunked HTTP connection
Reviewed-by: michaelm
This commit is contained in:
parent
ee8568fe00
commit
8b35e25262
@ -3158,6 +3158,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
private boolean marked = false;
|
||||
private int inCache = 0;
|
||||
private int markCount = 0;
|
||||
private boolean closed; // false
|
||||
|
||||
public HttpInputStream (InputStream is) {
|
||||
super (is);
|
||||
@ -3233,8 +3234,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureOpen() throws IOException {
|
||||
if (closed)
|
||||
throw new IOException("stream is closed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
ensureOpen();
|
||||
try {
|
||||
byte[] b = new byte[1];
|
||||
int ret = read(b);
|
||||
@ -3254,6 +3261,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
ensureOpen();
|
||||
try {
|
||||
int newLen = super.read(b, off, len);
|
||||
int nWrite;
|
||||
@ -3291,7 +3299,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
|
||||
@Override
|
||||
public long skip (long n) throws IOException {
|
||||
|
||||
ensureOpen();
|
||||
long remaining = n;
|
||||
int nr;
|
||||
if (skipBuffer == null)
|
||||
@ -3317,6 +3325,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
|
||||
@Override
|
||||
public void close () throws IOException {
|
||||
if (closed)
|
||||
return;
|
||||
|
||||
try {
|
||||
if (outputStream != null) {
|
||||
if (read() != -1) {
|
||||
@ -3332,6 +3343,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
|
||||
}
|
||||
throw ioex;
|
||||
} finally {
|
||||
closed = true;
|
||||
HttpURLConnection.this.http = null;
|
||||
checkResponseCredentials (true);
|
||||
}
|
||||
|
||||
185
jdk/test/sun/net/www/protocol/http/HttpStreams.java
Normal file
185
jdk/test/sun/net/www/protocol/http/HttpStreams.java
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 8011719
|
||||
* @summary Basic checks to verify behavior of returned input streams
|
||||
*/
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public class HttpStreams {
|
||||
|
||||
void client(String u) throws Exception {
|
||||
byte[] ba = new byte[5];
|
||||
HttpURLConnection urlc = (HttpURLConnection)(new URL(u)).openConnection();
|
||||
int resp = urlc.getResponseCode();
|
||||
InputStream is;
|
||||
if (resp == 200)
|
||||
is = urlc.getInputStream();
|
||||
else
|
||||
is = urlc.getErrorStream();
|
||||
|
||||
expectNoThrow(() -> { is.read(); }, "read on open stream should not throw :" + u);
|
||||
expectNoThrow(() -> { is.close(); }, "close should never throw: " + u);
|
||||
expectNoThrow(() -> { is.close(); }, "close should never throw: " + u);
|
||||
expectThrow(() -> { is.read(); }, "read on closed stream should throw: " + u);
|
||||
expectThrow(() -> { is.read(ba); }, "read on closed stream should throw: " + u);
|
||||
expectThrow(() -> { is.read(ba, 0, 2); }, "read on closed stream should throw: " + u);
|
||||
}
|
||||
|
||||
void test() throws Exception {
|
||||
HttpServer server = null;
|
||||
try {
|
||||
server = startHttpServer();
|
||||
String baseUrl = "http://localhost:" + server.getAddress().getPort() + "/";
|
||||
client(baseUrl + "chunked/");
|
||||
client(baseUrl + "fixed/");
|
||||
client(baseUrl + "error/");
|
||||
client(baseUrl + "chunkedError/");
|
||||
|
||||
// Test with a response cache
|
||||
ResponseCache ch = ResponseCache.getDefault();
|
||||
ResponseCache.setDefault(new TrivialCacheHandler());
|
||||
try {
|
||||
client(baseUrl + "chunked/");
|
||||
client(baseUrl + "fixed/");
|
||||
client(baseUrl + "error/");
|
||||
client(baseUrl + "chunkedError/");
|
||||
} finally {
|
||||
ResponseCache.setDefault(ch);
|
||||
}
|
||||
} finally {
|
||||
if (server != null)
|
||||
server.stop(0);
|
||||
}
|
||||
|
||||
System.out.println("passed: " + pass + ", failed: " + fail);
|
||||
if (fail > 0)
|
||||
throw new RuntimeException("some tests failed check output");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
(new HttpStreams()).test();
|
||||
}
|
||||
|
||||
// HTTP Server
|
||||
HttpServer startHttpServer() throws IOException {
|
||||
HttpServer httpServer = HttpServer.create(new InetSocketAddress(0), 0);
|
||||
httpServer.createContext("/chunked/", new ChunkedHandler());
|
||||
httpServer.createContext("/fixed/", new FixedHandler());
|
||||
httpServer.createContext("/error/", new ErrorHandler());
|
||||
httpServer.createContext("/chunkedError/", new ChunkedErrorHandler());
|
||||
httpServer.start();
|
||||
return httpServer;
|
||||
}
|
||||
|
||||
static abstract class AbstractHandler implements HttpHandler {
|
||||
@Override
|
||||
public void handle(HttpExchange t) throws IOException {
|
||||
try (InputStream is = t.getRequestBody()) {
|
||||
while (is.read() != -1);
|
||||
}
|
||||
t.sendResponseHeaders(respCode(), length());
|
||||
try (OutputStream os = t.getResponseBody()) {
|
||||
os.write(message());
|
||||
}
|
||||
t.close();
|
||||
}
|
||||
|
||||
abstract int respCode();
|
||||
abstract int length();
|
||||
abstract byte[] message();
|
||||
}
|
||||
|
||||
static class ChunkedHandler extends AbstractHandler {
|
||||
static final byte[] ba =
|
||||
"Hello there from chunked handler!".getBytes(StandardCharsets.US_ASCII);
|
||||
int respCode() { return 200; }
|
||||
int length() { return 0; }
|
||||
byte[] message() { return ba; }
|
||||
}
|
||||
|
||||
static class FixedHandler extends AbstractHandler {
|
||||
static final byte[] ba =
|
||||
"Hello there from fixed handler!".getBytes(StandardCharsets.US_ASCII);
|
||||
int respCode() { return 200; }
|
||||
int length() { return ba.length; }
|
||||
byte[] message() { return ba; }
|
||||
}
|
||||
|
||||
static class ErrorHandler extends AbstractHandler {
|
||||
static final byte[] ba =
|
||||
"This is an error mesg from the server!".getBytes(StandardCharsets.US_ASCII);
|
||||
int respCode() { return 400; }
|
||||
int length() { return ba.length; }
|
||||
byte[] message() { return ba; }
|
||||
}
|
||||
|
||||
static class ChunkedErrorHandler extends ErrorHandler {
|
||||
int length() { return 0; }
|
||||
}
|
||||
|
||||
static class TrivialCacheHandler extends ResponseCache
|
||||
{
|
||||
public CacheResponse get(URI uri, String rqstMethod, Map rqstHeaders) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CacheRequest put(URI uri, URLConnection conn) {
|
||||
return new TrivialCacheRequest();
|
||||
}
|
||||
}
|
||||
|
||||
static class TrivialCacheRequest extends CacheRequest
|
||||
{
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
public void abort() {}
|
||||
public OutputStream getBody() throws IOException { return baos; }
|
||||
}
|
||||
|
||||
static interface ThrowableRunnable {
|
||||
void run() throws IOException;
|
||||
}
|
||||
|
||||
void expectThrow(ThrowableRunnable r, String msg) {
|
||||
try { r.run(); fail(msg); } catch (IOException x) { pass(); }
|
||||
}
|
||||
|
||||
void expectNoThrow(ThrowableRunnable r, String msg) {
|
||||
try { r.run(); pass(); } catch (IOException x) { fail(msg, x); }
|
||||
}
|
||||
|
||||
private int pass;
|
||||
private int fail;
|
||||
void pass() { pass++; }
|
||||
void fail(String msg, Exception x) { System.out.println(msg); x.printStackTrace(); fail++; }
|
||||
void fail(String msg) { System.out.println(msg); Thread.dumpStack(); fail++; }
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user