blob: 8aba6b05d3ea8fdfddead84312f8e5c0b13fd62a [file] [log] [blame]
/*
* 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");
}
}