/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2009-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.grizzly.http;
import com.sun.grizzly.ControllerStateListenerAdapter;
import com.sun.grizzly.http.utils.SelectorThreadUtils;
import com.sun.grizzly.tcp.http11.GrizzlyAdapter;
import com.sun.grizzly.tcp.http11.GrizzlyRequest;
import com.sun.grizzly.tcp.http11.GrizzlyResponse;
import com.sun.grizzly.util.Utils;
import com.sun.grizzly.util.http.MimeHeaders;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.logging.Level;
import java.util.logging.Logger;
import junit.framework.TestCase;
/**
* Basic {@link SelectorThread} test.
*
* @author Jeanfrancois Arcand
*/
public class BasicSelectorThreadTest extends TestCase {
private final static Logger logger = SelectorThread.logger();
public static final int PORT = 18890;
private SelectorThread st;
public void createSelectorThread(int port) {
st = new SelectorThread() {
/**
* Start the SelectorThread using its own thread and don't block the Thread.
* This method should be used when Grizzly is embedded.
*/
@Override
public void listen() throws IOException, InstantiationException {
initEndpoint();
final CountDownLatch latch = new CountDownLatch(1);
controller.addStateListener(new ControllerStateListenerAdapter() {
@Override
public void onReady() {
enableMonitoring();
latch.countDown();
}
@Override
public void onException(Throwable e) {
if (latch.getCount() > 0) {
logger().log(Level.SEVERE, "Exception during " +
"starting the controller", e);
latch.countDown();
} else {
logger().log(Level.SEVERE, "Exception during " +
"controller processing", e);
}
}
});
super.start();
try {
latch.await();
} catch (InterruptedException ex) {
}
if (!controller.isStarted()) {
throw new IllegalStateException("Controller is not started!");
}
}
};
st.setPort(port);
st.setDisplayConfiguration(Utils.VERBOSE_TESTS);
}
protected HttpURLConnection getConnection(String alias, int port) throws IOException {
URL url = new URL("http", "localhost", port, alias);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
urlConn.connect();
return urlConn;
}
public void testKeepAliveTest() throws Exception{
Utils.dumpOut("Test: testKeepAliveTest");
try {
createSelectorThread(0);
st.setAdapter(new HelloWorldAdapter());
st.setMaxKeepAliveRequests(0);
SelectorThread.enableNioLogging = true;
st.listen();
HttpURLConnection conn = getConnection("/", st.getPort());
String s = conn.getHeaderField("Connection");
assertEquals(s, "close");
} finally {
SelectorThreadUtils.stopSelectorThread(st);
}
}
public void testMultipleBytesMimeHeaders() throws Exception{
Utils.dumpOut("Test: testMultipleBytesMimeHeaders");
try {
createSelectorThread(0);
st.setAdapter(new GrizzlyAdapter() {
private final byte[] test = "test-1".getBytes();
private final byte[] test2 = "test-2".getBytes();
private final byte[] test3 = "test-3".getBytes();
private final byte[] test4 = "test-4".getBytes();
@Override
public void service(GrizzlyRequest request, GrizzlyResponse response) {
MimeHeaders m1 = response.getResponse().getMimeHeaders();
m1.addValue("Set-Cookie").setBytes(test, 0, test.length);
m1.addValue("Set-Cookie").setBytes(test2, 0, test2.length);
m1.addValue("Set-Cookie").setBytes(test3, 0, test3.length);
m1.addValue("Set-Cookie").setBytes(test4, 0, test4.length);
}
});
st.setMaxKeepAliveRequests(0);
SelectorThread.enableNioLogging = true;
logger.setLevel(Level.WARNING);
st.listen();
Socket s = new Socket("localhost", st.getPort());
s.setSoTimeout(30 * 1000);
OutputStream os = s.getOutputStream();
Utils.dumpErr("GET / HTTP/1.1\n");
os.write("GET / HTTP/1.1\n".getBytes());
os.write(("Host: localhost:" + PORT + "\n").getBytes());
os.write("\n".getBytes());
os.flush();
InputStream is = new DataInputStream(s.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
Utils.dumpErr("================== reading the response");
boolean gotCorrectResponse = false;
int i = 0;
while ((line = br.readLine()) != null) {
Utils.dumpErr("-> " + line);
if (line.startsWith("Set-Cookie")) {
if (line.endsWith("test-" + ++i)){
gotCorrectResponse = true;
} else {
gotCorrectResponse = false;
}
}
}
assertTrue(gotCorrectResponse);
} finally {
SelectorThreadUtils.stopSelectorThread(st);
}
}
public void testKeepAliveNotFoundTest() throws Exception{
Utils.dumpOut("Test: testKeepAliveNotFoundTest");
try {
createSelectorThread(0);
st.setAdapter(new NotFoundAdapter());
st.setMaxKeepAliveRequests(0);
SelectorThread.enableNioLogging = true;
st.listen();
HttpURLConnection conn = getConnection("/404.html", st.getPort());
String s = conn.getHeaderField("Connection");
assertEquals(s, "close");
} finally {
SelectorThreadUtils.stopSelectorThread(st);
}
}
public void testEphemeralPort() throws Exception {
Utils.dumpOut("Test: testEphemeralPort");
final String testString = "HelloWorld";
final byte[] testData = testString.getBytes();
try {
createSelectorThread(0);
st.setAdapter(new HelloWorldAdapter());
st.listen();
sendRequest(testData, testString, st.getPort());
} finally {
SelectorThreadUtils.stopSelectorThread(st);
}
}
public void testHelloWorldGrizzlyAdapter() throws Exception {
Utils.dumpOut("Test: testHelloWorldGrizzlyAdapter");
final ScheduledThreadPoolExecutor pe = new ScheduledThreadPoolExecutor(1);
final String testString = "HelloWorld";
final byte[] testData = testString.getBytes();
try {
createSelectorThread(PORT);
st.setAdapter(new HelloWorldAdapter());
st.listen();
st.enableMonitoring();
sendRequest(testData, testString, PORT);
} finally {
SelectorThreadUtils.stopSelectorThread(st);
pe.shutdown();
}
}
public class NotFoundAdapter extends GrizzlyAdapter {
@Override
public void service(GrizzlyRequest request, GrizzlyResponse response) {
response.setStatus(404, "Not Found");
}
}
public class HelloWorldAdapter extends GrizzlyAdapter {
@Override
public void service(GrizzlyRequest request, GrizzlyResponse response) {
try {
response.getWriter().println("HelloWorld");
} catch (IOException ex) {
ex.printStackTrace();
fail(ex.getMessage());
}
}
}
private String sendRequest(byte[] testData, String testString, int port)
throws Exception {
return sendRequest(testData, testString, true, port);
}
private String sendRequest(byte[] testData, String testString, boolean assertTrue, int port)
throws Exception {
URL url = new URL("http://localhost:" + port);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
OutputStream os = connection.getOutputStream();
os.write("Hello".getBytes());
os.flush();
InputStream is = new DataInputStream(connection.getInputStream());
byte[] response = new byte[testData.length];
is.read(response);
String r = new String(response);
if (assertTrue) {
Utils.dumpOut("Response: " + r);
assertEquals(testString, r);
}
connection.disconnect();
return r;
}
}