260 likes | 357 Views
Core Servlets chapter 5: HTTP request headers. Requesting header information. It is possible that information the servlet needs is not in the form data but is in the request headers, which contain Accept, Accept-Encoding, Connection, Cookie, Host, Referer and User-Agent.
E N D
Requesting header information • It is possible that information the servlet needs is not in the form data but is in the request headers, which contain Accept, Accept-Encoding, Connection, Cookie, Host, Referer and User-Agent. • The servlet needs to explicitly read these. • To read, call (String) getHeader method of HTTPServletRequest with the name of the specific header passed in. • Always check for null on return because the header may not have been sent. • The header names are not case sensitive.
Requesting header information Some headers are used so frequently thay have their own specifically defined methods: • getCookies…. Will parse and store in an array of Cookie objects • getAuthType, getRemoteUser • getContentLength – an int • getContentType returns String • getDateHeader and getIntHeader return Date and int values • getHeaderNames returns an Enumeration of all headers • getHeaders returns an Enumeration of all occurences of a header
The request line itself Methods in HTTPServletRequest return information from the first line of the request: • getMethod …returns GET, POST, or other method • getRequestURI returns the part of the request after the host and port number but before the form data • getQueryString returns form data • getProtocol returns HTTP/1.0 or HTTP/1.1 and should generally be checked before specifying response headers specific to HTTP/1.1
A servlet which returns all header information • Calling getHeaderNames returns an Enumeration of all headers. Looping through this with calls to getHeader returns values. These are used to populate a table.
From wikipedia…MIME • Multipurpose Internet Mail Extensions (MIME) is an Internet standard that extends the format of e-mail to support: • text in character sets other than US-ASCII; • non-text attachments; • message bodies with multiple parts; and • header information in non-ASCII character sets. • MIME's use, however, has grown beyond describing the content of e-mail to describing content type in general.
Understanding request headers • Accept -all MIME types accepted by the browser.. For example not all browsers support png format. • Accept-Charset – what char set the broswer can use • Accept-Encoding –eg., gzip and zip • Accept-Language – en, en-us, and so on • Authorization – used by client for identification when accessing pw/protected pages • Connection • Content-length - applicable only to post requests, it gives the size of the POST data in bytes • Cookie- returns cookies to servers that sent them to the browser… Don’t read this directly… instead use request.getCookies() • Host • User-Agent – The browser or client making the request. It can be used to return different content to different browsers. For example, you might send wml to a phone or html to a conventional broswer. • If-Modified-since • If-unmodified since • Referer – provides URL of referring webpage. Tells you where a request came from, for example, tracking advertisers referring customers to your site, modifying response if the request came from within or outside your site, etc. Many broswers filter out this header (Norton, Opera)
Sending compressed data: note from the table above the browser accepts gzip format
Using gzip utilities: three static functions package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.zip.*; public class GzipUtilities { /** Does the client support gzip? */ public static boolean isGzipSupported (HttpServletRequest request) { String encodings = request.getHeader("Accept-Encoding"); return((encodings != null) && (encodings.indexOf("gzip") != -1)); } /** Has user disabled gzip (e.g., for benchmarking)? */ public static boolean isGzipDisabled (HttpServletRequest request) { String flag = request.getParameter("disableGzip"); return((flag != null) && (!flag.equalsIgnoreCase("false"))); } /** Return gzipping PrintWriter for response. */ public static PrintWriter getGzipWriter (HttpServletResponse response) throws IOException { return(new PrintWriter (new GZIPOutputStream (response.getOutputStream()))); }}
A servlet that generates lots of content package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class LongServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); // Change the definition of "out" depending on whether or not gzip is supported. PrintWriter out; if (GzipUtilities.isGzipSupported(request) && !GzipUtilities.isGzipDisabled(request)) { out = GzipUtilities.getGzipWriter(response); response.setHeader("Content-Encoding", "gzip"); } else { out = response.getWriter(); } // Once "out" has been assigned appropriately, the rest of the page has no dependencies on the type of writer being used. String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; String title = "Long Page"; out.println (docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=\"CENTER\">" + title + "</H1>\n"); String line = "Blah, blah, blah, blah, blah. " + "Yadda, yadda, yadda, yadda."; for(int i=0; i<10000; i++) { out.println(line); } out.println("</BODY></HTML>"); out.close(); // Needed for gzip; optional otherwise. }}
Previous example • In this example, the servlet checked to see if the browser accepted a zipped format for content, and, if it did, it sent the page using gzip.
Checking browser type • In this as in all examples, be sure to check that request.getHeader() is not null. • Do not use this generally, as many browsers allow you to change the value sent by user-agent. • The next example sends browser-specific insults to the user.
The servlet package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class BrowserInsult extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title, message; // Assume for simplicity that Netscape and IE are the only two browsers String userAgent = request.getHeader("User-Agent"); if ((userAgent != null) && (userAgent.indexOf("MSIE") != -1)) { title = "Microsoft Minion"; message = "Welcome, O spineless slave to the " + "mighty empire."; } else { title = "Hopeless Netscape Rebel"; message = "Enjoy it while you can. " + "You <I>will</I> be assimilated!"; } String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + message + "\n" + "</BODY></HTML>"); }}
Webclient sends no header- I added code to catch null pointer exception
Customizing display based on Referer • The next example checks if the header “Referer” contains one of three strings and displays different images accordingly. • I am not sure where the images are in terms of the text. I just found my own gif files. • This would be useful if you wanted to: • use a display type similar to the sender • Wanted different display for someone visiting from outside than for someone arriving here from an internal link
3 html files – identical except name – this is JRunreferer.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD><TITLE>Referer Test</TITLE></HEAD> <BODY BGCOLOR="#FDF5E6"> <H1 ALIGN="CENTER">Referer Test</H1> Click <A HREF="http://localhost/servlet/coreservlets.CustomizeImage">here</A> to visit the servlet. </BODY></HTML>
Most of the servlet public class CustomizeImage extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String referer = request.getHeader("Referer"); if (referer == null) { referer = "<I>none</I>"; } String title = "Referring page: " + referer; String imageName; if (contains(referer, "JRun")) { imageName = "jrun-powered.gif"; } else if (contains(referer, "Resin")) { imageName = "resin-powered.gif"; } else { imageName = "tomcat-powered.ico"; } String imagePath = "../request-headers/images/" + imageName; String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<CENTER><H2>" + title + "</H2>\n" + "<IMG SRC=\"" + imagePath + "\">\n" + "</CENTER></BODY></HTML>"); } private boolean contains(String mainString, String subString) { return(mainString.indexOf(subString) != -1); }}
Accessing the standard CGI variables • These are variables based on header information, on the socket (name and IP of the requesting host), or from server installation parameters like mapping URLs to physical paths. • Common Gateway Interface programmers (Perl, eg.) would be familiar with these.
More remarks on CGI vars • The text suggests unless you have a CGI background, you can skim this section, • But note you can use • getServletContext().getRealPath to map a URI (the part of the URL after the host/port info) to an actual path • Request.getRemoteHost and request.getRemoteAddress to get the name and IP of the client.
(Most of) ShowCGIVariables public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String[][] variables = { { "AUTH_TYPE", request.getAuthType() }, { "CONTENT_LENGTH", String.valueOf(request.getContentLength()) }, { "CONTENT_TYPE", request.getContentType() }, { "DOCUMENT_ROOT", getServletContext().getRealPath("/") }, { "PATH_INFO", request.getPathInfo() }, { "PATH_TRANSLATED", request.getPathTranslated() }, { "QUERY_STRING", request.getQueryString() }, { "REMOTE_ADDR", request.getRemoteAddr() }, { "REMOTE_HOST", request.getRemoteHost() }, //more like this { "SERVER_PROTOCOL", request.getProtocol() }, { "SERVER_SOFTWARE", getServletContext().getServerInfo() } }; String title = "Servlet Example: Showing CGI Variables"; String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; out.println(docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<CENTER>\n" + "<H1>" + title + "</H1>\n" + "<TABLE BORDER=1>\n" + " <TR BGCOLOR=\"#FFAD00\">\n" + " <TH>CGI Variable Name<TH>Value"); for(int i=0; i<variables.length; i++) { String varName = variables[i][0]; String varValue = variables[i][1]; if (varValue == null) varValue = "<I>Not specified</I>"; out.println(" <TR><TD>" + varName + "<TD>" + varValue); } out.println("</TABLE></CENTER></BODY></HTML>"); } }