// 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(); } }