| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package flex.messaging.log; |
| |
| import javax.servlet.ServletContext; |
| import javax.servlet.http.HttpServletRequest; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.Date; |
| import java.util.Enumeration; |
| |
| |
| /** |
| * Static class to log HTTP request data when it is wrapped by our LoggingHttpServletRequestWrapper. |
| */ |
| public class HTTPRequestLog { |
| /** |
| * Request attribute for storing error info. |
| */ |
| public static final String HTTP_ERROR_INFO = "org.apache.flex.blazeds.internal._exception_info"; |
| |
| // Default file name |
| private static String filename; |
| |
| /** |
| * Called to set up filename for HTTP request logging. |
| * If the init parameter <b>HttpErrorLog</b> is set in the servlet context, its value is set as the output filename |
| * |
| * @param context the ServletContext object |
| * @return true if request logging is enabled. |
| */ |
| public static boolean init(ServletContext context) { |
| // Get the HttpRequest log file information. |
| String logfile = context.getInitParameter("HttpErrorLog"); |
| if (logfile == null || logfile.length() == 0) { |
| return false; |
| } |
| filename = logfile; |
| return true; |
| } |
| |
| /** |
| * Change the output file name. |
| * |
| * @param fileName the file name |
| */ |
| public static void setFileName(String fileName) { |
| if (fileName != null) { |
| filename = fileName; |
| } |
| } |
| |
| /** |
| * Get the file name. |
| * |
| * @return String the file name |
| */ |
| public static String getFileName() { |
| return filename; |
| } |
| |
| /** |
| * Log the HTTP request if logging turned on and we have a filename. |
| * |
| * @param header the header name |
| * @param httpReq the HttpServletRequest |
| */ |
| public static synchronized void outputRequest(String header, HttpServletRequest httpReq) { |
| // If things aren't set up, do nothing. |
| if (!(httpReq instanceof LoggingHttpServletRequestWrapper) || filename == null) { |
| return; |
| } |
| |
| LoggingHttpServletRequestWrapper req = (LoggingHttpServletRequestWrapper) httpReq; |
| FileWriter fw = null; |
| try { |
| // Open the file |
| fw = new FileWriter(filename, true); |
| fw.write("#===== Request Client Infomation =====#" + "\n"); |
| if (header != null) { |
| fw.write("Error : " + header + "\n"); |
| } |
| fw.write("Timestamp : " + new Date(System.currentTimeMillis()).toString() + "\n"); |
| fw.write("Client IP Address : " + req.getRemoteAddr() + "\n"); |
| fw.write("Client FQDN : " + req.getRemoteHost() + "\n"); |
| fw.write("Body size : " + req.getContentLength() + "\n"); |
| |
| fw.write("#===== HTTP Headers =====#" + "\n"); |
| outputHeaders(fw, req); |
| |
| fw.write("#===== HTTP Body =====#" + "\n"); |
| outputBody(fw, req); |
| |
| fw.close(); |
| } catch (IOException ex) { |
| if (fw != null) { |
| try { |
| fw.close(); |
| } catch (IOException e) { /* ignore */ } |
| } |
| System.out.println("Unable to write HTTP request data to file " + filename + ": " + ex.toString()); |
| } |
| } |
| |
| /** |
| * Output 1 line message (Auto file open). |
| * |
| * @param message the message to print |
| */ |
| public static void outputPrint(String message) { |
| FileWriter fw = null; |
| try { |
| fw = new FileWriter(filename, true); |
| fw.write(message + "\n"); |
| fw.close(); |
| } catch (IOException ex) { |
| if (fw != null) { |
| try { |
| fw.close(); |
| } catch (IOException e) { /* ignore */ } |
| } |
| System.out.println("Unable to log message '" + message + "' to file " + filename + " : " + ex.toString()); |
| } |
| } |
| |
| |
| /** |
| * Display the request header. |
| */ |
| private static void outputHeaders(FileWriter fw, LoggingHttpServletRequestWrapper req) throws IOException { |
| // Get the header |
| Enumeration reqHeaderNum = req.getHeaderNames(); |
| |
| // Do nothing if there is no header |
| if (reqHeaderNum == null) { |
| fw.write("No headers" + "\n"); |
| return; |
| } |
| |
| // Repeat the header element |
| while (reqHeaderNum.hasMoreElements()) { |
| // Get the key |
| String key = (String) reqHeaderNum.nextElement(); |
| |
| // Output the header information |
| outputHeaderElements(fw, req, key); |
| } |
| } |
| |
| /** |
| * Output header information. |
| */ |
| private static void outputHeaderElements(FileWriter fw, LoggingHttpServletRequestWrapper req, String key) throws IOException { |
| // Output the header information |
| Enumeration e = req.getHeaders(key); |
| String keyname = key; |
| |
| while (e.hasMoreElements()) { |
| fw.write(keyname + " : " + e.nextElement() + "\n"); |
| // Output key name only for the first time |
| keyname = " "; |
| } |
| } |
| |
| /** |
| * Output the body information. |
| */ |
| private static void outputBody(FileWriter fw, LoggingHttpServletRequestWrapper req) throws IOException { |
| // Get the body size |
| int leng = req.getContentLength(); |
| // Do nothing if there is no body |
| if (leng <= 0) return; |
| |
| // Buffer to read |
| byte rbuf[] = new byte[leng]; |
| |
| // Put data |
| InputStream in = req.getInputStream(); |
| if (in.read(rbuf, 0, leng) > 0) { |
| // Output data |
| outputBinary(fw, rbuf); |
| } |
| } |
| |
| /** |
| * Output body information. |
| */ |
| private static void outputBinary(FileWriter fw, byte buf[]) throws IOException { |
| |
| int adrs = 0; |
| |
| // Do every 16 bytes |
| for (int j = 0; j < buf.length; j += 16) { |
| |
| // Change the number to hex. |
| String adrsStr = "00000000" + Integer.toHexString(adrs); |
| adrsStr = adrsStr.substring(adrsStr.length() - 8, adrsStr.length()); |
| fw.write("\n" + adrsStr + " : "); |
| // Add address by 16 |
| adrs += 16; |
| |
| // Output in hex. |
| for (int i = 0; i < 16; i++) { |
| |
| // If it is out of the limit, display in white space |
| if (i + j >= buf.length) { |
| fw.write(" "); |
| } else { |
| int n = (int) buf[i + j]; |
| if (n < 0) n += 256; |
| // Change the data into hex |
| String s = "00" + Integer.toHexString(n); |
| s = s.substring(s.length() - 2, s.length()); |
| fw.write(s + " "); |
| } |
| } |
| |
| // Output in string |
| fw.write(" "); |
| for (int i = 0; i < 16; i++) { |
| |
| // If it is out of limit, break. |
| if (i + j >= buf.length) break; |
| |
| // If it is a special character, output "." |
| if (buf[i + j] < 0x20 || |
| (buf[i + j] & 0xff) > 0xde || |
| (buf[i + j] > 0x7e && (buf[i + j] & 0xff) < 0xa1)) { |
| fw.write("."); |
| } |
| // Output string |
| else { |
| String s = String.valueOf((char) buf[i + j]); |
| fw.write(s); |
| } |
| } |
| } |
| fw.write("\n"); |
| } |
| } |