use of com.azure.android.core.http.HttpHeaders in project azure-sdk-for-android by Azure.
the class PlaybackClient method playbackHttpResponse.
private HttpResponse playbackHttpResponse(final HttpRequest request) {
final String incomingUrl = applyReplacementRule(request.getUrl().toString());
final String incomingMethod = request.getHttpMethod().toString();
final String matchingUrl = removeHost(incomingUrl);
NetworkCallRecord networkCallRecord = recordedData.findFirstAndRemoveNetworkCall(record -> record.getMethod().equalsIgnoreCase(incomingMethod) && removeHost(record.getUri()).equalsIgnoreCase(matchingUrl));
count.incrementAndGet();
if (networkCallRecord == null) {
logger.warning("NOT FOUND - Method: {} URL: {}", incomingMethod, incomingUrl);
logger.warning("Records requested: {}.", count);
throw new IllegalStateException("==> Unexpected request: " + incomingMethod + " " + incomingUrl);
}
if (networkCallRecord.getException() != null) {
throw logger.logExceptionAsWarning(new RuntimeException(networkCallRecord.getException().get()));
}
// Overwrite the request header if any.
if (networkCallRecord.getHeaders().containsKey(X_MS_CLIENT_REQUEST_ID)) {
request.setHeader(X_MS_CLIENT_REQUEST_ID, networkCallRecord.getHeaders().get(X_MS_CLIENT_REQUEST_ID));
}
if (request.getHeaders().getValue(X_MS_ENCRYPTION_KEY_SHA256) != null) {
networkCallRecord.getResponse().put(X_MS_ENCRYPTION_KEY_SHA256, request.getHeaders().getValue(X_MS_ENCRYPTION_KEY_SHA256));
}
int recordStatusCode = Integer.parseInt(networkCallRecord.getResponse().get("StatusCode"));
HttpHeaders headers = new HttpHeaders();
for (Map.Entry<String, String> pair : networkCallRecord.getResponse().entrySet()) {
if (!pair.getKey().equals("StatusCode") && !pair.getKey().equals("Body")) {
String rawHeader = pair.getValue();
for (Map.Entry<String, String> rule : textReplacementRules.entrySet()) {
if (rule.getValue() != null) {
rawHeader = rawHeader.replaceAll(rule.getKey(), rule.getValue());
}
}
headers.put(pair.getKey(), rawHeader);
}
}
String rawBody = networkCallRecord.getResponse().get("Body");
byte[] bytes = null;
if (rawBody != null) {
for (Map.Entry<String, String> rule : textReplacementRules.entrySet()) {
if (rule.getValue() != null) {
rawBody = rawBody.replaceAll(rule.getKey(), rule.getValue());
}
}
String contentType = networkCallRecord.getResponse().get("Content-Type");
/*
* The Body Content-Type is application/octet-stream or avro/binary, those use a custom format to be written
* to disk. In older versions of azure-core-test this used Arrays.toString(), bodies saved using this format
* will begin with '[' and end with ']'. The new format for persisting these Content-Types is Base64
* encoding. Base64 encoding is more compact as Arrays.toString() will separate each byte with ', ', adding
* (2 * byte[].length) - 1 additional characters, additionally each byte on average takes 2-3 characters to
* be written to disk [-128,127). Base64 encoding only takes about 4 characters per 3 bytes, this results
* in a drastically smaller size on disk. In addition to a smaller size on disk, loading the body when it
* is Base64 encoded is much faster as it doesn't require string splitting.
*/
if (contentType != null && (contentType.equalsIgnoreCase("application/octet-stream") || contentType.equalsIgnoreCase("avro/binary"))) {
if (rawBody.startsWith("[") && rawBody.endsWith("]")) {
/*
* Body is encoded using the old Arrays.toString() format. Remove the leading '[' and trailing ']'
* and split the string into individual bytes using ', '.
*/
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
for (String piece : rawBody.substring(1, rawBody.length() - 1).split(", ")) {
outputStream.write(Byte.parseByte(piece));
}
bytes = outputStream.toByteArray();
} else {
/*
* Body is encoded using the Base64 encoded format, simply Base64 decode it.
*/
bytes = Base64.getDecoder().decode(rawBody);
}
} else {
bytes = rawBody.getBytes(StandardCharsets.UTF_8);
}
if (bytes.length > 0) {
headers.put("Content-Length", String.valueOf(bytes.length));
}
}
return new MockHttpResponse(request, recordStatusCode, headers, bytes);
}
use of com.azure.android.core.http.HttpHeaders in project azure-sdk-for-android by Azure.
the class SerdeEncodingTests method recognizeJson.
@ParameterizedTest
@ValueSource(strings = { "application/json", "application/kv+json", "APPLICATION/JSON", "application/FOO+JSON", "application/json;charset=utf-8", "application/config+json; charset=utf-32" })
void recognizeJson(String mimeType) {
// Arrange
HttpHeaders headers = new HttpHeaders(Collections.singletonMap(CONTENT_TYPE, mimeType));
// Act & Assert
Assertions.assertEquals(SerdeEncoding.JSON, SerdeEncoding.fromHeaders(headers.toMap()));
}
use of com.azure.android.core.http.HttpHeaders in project azure-sdk-for-android by Azure.
the class SerdeEncodingTests method defaultNoContentType.
@Test
void defaultNoContentType() {
// Arrange
HttpHeaders headers = new HttpHeaders(Collections.singletonMap("Http-Method", "GET"));
// Act & Assert
Assertions.assertEquals(SerdeEncoding.JSON, SerdeEncoding.fromHeaders(headers.toMap()));
}
use of com.azure.android.core.http.HttpHeaders in project azure-sdk-for-android by Azure.
the class SerdeEncodingTests method defaultUnsupportedType.
@ParameterizedTest
@ValueSource(strings = { "application/binary", "invalid-mime-type" })
void defaultUnsupportedType(String mimeType) {
// Arrange
HttpHeaders headers = new HttpHeaders(Collections.singletonMap(CONTENT_TYPE, mimeType));
// Act & Assert
Assertions.assertEquals(SerdeEncoding.JSON, SerdeEncoding.fromHeaders(headers.toMap()));
}
use of com.azure.android.core.http.HttpHeaders in project azure-sdk-for-android by Azure.
the class RetryPolicyTests method retryConsumesBody.
@Test
public void retryConsumesBody() {
final AtomicInteger bodyConsumptionCount = new AtomicInteger();
final InputStream errorBody = new ByteArrayInputStream("Should be consumed".getBytes(StandardCharsets.UTF_8)) {
@Override
public void close() throws IOException {
bodyConsumptionCount.incrementAndGet();
super.close();
}
};
final HttpPipeline pipeline = new HttpPipelineBuilder().policies(new RetryPolicy(new FixedDelay(2, Duration.ofMillis(1)))).httpClient(new NoOpHttpClient() {
@Override
public void send(HttpRequest httpRequest, CancellationToken cancellationToken, HttpCallback httpCallback) {
httpCallback.onSuccess(new HttpResponse(httpRequest) {
@Override
public int getStatusCode() {
return 503;
}
@Override
public String getHeaderValue(String name) {
return getHeaders().getValue(name);
}
@Override
public HttpHeaders getHeaders() {
return new HttpHeaders();
}
@Override
public InputStream getBody() {
return errorBody;
}
@Override
public byte[] getBodyAsByteArray() {
return collectBytesInInputStream(getBody());
}
@Override
public String getBodyAsString() {
return getBodyAsString(StandardCharsets.UTF_8);
}
@Override
public String getBodyAsString(Charset charset) {
return new String(getBodyAsByteArray(), charset);
}
@Override
public void close() {
try {
errorBody.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
}).build();
CountDownLatch latch = new CountDownLatch(1);
pipeline.send(new HttpRequest(HttpMethod.GET, "https://example.com"), RequestContext.NONE, CancellationToken.NONE, new HttpCallback() {
@Override
public void onSuccess(HttpResponse response) {
latch.countDown();
}
@Override
public void onError(Throwable error) {
latch.countDown();
}
});
awaitOnLatch(latch, "retryConsumesBody");
assertEquals(2, bodyConsumptionCount.get());
}
Aggregations