/*
* Copyright 2016 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.linecorp.armeria.client.http.retrofit2;
import static java.util.Objects.requireNonNull;
import java.net.URI;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.escape.Escaper;
import com.google.common.escape.Escapers;
import com.linecorp.armeria.client.http.HttpClient;
import com.linecorp.armeria.common.Scheme;
import com.linecorp.armeria.common.SessionProtocol;
import okhttp3.HttpUrl;
import retrofit2.Retrofit;
/**
* A helper class for creating a new {@link Retrofit} instance with {@link ArmeriaCallFactory}.
* For example,
* <pre>{@code
* HttpClient httpClient = Clients.newClient(ClientFactory.DEFAULT,
* "none+http://localhost:8080",
* HttpClient.class);
*
* Retrofit retrofit = ArmeriaRetrofit.builder(httpClient)
* .addConverterFactory(GsonConverterFactory.create())
* .build();
*
* MyApi api = retrofit.create(MyApi.class);
* Response<User> user = api.getUser().execute();
* }
* </pre>
*/
public final class ArmeriaRetrofit {
private static final Escaper GROUP_NAME_ESCAPER = Escapers.builder()
.addEscape('@', "_")
.addEscape('/', "_")
.addEscape('\\', "_")
.addEscape('?', "_")
.addEscape('#', "_")
.addEscape(':', "_")
.build();
/**
* Creates a {@link Retrofit.Builder} with {@link ArmeriaCallFactory} using the specified
* {@link HttpClient} instance.
*/
public static Retrofit.Builder builder(HttpClient httpClient) {
return new Retrofit.Builder()
.baseUrl(convertToOkHttpUrl(httpClient.uri()))
.callFactory(new ArmeriaCallFactory(httpClient));
}
@VisibleForTesting
static HttpUrl convertToOkHttpUrl(URI uri) {
requireNonNull(uri.getScheme(), "uri does not contain the scheme component.");
SessionProtocol sessionProtocol =
Scheme.tryParse(uri.getScheme())
.map(Scheme::sessionProtocol)
.orElseGet(() -> SessionProtocol.of(uri.getScheme()));
String protocol = sessionProtocol.isTls() ? "https" : "http";
String authority = uri.getAuthority();
String path = uri.getPath();
final HttpUrl okHttpUrl = HttpUrl.parse(protocol + "://" + authority + path);
if (okHttpUrl == null) {
return HttpUrl.parse(protocol + "://" + GROUP_NAME_ESCAPER.escape(authority) + path);
} else {
return okHttpUrl;
}
}
private ArmeriaRetrofit() {}
}