/*
* 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 4203167
*
* @summary RMI blocks in HttpAwareServerSocket.accept() if you telnet to it
* @author Adrian Colley
*
* @library ../../../../../java/rmi/testlibrary
* @build TestIface TestImpl TestImpl_Stub
* @run main/othervm/policy=security.policy/timeout=60 BlockAcceptTest
*/
/* This test attempts to stymie the RMI accept loop. The accept loop in
* RMI endlessly accepts a connection, spawns a thread for it, and repeats.
* The accept() call can be replaced by a user-supplied library which
* might foolishly block indefinitely in its accept() method, which would
* prevent RMI from accepting other connections on that socket.
*
* a foolish thing. It reads 4 bytes to see if they're "POST" before
* returning. The bug fix is to move the HTTP stuff into the mainloop,
* which has the side effect of enabling it for non-default socketfactories.
*
* This test:
* 1. Creates an object and exports it.
* 2. Connects to the listening RMI port and sends nothing, to hold it up.
* 3. Makes a regular call, using HTTP tunnelling.
* 4. Fails to deadlock, thereby passing the test.
*
* Some runtime dependencies I'm trying to eliminate:
* 1. We don't know the port number until after exporting the object, but
* have to set it in http.proxyPort somehow. Hopefully http.proxyPort
* isn't read too soon or this test will fail with a ConnectException.
*/
public class BlockAcceptTest
{
throws Exception
{
// Make trouble for ourselves
// HTTP direct to the server port
// Set the socket factory.
// Create remote object
// Export and get which port.
try {
// Sanity
if (port == 0)
throw new Error("TEST FAILED: export didn't reserve a port(?)");
// Set the HTTP port, at last.
// Now, connect to that port
//Thread.sleep(2000);
port + ")");
// we hold the connection open until done with the test.
// The test itself: make a remote call and see if it's blocked or
// if it works
//Thread.sleep(2000);
throw new Error("TEST FAILED: result not OK");
// Clean up, including writing a byte to that connection just in
// case an optimizer thought of optimizing it out of existence
try {
}
} finally {
try {
}
}
// Should exit here
}
private static class HttpOutFactory
extends RMISocketFactory
{
throws IOException
{
return ((new RMIHttpToPortSocketFactory()).createSocket(h, p));
}
/** Create a server socket and remember which port it's on.
* Aborts if createServerSocket(0) is called twice, because then
* it doesn't know whether to remember the first or second port.
*/
throws IOException
{
if (p == 0) {
if (servport != 0) {
"Duplicate createServerSocket(0)");
throw new Error("Test aborted (createServerSocket)");
}
}
return (ss);
}
/** Return which port was reserved by createServerSocket(0).
* If the return value was 0, createServerSocket(0) wasn't called.
*/
public int whichPort() {
return (servport);
}
} // end class HttpOutFactory
}