/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 4774503
* @summary Calling HttpURLConnection's disconnect method after the
* response has been received causes havoc with persistent
* connections.
*/
public class DisconnectAfterEOF {
/*
* Worker thread to service single connection - can service
* multiple http requests on same connection.
*/
Socket s;
this.s = s;
}
public void run() {
try {
new BufferedOutputStream(
s.getOutputStream() ));
byte b[] = new byte[1024];
int n = -1;
int cl = -1;
int remaining = -1;
boolean close = false;
boolean inBody = false;
for (;;) {
boolean sendResponse = false;
try {
} catch (IOException ioe) {
n = -1;
}
if (n <= 0) {
if (inBody) {
"entire request received.");
}
return;
}
// reading entity-body
if (inBody) {
if (n > remaining) {
return;
}
remaining -= n;
if (remaining == 0) {
sendResponse = true;
n = 0;
} else {
continue;
}
}
// reading headers
for (int i=0; i<n; i++) {
char c = (char)b[i];
if (c != '\n') {
continue;
}
// Got end-of-line
if (len > 0) {
return;
}
}
// empty line
if (cl < 0) {
return;
}
// the surplus is body data
int dataRead = n - (i+1);
if (remaining > 0) {
inBody = true;
break;
} else {
// entire body has been read
sendResponse = true;
}
} else {
// non-empty line - check for Content-Length
}
close =true;
}
}
}
sb = new StringBuffer();
}
if (sendResponse) {
// send a large response
int rspLen = 32000;
if (rspLen > 0)
if (close)
return;
sendResponse = false;
inBody = false;
cl = -1;
}
}
} catch (IOException ioe) {
} finally {
try {
s.close();
} catch (Exception e) { }
}
}
}
/*
* Server thread to accept connection and create worker threads
* to service each connection.
*/
}
public void run() {
try {
for (;;) {
w.start();
}
} catch (IOException ioe) {
}
}
public void shutdown() {
try {
} catch (IOException ioe) { }
}
}
uc.setDoOutput(true);
// force the request to be sent
uc.getInputStream();
return uc;
}
byte b[] = new byte[4096];
int n;
do {
if (n > 0) cl -= n;
} while (n > 0);
if (cl != 0) {
throw new RuntimeException("ERROR: content-length mismatch");
}
return uc;
}
// start server
"/foo.html";
/*
* The following is the test scenario we create here :-
*
* to EOF. As it's a persistent connection the idle
* connection should go into the keep-alive cache for a
* few seconds.
*
* 2. We start a second request but don't read the response.
* As the request is to the same server we can assume it
* (for our implementation anyway) that it will use the
* same TCP connection.
*
* 3. We "disconnect" the first HttpURLConnection. This
* should be no-op because the connection is in use
* but another request. However with 1.3.1 and 1.4/1.4.1
* this causes the TCP connection for the second request
* to be closed.
*
*/
try {
} catch (IOException x) {
ioe = x;
}
/*
* Shutdown server as we are done. Worker threads created
* by the server will shutdown automatically when the
* client connection closes.
*/
throw ioe;
}
}
}