package com.getsentry.raven.marshaller.json;
import com.fasterxml.jackson.core.JsonGenerator;
import com.getsentry.raven.event.interfaces.HttpInterface;
import com.getsentry.raven.util.Util;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
/**
* Binding system allowing to convert an {@link HttpInterface} into a JSON stream.
*/
public class HttpInterfaceBinding implements InterfaceBinding<HttpInterface> {
/**
* Maximum length for the HTTP request body.
*
* See <a href="https://docs.sentry.io/clientdev/data-handling/#variable-size">the SDK reference</a>
* for more information.
*/
public static final int MAX_BODY_LENGTH = 2048;
private static final String URL = "url";
private static final String METHOD = "method";
private static final String DATA = "data";
private static final String BODY = "body";
private static final String QUERY_STRING = "query_string";
private static final String COOKIES = "cookies";
private static final String HEADERS = "headers";
private static final String ENVIRONMENT = "env";
private static final String ENV_REMOTE_ADDR = "REMOTE_ADDR";
private static final String ENV_SERVER_NAME = "SERVER_NAME";
private static final String ENV_SERVER_PORT = "SERVER_PORT";
private static final String ENV_LOCAL_ADDR = "LOCAL_ADDR";
private static final String ENV_LOCAL_NAME = "LOCAL_NAME";
private static final String ENV_LOCAL_PORT = "LOCAL_PORT";
private static final String ENV_SERVER_PROTOCOL = "SERVER_PROTOCOL";
private static final String ENV_REQUEST_SECURE = "REQUEST_SECURE";
private static final String ENV_REQUEST_ASYNC = "REQUEST_ASYNC";
private static final String ENV_AUTH_TYPE = "AUTH_TYPE";
private static final String ENV_REMOTE_USER = "REMOTE_USER";
@Override
public void writeInterface(JsonGenerator generator, HttpInterface httpInterface) throws IOException {
generator.writeStartObject();
generator.writeStringField(URL, httpInterface.getRequestUrl());
generator.writeStringField(METHOD, httpInterface.getMethod());
generator.writeFieldName(DATA);
writeData(generator, httpInterface.getParameters(), httpInterface.getBody());
generator.writeStringField(QUERY_STRING, httpInterface.getQueryString());
generator.writeFieldName(COOKIES);
writeCookies(generator, httpInterface.getCookies());
generator.writeFieldName(HEADERS);
writeHeaders(generator, httpInterface.getHeaders());
generator.writeFieldName(ENVIRONMENT);
writeEnvironment(generator, httpInterface);
generator.writeEndObject();
}
private void writeEnvironment(JsonGenerator generator, HttpInterface httpInterface) throws IOException {
generator.writeStartObject();
generator.writeStringField(ENV_REMOTE_ADDR, httpInterface.getRemoteAddr());
generator.writeStringField(ENV_SERVER_NAME, httpInterface.getServerName());
generator.writeNumberField(ENV_SERVER_PORT, httpInterface.getServerPort());
generator.writeStringField(ENV_LOCAL_ADDR, httpInterface.getLocalAddr());
generator.writeStringField(ENV_LOCAL_NAME, httpInterface.getLocalName());
generator.writeNumberField(ENV_LOCAL_PORT, httpInterface.getLocalPort());
generator.writeStringField(ENV_SERVER_PROTOCOL, httpInterface.getProtocol());
generator.writeBooleanField(ENV_REQUEST_SECURE, httpInterface.isSecure());
generator.writeBooleanField(ENV_REQUEST_ASYNC, httpInterface.isAsyncStarted());
generator.writeStringField(ENV_AUTH_TYPE, httpInterface.getAuthType());
//TODO: Should that be really displayed here ? Consider the user interface?
generator.writeStringField(ENV_REMOTE_USER, httpInterface.getRemoteUser());
generator.writeEndObject();
}
private void writeHeaders(JsonGenerator generator, Map<String, Collection<String>> headers) throws IOException {
generator.writeStartArray();
for (Map.Entry<String, Collection<String>> headerEntry : headers.entrySet()) {
for (String value : headerEntry.getValue()) {
generator.writeStartArray();
generator.writeString(headerEntry.getKey());
generator.writeString(value);
generator.writeEndArray();
}
}
generator.writeEndArray();
}
private void writeCookies(JsonGenerator generator, Map<String, String> cookies) throws IOException {
//TODO: Cookies shouldn't be sent by default
if (cookies.isEmpty()) {
generator.writeNull();
return;
}
generator.writeStartObject();
for (Map.Entry<String, String> cookie : cookies.entrySet()) {
generator.writeStringField(cookie.getKey(), cookie.getValue());
}
generator.writeEndObject();
}
private void writeData(JsonGenerator generator,
Map<String, Collection<String>> parameterMap,
String body) throws IOException {
if (parameterMap == null && body == null) {
generator.writeNull();
return;
}
generator.writeStartObject();
if (body != null) {
generator.writeStringField(BODY, Util.trimString(body, MAX_BODY_LENGTH));
}
if (parameterMap != null) {
for (Map.Entry<String, Collection<String>> parameter : parameterMap.entrySet()) {
generator.writeArrayFieldStart(parameter.getKey());
for (String parameterValue : parameter.getValue()) {
generator.writeString(parameterValue);
}
generator.writeEndArray();
}
}
generator.writeEndObject();
}
}