You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I found that the JsonRpcHttpClient did not work with an RPC server provided by gorilla/rpc. The problem seems to be that HttpUrlConnection is performing a CONNECT while this server is configured to use POST, and therefore gorilla/rpc simply returns a 405.
Firstly, is there a way to configure JsonRpcHttpClient to use simple requests instead of a connect? I think the answer is no, and thus the basis of a similar issue #252.
Secondly, if JsonRpcHttpClient cannot work with gorilla/rpc, here is what I came up with to work around the limitation. This is not quite production code, but it is a very minimal adapter that combines the JsonRpcClient and (an older version of) OkHttp to fully implement IJsonRpcClient:
packagecom.path.to.package;
importcom.fasterxml.jackson.databind.ObjectMapper;
importcom.googlecode.jsonrpc4j.IJsonRpcClient;
importcom.googlecode.jsonrpc4j.JsonRpcClient;
importcom.squareup.okhttp.Headers;
importcom.squareup.okhttp.MediaType;
importcom.squareup.okhttp.OkHttpClient;
importcom.squareup.okhttp.Request;
importcom.squareup.okhttp.RequestBody;
importjava.io.ByteArrayOutputStream;
importjava.lang.reflect.Type;
importjava.net.URL;
importjava.util.HashMap;
importjava.util.Map;
importstaticcom.googlecode.jsonrpc4j.JsonRpcBasicServer.ACCEPT_ENCODING;
publicclassRpcServerOkHttpClientextendsJsonRpcClientimplementsIJsonRpcClient {
privatefinalOkHttpClientclient = newOkHttpClient();
privatefinalMediaTypemediaType = MediaType.parse("application/json");
privatestaticfinalStringGZIP = "gzip";
privatefinalMap<String, String> headers = newHashMap<>();
privateURLserviceUrl;
privatebooleangzipRequests = false;
/** * Creates the {@link RpcServerOkHttpClient} bound to the given {@code serviceUrl}. * The headers provided in the {@code headers} map are added to every request * made to the {@code serviceUrl}. * * @param serviceUrl the service end-point URL * @param headers the headers */publicRpcServerOkHttpClient(URLserviceUrl, Map<String, String> headers) {
this(newObjectMapper(), serviceUrl, headers);
}
/** * Creates the {@link RpcServerOkHttpClient} bound to the given {@code serviceUrl}. * The headers provided in the {@code headers} map are added to every request * made to the {@code serviceUrl}. * * @param mapper the {@link ObjectMapper} to use for json<->java conversion * @param serviceUrl the service end-point URL * @param headers the headers */publicRpcServerOkHttpClient(ObjectMappermapper, URLserviceUrl, Map<String, String> headers) {
this(mapper, serviceUrl, headers, false, false);
}
/** * Creates the {@link RpcServerOkHttpClient} bound to the given {@code serviceUrl}. * The headers provided in the {@code headers} map are added to every request * made to the {@code serviceUrl}. * * @param mapper the {@link ObjectMapper} to use for json<->java conversion * @param serviceUrl the service end-point URL * @param headers the headers * @param gzipRequests whether gzip the request * @param acceptGzipResponses whether accept gzip response */publicRpcServerOkHttpClient(ObjectMappermapper, URLserviceUrl, Map<String, String> headers, booleangzipRequests, booleanacceptGzipResponses) {
super(mapper);
this.serviceUrl = serviceUrl;
this.headers.putAll(headers);
this.gzipRequests = gzipRequests;
if (acceptGzipResponses) {
this.headers.put(ACCEPT_ENCODING, GZIP);
}
}
/** * Creates the {@link RpcServerOkHttpClient} bound to the given {@code serviceUrl}. * The headers provided in the {@code headers} map are added to every request * made to the {@code serviceUrl}. * * @param serviceUrl the service end-point URL */publicRpcServerOkHttpClient(URLserviceUrl) {
this(newObjectMapper(), serviceUrl, newHashMap<String, String>());
}
/** * {@inheritDoc} */@Overridepublicvoidinvoke(StringmethodName, Objectargument) throwsThrowable {
invoke(methodName, argument, null, newHashMap<>());
}
@OverridepublicObjectinvoke(StringmethodName, Objectargument, TypereturnType) throwsThrowable {
returninvoke(methodName, argument, returnType, newHashMap<>());
}
@OverridepublicObjectinvoke(StringmethodName, Objectargument, TypereturnType, Map<String, String> extraHeaders) throwsThrowable {
varbaos = newByteArrayOutputStream();
super.invoke(methodName, argument, baos);
varbody = RequestBody.create(mediaType, baos.toByteArray());
varrequest = newRequest.Builder()
.url(serviceUrl)
.post(body)
.headers(Headers.of(extraHeaders))
.build();
if (gzipRequests) {
// TODO: set something on okhttp
}
varcall = client.newCall(request);
varresponse = call.execute();
if (! response.isSuccessful()) {
thrownewRuntimeException("Failed to execute request: " + response);
}
returnsuper.readResponse(returnType, response.body().byteStream());
}
@Overridepublic <T> Tinvoke(StringmethodName, Objectargument, Class<T> clazz) throwsThrowable {
returninvoke(methodName, argument, clazz, newHashMap<>());
}
@Overridepublic <T> Tinvoke(StringmethodName, Objectargument, Class<T> clazz, Map<String, String> extraHeaders) throwsThrowable {
return (T) invoke(methodName, argument, (Type) clazz, newHashMap<>());
}
}
The text was updated successfully, but these errors were encountered:
I found that the
JsonRpcHttpClient
did not work with an RPC server provided by gorilla/rpc. The problem seems to be thatHttpUrlConnection
is performing a CONNECT while this server is configured to use POST, and therefore gorilla/rpc simply returns a 405.Firstly, is there a way to configure
JsonRpcHttpClient
to use simple requests instead of a connect? I think the answer is no, and thus the basis of a similar issue #252.Secondly, if
JsonRpcHttpClient
cannot work with gorilla/rpc, here is what I came up with to work around the limitation. This is not quite production code, but it is a very minimal adapter that combines theJsonRpcClient
and (an older version of)OkHttp
to fully implementIJsonRpcClient
:The text was updated successfully, but these errors were encountered: