Per RFC2616 (The HTTP/1.1 spec) Section 14.43 User-Agent. http://tools.ietf.org/html/rfc2616#section-14.43
You are required to provide a value, otherwise the header is deemed invalid. In your example request headers, jetty parses the User-Agent header, sees no valid, deems it to be bad, and excludes it from the header map. Jetty has a philosophy of being tolerant on what it can accept, and strict on what it generates. If we didn't have this philosophy, your bad header would result in an error 400 (Bad Request). The fact that Jetty 8 gave you a blank is that Jetty 8 had the bug of keeping a reference to a bad header. The Jetty 8 behavior is at best, undefined. With the common http handling introduced in Jetty 9 (for HTTP 1.0, HTTP 1.1, SPDY, and HTTP 2.0) many of these kinds of undefined behavior have been addressed. Sorry :( -- Joakim Erdfelt <[email protected]> webtide.com <http://www.webtide.com/> Developer advice, services and support from the Jetty & CometD experts eclipse.org/jetty - cometd.org On Fri, May 24, 2013 at 10:30 AM, Denis Bardadym <[email protected]>wrote: > Hello. > > I found that jetty 9.0.2.v20130417 HttpServletRequest.getHeader return > null when header is empty. You can see this in simple application: > > import java.io.IOException; > import javax.servlet.ServletException; > import javax.servlet.http.HttpServlet; > import javax.servlet.http.HttpServletRequest; > import javax.servlet.http.HttpServletResponse; > import org.eclipse.jetty.server.Server; > import org.eclipse.jetty.servlet.ServletHandler; > > public class MinimalServlets { > > public static void main(String[] args) throws Exception { > Server server = new Server(8080); > ServletHandler handler = new ServletHandler(); > server.setHandler(handler); > handler.addServletWithMapping(HelloServlet.class, "/*"); > server.start(); > server.join(); > } > > public static class HelloServlet extends HttpServlet { > > @Override > protected void doGet(HttpServletRequest request, > HttpServletResponse response) throws ServletException, IOException { > response.setContentType("text/html"); > response.setStatus(HttpServletResponse.SC_OK); > java.io.Writer w = response.getWriter(); > w.println(request.getHeader("User-Agent")); > w.println(request.getHeader("X-Not-Exists")); > } > } > } > > When i send curl request like this: > > mac:liftweb den$ curl -v -D - -H "User-Agent;" -H "User-Agent:" > http://localhost:8080 > * About to connect() to localhost port 8080 (#0) > * Trying ::1... > * connected > * Connected to localhost (::1) port 8080 (#0) > > GET / HTTP/1.1 > > Host: localhost:8080 > > Accept: */* > > User-Agent: > > > < HTTP/1.1 200 OK > HTTP/1.1 200 OK > < Content-Type: text/html; charset=ISO-8859-1 > Content-Type: text/html; charset=ISO-8859-1 > < Transfer-Encoding: chunked > Transfer-Encoding: chunked > < Server: Jetty(9.0.2.v20130417) > Server: Jetty(9.0.2.v20130417) > > < > null > null > * Connection #0 to host localhost left intact > * Closing connection #0 > > It returns both nulls. But by javadoc it should return null only if header > not presented but you see that User-Agent: just empty. > > This does not happen in jetty8: > > @SuppressWarnings("serial") > public class HelloServlet extends HttpServlet > { > String greeting = "Hello"; > > public HelloServlet() > { > } > > public HelloServlet(String hi) > { > greeting = hi; > } > > private String getVal(String s) { > if(s == null) return "null"; > else return s; > } > > @Override > protected void doGet(HttpServletRequest request, HttpServletResponse > response) throws ServletException, IOException > { > response.setContentType("text/html"); > response.setStatus(HttpServletResponse.SC_OK); > PrintWriter writer = response.getWriter(); > writer.println("User-Agent: " + > getVal(request.getHeader("User-Agent"))); > writer.println("X-Not-Exists: " + > getVal(request.getHeader("X-Not-Exists"))); > writer.flush(); > writer.close(); > } > } > > and > public class OneServletContext { > public static void main(String[] args) throws Exception { > Server server = new Server(8080); > > ServletContextHandler context = new > ServletContextHandler(ServletContextHandler.SESSIONS); > context.setContextPath("/"); > server.setHandler(context); > > // Server content from tmp > ServletHolder holder = > context.addServlet(org.eclipse.jetty.servlet.DefaultServlet.class, > "/tmp/*"); > holder.setInitParameter("resourceBase", "/tmp"); > holder.setInitParameter("pathInfoOnly", "true"); > > // Serve some hello world servlets > context.addServlet(new ServletHolder(new HelloServlet()), "/*"); > context.addServlet(new ServletHolder(new HelloServlet("Buongiorno > Mondo")), "/it/*"); > context.addServlet(new ServletHolder(new HelloServlet("Bonjour le > Monde")), "/fr/*"); > > server.start(); > server.join(); > } > } > > so when i send it request: > > mac:liftweb den$ curl -v -D - -H "User-Agent;" -H "User-Agent:" > http://localhost:8080 > * About to connect() to localhost port 8080 (#0) > * Trying ::1... > * connected > * Connected to localhost (::1) port 8080 (#0) > > GET / HTTP/1.1 > > Host: localhost:8080 > > Accept: */* > > User-Agent: > > > < HTTP/1.1 200 OK > HTTP/1.1 200 OK > < Content-Type: text/html;charset=ISO-8859-1 > Content-Type: text/html;charset=ISO-8859-1 > < Transfer-Encoding: chunked > Transfer-Encoding: chunked > < Server: Jetty(8.1.10.v20130312) > Server: Jetty(8.1.10.v20130312) > > < > User-Agent: > X-Not-Exists: null > * Connection #0 to host localhost left intact > * Closing connection #0 > > > Does it really bug?? > > Thanks, Denis Bardadym. > > > _______________________________________________ > jetty-users mailing list > [email protected] > https://dev.eclipse.org/mailman/listinfo/jetty-users >
_______________________________________________ jetty-users mailing list [email protected] https://dev.eclipse.org/mailman/listinfo/jetty-users
