package com.philemonworks.critter.action;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.philemonworks.critter.Recording;
import com.philemonworks.critter.rule.RuleContext;
import com.philemonworks.critter.ui.fixed.RecordingInput;
public class Record implements Action {
private static final Logger LOG = LoggerFactory.getLogger(Record.class);
@Override
public String explain() {
return "record the request (+ response)";
}
@Override
public void perform(RuleContext context) {
Recording record = new Recording();
// TODO cleanup this
record.host = context.httpContext.getRequest().getHeaderValue("Host");
record.method = context.httpContext.getRequest().getMethod();
record.path = context.forwardURI.getPath();
record.query = context.forwardURI.getQuery();
RecordingInput tester = new RecordingInput();
this.copyRequestContents(context, record, tester);
this.copyResponseData(context, record, tester);
try {
context.recordingDao.save(record);
} catch (Exception ex) {
LOG.error("Unable to save recording", ex);
}
}
private void copyRequestContents(RuleContext context, Recording record, RecordingInput tester) {
tester.contenttype = context.httpContext.getRequest().getHeaderValue("Content-Type");
record.requestReceivedDate = context.requestReceivedDate;
if (tester.hasTextualRequestContent()) {
record.requestContent = context.httpContext.getRequest().getEntity(String.class);
}
for (Entry<String, List<String>> each : context.httpContext.getRequest().getRequestHeaders().entrySet()) {
copyRequestHeader(record, each);
}
}
private void copyResponseData(RuleContext context, Recording record, RecordingInput tester) {
// see if a response is available
if (context.forwardResponse == null) {
return;
}
tester.responsecontenttype = (String) context.forwardResponse.getMetadata().getFirst("Content-Type");
if (tester.hasTextualResponseContent()) {
Object e = context.forwardResponse.getEntity();
if (e instanceof InputStream) {
record.responseContent = this.readStringContents((InputStream) e);
}
if (e instanceof String) {
record.responseContent = (String) e;
}
}
for (Entry<String, List<Object>> each : context.forwardResponse.getMetadata().entrySet()) {
copyResponseHeader(record, each);
}
}
private void copyResponseHeader(Recording record, Entry<String, List<Object>> each) {
try {
record.responseHeaders.put(each.getKey(), (String) each.getValue().get(0));
} catch (Exception ex) {
LOG.error("Unable to copy response header", ex);
}
}
private void copyRequestHeader(Recording record, Entry<String, List<String>> each) {
try {
record.requestHeaders.put(each.getKey(), each.getValue().get(0));
} catch (Exception ex) {
LOG.error("Unable to copy request header", ex);
}
}
private String readStringContents(InputStream is) {
try {
BufferedReader buf = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder(1024);
while (buf.ready()) {
sb.append(buf.readLine()).append("\n");
}
return sb.toString();
} catch (Exception ex) {
LOG.error("Unable to read string contents", ex);
}
return "";
}
}