Reputation: 11753
I'm running an embedded Jetty (9.1.0.v20131115) setup, and have several Handlers setup to process requests on several different contexts.
One of these Handlers performs login functionality when the user submits a form. It's setup as follows:
ContextHandler loginContext = new ContextHandler("/login");
loginContext.setHandler(new LoginHandler());
// Other handlers go here...
contexts.setHandlers(new Handler[]{rootContext, logoutContext, loginContext, resourceHandler});
server.setHandler(contexts);
That should be pretty standard and is nothing special. What perplexes me is that when I run the LoginHandler through a debugger, the HttpServletRequest object has no parameters, even though the form clearly has two form input elements!
here's a copy of the request, which I caught via netcat:
POST /login HTTP/1.1
Host: localhost:52520
Connection: keep-alive
Content-Length: 31
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:52520
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:52520/dashboard/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
username=myuser&password=mypass
On top of that, if I change the form action to GET instead of POST the parameters show up just fine!
Is there anything special that must be done to get a Handler to accept POST parameters?
Upvotes: 0
Views: 2598
Reputation: 49515
Seems to work just fine.
package jetty;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.util.IO;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class JettyPostTest
{
public static class LoginHandler extends HandlerWrapper
{
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
PrintWriter out = response.getWriter();
response.setContentType("text/plain");
out.printf("username = %s\n",request.getParameter("username"));
out.printf("password = %s\n",request.getParameter("password"));
baseRequest.setHandled(true);
}
}
private static Server server;
private static int port;
@BeforeClass
public static void startServer() throws Exception
{
server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(0);
server.addConnector(connector);
// collection for handlers
HandlerCollection handlers = new HandlerCollection();
server.setHandler(handlers);
// login context
ContextHandler loginContext = new ContextHandler("/login");
loginContext.setHandler(new LoginHandler());
handlers.addHandler(loginContext);
// default handler
handlers.addHandler(new DefaultHandler());
// start server
server.start();
// grab port
port = connector.getLocalPort();
}
@AfterClass
public static void stopServer() throws Exception
{
server.stop();
}
@Test
public void testPostParameters() throws IOException
{
StringBuilder req = new StringBuilder();
req.append("POST /login/ HTTP/1.1\r\n");
req.append("Host: localhost:").append(port).append("\r\n");
req.append("Connection: close\r\n");
req.append("Content-Length: 31\r\n");
req.append("Cache-Control: max-age=0\r\n");
req.append("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n");
req.append("Origin: http://localhost:").append(port).append("\r\n");
req.append("User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36\r\n");
req.append("Content-Type: application/x-www-form-urlencoded\r\n");
req.append("Referer: http://localhost:").append(port).append("/dashboard/\r\n");
req.append("Accept-Encoding: gzip,deflate,sdch\r\n");
req.append("Accept-Language: en-US,en;q=0.8\r\n");
req.append("\r\n");
req.append("username=myuser&password=mypass\r\n");
try (Socket socket = new Socket())
{
socket.connect(new InetSocketAddress("localhost",port));
// Write request
try (OutputStream out = socket.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(out);
InputStream in = socket.getInputStream();
InputStreamReader reader = new InputStreamReader(in))
{
StringReader reqStream = new StringReader(req.toString());
IO.copy(reqStream,writer);
writer.flush();
out.flush();
StringWriter respStream = new StringWriter();
IO.copy(reader,respStream);
System.out.println(respStream.toString());
String expected = "username = myuser\npassword = mypass\n";
assertThat("Response",respStream.toString(),containsString(expected));
}
}
}
}
Results in the output:
2013-12-18 13:23:08.856:INFO:oejs.Server:main: jetty-9.1.0.v20131115
2013-12-18 13:23:08.888:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@49ada86{/login,null,AVAILABLE}
2013-12-18 13:23:08.897:INFO:oejs.ServerConnector:main: Started ServerConnector@3f14b553{HTTP/1.1}{0.0.0.0:34456}
HTTP/1.1 200 OK
Content-Type: text/plain; charset=ISO-8859-1
Connection: close
Server: Jetty(9.1.0.v20131115)
username = myuser
password = mypass
2013-12-18 13:23:08.994:INFO:oejs.ServerConnector:main: Stopped ServerConnector@3f14b553{HTTP/1.1}{0.0.0.0:0}
2013-12-18 13:23:08.995:INFO:oejsh.ContextHandler:main: Stopped o.e.j.s.h.ContextHandler@49ada86{/login,null,UNAVAILABLE}
Only change I made from your request is to change Connection: keep-alive
to Connection: close
to let jetty close the connection. This change is minor and only made to allow the test to execute swiftly, using the original value does not change the results of the test.
Something piece of information is missing from your question.
Upvotes: 2