Why do it?
LuciadCPillar allows you to connect to access-restricted web services by providing authentication credentials.
There are cases where web services require forms of authentication that LuciadCPillar doesn’t support internally, such as bearer token schemes or signed URLs. In these cases, you can control HTTP requests to get access-restricted resources, either by adding HTTP headers and URI query parameters, or by modifying requests based on server responses.
How to do it?
You customize HTTP data loading by creating an IHttpClient
IHttpClient
IHttpClient
and passing it to model decoders that implement HTTP data loading.
For cases where you simply want to add HTTP headers and URI query parameters to each request, the LuciadCPillar API provides
the HttpClient
HttpClient
HttpClient
class. That’s a ready-made implementation of the IHttpClient
IHttpClient
IHttpClient
interface, which you can use to add HttpRequestOptions
HttpRequestOptions
HttpRequestOptions
to HTTP requests.
Program: HttpClient usage shows an example of how you can use the HTTP client.
auto httpClient = HttpClient::newBuilder().build();
auto httpRequestOptions = HttpRequestOptions::newBuilder().header("Authorization", "Bearer FooToken").build();
httpClient->setHttpRequestOptions(httpRequestOptions);
auto options = Ogc3DTilesModelDecoder::Options::newBuilder().httpClient(httpClient).build();
auto model = Ogc3DTilesModelDecoder::decode(url, options);
var httpClient = HttpClient.NewBuilder().Build();
var httpRequestOptions = HttpRequestOptions.NewBuilder().Header("Authorization", "Bearer FooToken").Build();
httpClient.HttpRequestOptions = httpRequestOptions;
var options = Ogc3DTilesModelDecoder.Options.NewBuilder().HttpClient(httpClient).Build();
var model = Ogc3DTilesModelDecoder.Decode(url, options);
var httpClient = HttpClient.newBuilder().build();
var httpRequestOptions = HttpRequestOptions.newBuilder().header("Authorization", "Bearer FooToken").build();
httpClient.setHttpRequestOptions(httpRequestOptions);
var options = Ogc3DTilesModelDecoder.Options.newBuilder().httpClient(httpClient).build();
var model = Ogc3DTilesModelDecoder.decode(url, options);
If you require finer control over the sent requests to adapt them to your needs, or if you want to use your own HTTP connection
implementation, you can create a custom IHttpClient
IHttpClient
IHttpClient
.
Program: Custom HTTP data loading shows an example of a custom HTTP client that adapts the HTTP request by adding an authorization header.
class CustomHttpClient final : public IHttpClient {
public:
explicit CustomHttpClient(std::string bearerToken) : _bearerToken(std::move(bearerToken)), _httpClient(HttpClient::newBuilder().build()) {
}
luciad::expected<HttpResponse, ErrorInfo> send(const HttpRequest& request, const CancellationToken& token) override {
auto httpRequest = request.asBuilder().header("Authorization", "Bearer " + _bearerToken).build();
auto response = _httpClient->send(httpRequest, token);
if (response.has_value()) {
std::cout << "Status code: " << response->getStatusCode() << std::endl;
}
return response;
}
private:
std::string _bearerToken;
std::shared_ptr<HttpClient> _httpClient;
};
public class CustomHttpClient : IHttpClient
{
private string _bearerToken;
private HttpClient _httpClient;
public CustomHttpClient(string bearerToken)
{
_bearerToken = bearerToken;
_httpClient = HttpClient.NewBuilder().Build();
}
public HttpResponse Send(HttpRequest request, CancellationToken token)
{
var httpRequest = request.AsBuilder().Header("Authorization", "Bearer " + _bearerToken).Build();
var response = _httpClient.Send(httpRequest, token);
Console.WriteLine("Status code: " + response.StatusCode);
return response;
}
}
private static class CustomHttpClient implements IHttpClient {
private final String _bearerToken;
private final HttpClient _httpClient;
CustomHttpClient(String bearerToken) {
_bearerToken = bearerToken;
_httpClient = HttpClient.newBuilder().build();
}
@Override
public @NotNull HttpResponse send(@NotNull HttpRequest request, @NotNull CancellationToken token) throws IOException {
var httpRequest = request.asBuilder().header("Authorization", "Bearer " + _bearerToken).build();
var response = _httpClient.send(httpRequest, token);
System.out.println("Status code: " + response.getStatusCode());
return response;
}
}
Program: Custom http client usage shows an example of how to use the custom HTTP client.
auto customHttpClient = std::make_shared<CustomHttpClient>("FooToken");
auto options = Ogc3DTilesModelDecoder::Options::newBuilder().httpClient(customHttpClient).build();
auto model = Ogc3DTilesModelDecoder::decode(url, options);
var customHttpClient = new CustomHttpClient("FooToken");
var options = Ogc3DTilesModelDecoder.Options.NewBuilder()
.HttpClient(customHttpClient)
.Build();
var model = Ogc3DTilesModelDecoder.Decode(path, options);
var customHttpClient = new CustomHttpClient("FooToken");
var options = Ogc3DTilesModelDecoder.Options.newBuilder()
.httpClient(customHttpClient)
.build();
var model = Ogc3DTilesModelDecoder.decode(url, options);