All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.foreach.across.modules.logging.requestresponse.RequestResponseLogEntry Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014 the original author or authors
 *
 * Licensed 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 com.foreach.across.modules.logging.requestresponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.yaml.snakeyaml.Yaml;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.regex.Pattern;

public class RequestResponseLogEntry
{
	private static final String ILLEGAL_PARAMETER_PATTERN = ".*password.*";

	private final UUID id;
	private final long started, finished;

	private String requestData, responseData, requestPayloadSize, responsePayloadSize;
	private boolean requestDataTruncated, responseDataTruncated;

	private int responseStatus;
	private String sessionId, responseContentType, contentType, url, uri, callerInfo, requestMethod, remoteIp,
			responseCharacterEncoding;

	private Map requestCookies = new TreeMap<>();
	private Map requestHeaders = new TreeMap<>();
	private Map responseHeaders = new TreeMap<>();
	private Map requestParameters = new TreeMap<>();

	public RequestResponseLogEntry( long started,
	                                long finished,
	                                LogRequestWrapper request,
	                                LogResponseWrapper response ) {
		id = UUID.randomUUID();

		this.started = started;
		this.finished = finished;

		buildRequestInfo( request );
		buildResponseInfo( response );
	}

	private void buildRequestInfo( LogRequestWrapper request ) {
		url = request.getRequestURL().toString();
		uri = request.getRequestURI();

		if ( !StringUtils.isBlank( request.getQueryString() ) ) {
			url += "?" + request.getQueryString();
		}

		requestMethod = request.getMethod();
		contentType = request.getContentType();

		Enumeration headerNames = request.getHeaderNames();

		while ( headerNames.hasMoreElements() ) {
			String headerName = headerNames.nextElement();
			requestHeaders.put( headerName, request.getHeader( headerName ) );

		}

		callerInfo = String.format( "%s @ %s:%s", StringUtils.defaultString( request.getRemoteUser(), "unknown" ),
		                            request.getRemoteAddr(),
		                            request.getRemotePort() );
		remoteIp = request.getRemoteAddr();

		Cookie[] cookies = request.getCookies();

		if ( cookies != null ) {
			for ( Cookie cookie : request.getCookies() ) {
				requestCookies.put( cookie.getName(), cookie.getValue() );
			}
			requestHeaders.remove( "cookie" );
		}

		HttpSession session = request.getSession( false );

		if ( session != null ) {
			sessionId = session.getId();
		}

		if ( !isMultipart( request ) ) {
			if ( request.payloadSize() > 1024 * 512 ) {
				requestData = "Request data is too big: " + request.payloadSize() + " bytes";
			}
			else {
				try {
					String charEncoding =
							request.getCharacterEncoding() != null ? request.getCharacterEncoding() :
									"UTF-8";
					requestData = new String( request.toByteArray(), charEncoding );
				}
				catch ( UnsupportedEncodingException usee ) {
					requestData = "Unable to parse request payload.";
				}
			}
		}
		else {
			requestData = "Request payload is multipart data.";
		}

		request.getParameterMap()
		       .forEach( ( key, value ) -> {
			       if ( Pattern.matches( ILLEGAL_PARAMETER_PATTERN, StringUtils.lowerCase( key ) ) ) {
				       requestParameters.put( key, new String[] { "*" } );
			       }
			       else {
				       requestParameters.put( key, value );
			       }
		       } );

		requestDataTruncated = request.isMaximumReached();
		requestPayloadSize = FileUtils.byteCountToDisplaySize( request.payloadSize() );
		if ( StringUtils.isEmpty( requestData ) ) {
			requestData = "no request payload";
		}
	}

	private boolean isMultipart( HttpServletRequest request ) {
		return request.getContentType() != null && request.getContentType().startsWith( "multipart/form-data" );
	}

	private void buildResponseInfo( LogResponseWrapper response ) {
		responseStatus = response.getStatus();
		responseContentType = response.getContentType();
		responseCharacterEncoding = response.getCharacterEncoding();

		for ( String headerName : response.getHeaderNames() ) {
			responseHeaders.put( headerName, response.getHeader( headerName ) );
		}

		if ( response.payloadSize() > 1024 * 512 ) {
			responseData = "Response data is too big: " + response.payloadSize() + " bytes";
		}
		else {
			try {
				String charEncoding =
						response.getCharacterEncoding() != null ? response.getCharacterEncoding() : "UTF-8";
				responseData = new String( response.toByteArray(), charEncoding );
			}
			catch ( UnsupportedEncodingException usee ) {
				responseData = "Unable to parse response payload.";
			}
		}

		responseDataTruncated = response.isMaximumReached();
		responsePayloadSize = FileUtils.byteCountToDisplaySize( response.payloadSize() );
		if ( StringUtils.isEmpty( responseData ) ) {
			responseData = "no response payload";
		}
	}

	public String getRequestMethod() {
		return requestMethod;
	}

	public String getSessionId() {
		return sessionId;
	}

	public String getContentType() {
		return contentType;
	}

	public String getUrl() {
		return url;
	}

	public String getCallerInfo() {
		return callerInfo;
	}

	public Map getRequestHeaders() {
		return requestHeaders;
	}

	public Map getRequestCookies() {
		return requestCookies;
	}

	public int getResponseStatus() {
		return responseStatus;
	}

	public String getResponseContentType() {
		return responseContentType;
	}

	public String getUri() {
		return uri;
	}

	public String getRemoteIp() {
		return remoteIp;
	}

	public String getResponseCharacterEncoding() {
		return responseCharacterEncoding;
	}

	public Map getResponseHeaders() {
		return responseHeaders;
	}

	public Map getRequestParameters() {
		return requestParameters;
	}

	public String getRequestInfo() {
		Map data = new LinkedHashMap<>();
		data.put( "url", getUrl() );
		data.put( "method", getRequestMethod() );
		if ( getContentType() != null ) {
			data.put( "contentType", getContentType() );
		}
		if ( getSessionId() != null ) {
			data.put( "sessionId", getSessionId() );
		}
		data.put( "remote", getCallerInfo() );
		data.put( "headers", getRequestHeaders() );
		data.put( "cookies", getRequestCookies() );

		Yaml yaml = new Yaml();
		return yaml.dump( data );
	}

	public UUID getId() {
		return id;
	}

	public String getRequestData() {
		return requestData;
	}

	public String getResponseData() {
		return responseData;
	}

	public Date getStarted() {
		return new Date( started );
	}

	public Date getFinished() {
		return new Date( finished );
	}

	public long getDuration() {
		return finished - started;
	}

	public boolean isRequestDataTruncated() {
		return requestDataTruncated;
	}

	public boolean isResponseDataTruncated() {
		return responseDataTruncated;
	}

	public String getRequestPayloadSize() {
		return requestPayloadSize;
	}

	public String getResponsePayloadSize() {
		return responsePayloadSize;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy