com.azure.core.http.HttpResponse Maven / Gradle / Ivy
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.core.http;
import com.azure.core.implementation.http.BufferedHttpResponse;
import com.azure.core.implementation.util.BinaryDataHelper;
import com.azure.core.implementation.util.FluxByteBufferContent;
import com.azure.core.util.BinaryData;
import com.azure.core.util.FluxUtil;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.util.Objects;
/**
* The response of an {@link HttpRequest}.
*/
public abstract class HttpResponse implements Closeable {
private final HttpRequest request;
/**
* Creates an instance of {@link HttpResponse}.
*
* @param request The {@link HttpRequest} that resulted in this {@link HttpResponse}.
*/
protected HttpResponse(HttpRequest request) {
this.request = request;
}
/**
* Get the response status code.
*
* @return The response status code
*/
public abstract int getStatusCode();
/**
* Lookup a response header with the provided name.
*
* @param name the name of the header to lookup.
* @return the value of the header, or null if the header doesn't exist in the response.
* @deprecated Use {@link #getHeaderValue(HttpHeaderName)} as it provides better performance.
*/
@Deprecated
public abstract String getHeaderValue(String name);
/**
* Lookup a response header with the provider {@link HttpHeaderName}.
*
* @param headerName the name of the header to lookup.
* @return the value of the header, or null if the header doesn't exist in the response.
*/
public String getHeaderValue(HttpHeaderName headerName) {
return getHeaders().getValue(headerName);
}
/**
* Get all response headers.
*
* @return the response headers
*/
public abstract HttpHeaders getHeaders();
/**
* Get the publisher emitting response content chunks.
*
* Returns a stream of the response's body content. Emissions may occur on Reactor threads which should not be
* blocked. Blocking should be avoided as much as possible/practical in reactive programming but if you do use
* methods like {@code block()} on the stream then be sure to use {@code publishOn} before the blocking call.
*
* @return The response's content as a stream of {@link ByteBuffer}.
*/
public abstract Flux getBody();
/**
* Gets the {@link BinaryData} that represents the body of the response.
*
* Subclasses should override this method.
*
* @return The {@link BinaryData} response body.
*/
public BinaryData getBodyAsBinaryData() {
Flux body = getBody();
if (body != null) {
return BinaryDataHelper.createBinaryData(new FluxByteBufferContent(body));
} else {
return null;
}
}
/**
* Gets the response content as a {@code byte[]}.
*
* @return The response content as a {@code byte[]}.
*/
public abstract Mono getBodyAsByteArray();
/**
* Gets the response content as a {@link String}.
*
* By default, this method will inspect the response body for containing a byte order mark (BOM) to determine the
* encoding of the string (UTF-8, UTF-16, etc.). If a BOM isn't found this will default to using UTF-8 as the
* encoding, if a specific encoding is required use {@link #getBodyAsString(Charset)}.
*
* @return The response content as a {@link String}.
*/
public abstract Mono getBodyAsString();
/**
* Gets the response content as a {@link String}.
*
* @param charset The {@link Charset} to use as the string encoding.
* @return The response content as a {@link String}.
*/
public abstract Mono getBodyAsString(Charset charset);
/**
* Gets the response content as an {@link InputStream}.
*
* @return The response content as an {@link InputStream}.
*/
public Mono getBodyAsInputStream() {
return getBodyAsByteArray().map(ByteArrayInputStream::new);
}
/**
* Gets the {@link HttpRequest request} which resulted in this response.
*
* @return The {@link HttpRequest request} which resulted in this response.
*/
public final HttpRequest getRequest() {
return request;
}
/**
* Gets a new {@link HttpResponse response} object wrapping this response with its content buffered into memory.
*
* @return A new {@link HttpResponse response} with the content buffered.
*/
public HttpResponse buffer() {
return new BufferedHttpResponse(this);
}
/**
* Transfers body bytes to the {@link AsynchronousByteChannel}.
* @param channel The destination {@link AsynchronousByteChannel}.
* @return A {@link Mono} that completes when transfer is completed.
* @throws NullPointerException When {@code channel} is null.
*/
public Mono writeBodyToAsync(AsynchronousByteChannel channel) {
Objects.requireNonNull(channel, "'channel' must not be null");
Flux body = getBody();
if (body != null) {
return FluxUtil.writeToAsynchronousByteChannel(body, channel);
} else {
return Mono.empty();
}
}
/**
* Transfers body bytes to the {@link WritableByteChannel}.
* @param channel The destination {@link WritableByteChannel}.
* @throws IOException When I/O operation fails.
* @throws NullPointerException When {@code channel} is null.
*/
public void writeBodyTo(WritableByteChannel channel) throws IOException {
Flux body = getBody();
if (body != null) {
FluxUtil.writeToWritableByteChannel(body, channel)
.doFinally(ignored -> close())
.block();
}
}
/**
* Closes the response content stream, if any.
*/
@Override
public void close() {
}
}