/*
* Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
* See LICENSE in the project root for license information.
*/
package com.linkedin.flashback.matchrules;
import com.linkedin.flashback.http.HttpUtilities;
import com.linkedin.flashback.serializable.RecordedEncodedHttpBody;
import com.linkedin.flashback.serializable.RecordedHttpBody;
import com.linkedin.flashback.serializable.RecordedHttpRequest;
import com.linkedin.flashback.serializable.RecordedStringHttpBody;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.apache.log4j.Logger;
/**
* Match the form-urlencoded POST parameters in the request body
* @author dvinegra
*/
public class MatchBodyPostParameters extends MatchBody {
private static final Logger logger = Logger.getLogger("MatchBodyPostParameters");
private final MatchRuleMapTransform _transform;
public MatchBodyPostParameters() {
this(null);
}
public MatchBodyPostParameters(MatchRuleMapTransform transform) {
if (transform != null) {
_transform = transform;
} else {
_transform = new MatchRuleIdentityTransform();
}
}
@Override
public boolean test(RecordedHttpRequest incomingRequest, RecordedHttpRequest expectedRequest) {
if (HttpUtilities.isFormURLEncodedContentType(incomingRequest.getContentType()) && HttpUtilities
.isFormURLEncodedContentType(expectedRequest.getContentType())) {
try {
Map<String, String> incomingParams = getPostParametersFromRequest(incomingRequest);
Map<String, String> expectedParams = getPostParametersFromRequest(expectedRequest);
return testParameterEquivalency(incomingParams, expectedParams);
} catch (UnsupportedEncodingException e) {
logger.error("Caught exception " + e + " while decoding POST parameters");
}
}
return super.test(incomingRequest, expectedRequest);
}
private Map<String, String> getPostParametersFromRequest(RecordedHttpRequest request)
throws UnsupportedEncodingException {
RecordedHttpBody body = request.getHttpBody();
if (body instanceof RecordedEncodedHttpBody) {
body = ((RecordedEncodedHttpBody) body).getDecodedBody();
}
assert (body instanceof RecordedStringHttpBody);
String content = ((RecordedStringHttpBody) body).getContent();
return HttpUtilities.stringToUrlParams(content, request.getCharset());
}
/**
* Tests whether the maps have the same key/value pairs in the same order
*/
private boolean testParameterEquivalency(Map<String, String> incomingParams, Map<String, String> expectedParams) {
return _transform.transform(incomingParams).toString().equals(_transform.transform(expectedParams).toString());
}
@Override
public String getMatchFailureDescriptionForRequests(RecordedHttpRequest incomingRequest, RecordedHttpRequest expectedRequest) {
StringBuilder resultBuilder = new StringBuilder("HTTP Body Parameters Mismatch");
if (_transform instanceof MatchRuleBlacklistTransform) {
resultBuilder.append(" (with Blacklist)");
} else if (_transform instanceof MatchRuleWhitelistTransform) {
resultBuilder.append(" (with Whitelist)");
}
try {
Map<String, String> incomingParams = getPostParametersFromRequest(incomingRequest);
Map<String, String> expectedParams = getPostParametersFromRequest(expectedRequest);
resultBuilder.append("%n")
.append(String.format("Incoming Parameters: %s%n", _transform.transform(incomingParams)))
.append(String.format("Expected Parameters: %s%n", _transform.transform(expectedParams)));
} catch (UnsupportedEncodingException e) {
logger.error("Caught exception " + e + " while decoding POST parameters");
}
return resultBuilder.toString();
}
}