// Copyright 2012 Georg-August-Universität Göttingen, Germany
//
// 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 de.ugoe.cs.autoquest.httpmonitor.proxy;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import de.ugoe.cs.autoquest.httpmonitor.HttpMonitorExchangeHandler;
import de.ugoe.cs.autoquest.httpmonitor.exchange.Address;
import de.ugoe.cs.autoquest.httpmonitor.exchange.Content;
import de.ugoe.cs.autoquest.httpmonitor.exchange.Cookie;
import de.ugoe.cs.autoquest.httpmonitor.exchange.Cookies;
import de.ugoe.cs.autoquest.httpmonitor.exchange.Header;
import de.ugoe.cs.autoquest.httpmonitor.exchange.Headers;
import de.ugoe.cs.autoquest.httpmonitor.exchange.HttpExchange;
import de.ugoe.cs.autoquest.httpmonitor.exchange.HttpRequest;
import de.ugoe.cs.autoquest.httpmonitor.exchange.HttpResponse;
import de.ugoe.cs.autoquest.httpmonitor.exchange.Method;
import de.ugoe.cs.autoquest.httpmonitor.exchange.ObjectFactory;
import de.ugoe.cs.autoquest.httpmonitor.exchange.Protocol;
import de.ugoe.cs.autoquest.httpmonitor.exchange.Status;
import de.ugoe.cs.util.console.Console;
/**
*
* TODO comment
*
*
* @author Patrick Harms
*/
class ExchangeListener {
/**
*
*/
private HttpMonitorExchangeHandler exchangeHandler;
/**
*
*/
private HttpServletRequest request;
/**
*
*/
private List requestData = new LinkedList();
/**
*
*/
private HttpServletResponse response;
/**
*
*/
private List responseData = new LinkedList();
/**
*
*/
private long lastUpdate = System.currentTimeMillis();
/**
*
*/
ExchangeListener(HttpMonitorExchangeHandler exchangeHandler) {
this.exchangeHandler = exchangeHandler;
}
/**
*
*/
public void onRequest(HttpServletRequest request) throws IllegalStateException {
Console.traceln(Level.FINEST, this + ": onRequest " + request);
if (request == null) {
throw new IllegalArgumentException("request must not be null");
}
lastUpdate = System.currentTimeMillis();
this.request = request;
}
/**
*
*/
public void onRequestContent(ByteBuffer data) {
Console.traceln(Level.FINEST, this + ": onRequestContent " + data);
if (data == null) {
throw new IllegalArgumentException("data must not be null");
}
lastUpdate = System.currentTimeMillis();
requestData.add(data);
}
/**
*
*/
public void onResponse(HttpServletResponse response) {
Console.traceln(Level.FINEST, this + ": onResponse " + response);
if (response == null) {
throw new IllegalArgumentException("response must not be null");
}
lastUpdate = System.currentTimeMillis();
this.response = response;
}
/**
*
*/
public void onResponseContent(ByteBuffer data) {
Console.traceln(Level.FINEST, this + ": onResponseContent " + data);
if (data == null) {
throw new IllegalArgumentException("data must not be null");
}
lastUpdate = System.currentTimeMillis();
responseData.add(data);
}
/**
*
*/
public void onFinish(Status status) {
Console.traceln(Level.FINEST, this + ": onFinish " + status);
if (status == null) {
throw new IllegalArgumentException("status must not be null");
}
lastUpdate = System.currentTimeMillis();
sendToExchangeHandler(status);
}
/**
* @return the request
*/
HttpServletRequest getRequest() {
return request;
}
/**
*
*/
long getLastUpdate() {
return lastUpdate;
}
/**
*
*/
private void sendToExchangeHandler(Status status) {
ObjectFactory eventObjectFactory = new ObjectFactory();
HttpExchange exchange = eventObjectFactory.createHttpExchange();
exchange.setStatus(status);
// the remote address
Address address = eventObjectFactory.createAddress();
address.setIp(request.getRemoteAddr());
address.setHost(request.getRemoteHost());
address.setPort(BigInteger.valueOf(request.getRemotePort()));
exchange.setSender(address);
// the local address
address = eventObjectFactory.createAddress();
address.setIp(request.getLocalAddr());
address.setHost(request.getLocalName());
address.setPort(BigInteger.valueOf(request.getLocalPort()));
exchange.setReceiver(address);
exchange.setRequest(map(request, eventObjectFactory));
exchange.setResponse(map(response, eventObjectFactory));
exchangeHandler.handleHttpExchange(exchange);
}
/**
*
*/
private HttpRequest map(HttpServletRequest request, ObjectFactory eventObjectFactory) {
HttpRequest eventRequest = eventObjectFactory.createHttpRequest();
eventRequest.setMethod(Method.fromValue(request.getMethod()));
eventRequest.setProtocol(Protocol.fromValue(request.getProtocol()));
eventRequest.setUrl(request.getRequestURL().toString());
eventRequest.setQuery(request.getQueryString());
Headers headers = eventObjectFactory.createHeaders();
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
Enumeration headerValues = request.getHeaders(headerName);
while (headerValues.hasMoreElements()) {
Header header = eventObjectFactory.createHeader();
header.setKey(headerName);
header.setValue(headerValues.nextElement());
headers.getHeader().add(header);
}
}
eventRequest.setHeaders(headers);
if (request.getCookies() != null) {
Cookies cookies = eventObjectFactory.createCookies();
for (javax.servlet.http.Cookie requestCookie : request.getCookies()) {
Cookie cookie = eventObjectFactory.createCookie();
cookie.setComment(requestCookie.getComment());
cookie.setDomain(requestCookie.getDomain());
cookie.setIsHttpOnly(requestCookie.isHttpOnly());
cookie.setIsSecure(requestCookie.getSecure());
cookie.setMaxAge(BigInteger.valueOf(requestCookie.getMaxAge()));
cookie.setName(requestCookie.getName());
cookie.setPath(requestCookie.getPath());
cookie.setValue(requestCookie.getValue());
cookie.setVersion(BigInteger.valueOf(requestCookie.getVersion()));
cookies.getCookie().add(cookie);
}
eventRequest.setCookies(cookies);
}
eventRequest.setAuthType(request.getAuthType());
eventRequest.setRemoteUser(request.getRemoteUser());
eventRequest.setRequestedSessionId(request.getRequestedSessionId());
if (requestData.size() > 0) {
Content content = eventObjectFactory.createContent();
content.setEncoding(request.getCharacterEncoding());
content.setType(request.getContentType());
content.setLength(request.getContentLength());
content.setData(createString(requestData));
eventRequest.setContent(content);
}
return eventRequest;
}
/**
*
*/
private HttpResponse map(HttpServletResponse response, ObjectFactory eventObjectFactory) {
HttpResponse eventResponse = eventObjectFactory.createHttpResponse();
eventResponse.setStatus(BigInteger.valueOf(response.getStatus()));
Headers headers = eventObjectFactory.createHeaders();
Collection headerNames = response.getHeaderNames();
for (String headerName : headerNames) {
Collection headerValues = response.getHeaders(headerName);
for (String headerValue : headerValues) {
Header header = eventObjectFactory.createHeader();
header.setKey(headerName);
header.setValue(headerValue);
headers.getHeader().add(header);
}
}
eventResponse.setHeaders(headers);
if (responseData.size() > 0) {
Content content = eventObjectFactory.createContent();
content.setEncoding(response.getCharacterEncoding());
content.setType(response.getContentType());
String data = createString(responseData);
content.setLength(data.length());
content.setData(data);
eventResponse.setContent(content);
}
return eventResponse;
}
/**
*
*/
private String createString(List bufferList) {
StringBuffer str = new StringBuffer();
for (ByteBuffer buffer : bufferList) {
while (buffer.hasRemaining()) {
str.append((char) buffer.get());
}
}
return str.toString();
}
}