Dynamic Cookies For Retrofit 2 Requests - java

I've been using retrofit for quite a long time and haven't faced any serious usability issue before now. So my use case is very simple, I've to fetch an entity from another API that we're using to process a few data. Now the only issue is the service is using Cookies to accept entity id.
So this means that each request needs to have dynamic set of cookie associated with it. But currently I cannot see anything such that in Retrofit. I can see a old PR, but it was rejected for unknown reason.
Can anyone from Retrofit team can help in this matter. I think it will be very helpful. If you need code examples I can provide that in an edit.
TIA

Implement a custom CookieJar and set on the OkHttpClient
https://square.github.io/okhttp/4.x/okhttp/okhttp3/-cookie-jar/
abstract fun loadForRequest(url: HttpUrl): List<Cookie>
Load cookies from the jar for an HTTP request to url. This method returns a possibly empty list of cookies for the network request.

Related

Rest api - update single field of resource

Lets say I have rest endpoint for my Driver resource.
I have PUT method like this
myapi/drivers/{id}
{body of put method}
I need to add functionality which will allow to 'enable' and 'disable' driver
Is it good idea to create new endpoint for that like this?
PUT myapi/drivers/{id}/enable/false
or it is better to use existing endpoint ? One problem with using existing endpoint is that driver has lot's of fields(almost 30) and sending all those fields just for updating only 'enabled' or 'disable' driver is something overkill.
What do you think?
This is exactly what the HTTP method PATCH is made for. It is used in cases where the resource has many fields but you only want to update a few.
Just like with PUT, you send a request to myapi/drivers/{id}. However, unlike with PUT, you only send the fields you want to change in the request body.
Creating endpoints like myapi/drivers/{id}/enable is not very RESTful, as "enable" can't really be called a resource on its own.
For an example implementation of a Spring PATCH endpoint, please see this link.
Use PATCH Http metod to update one field
PATCH myapi/drivers/{id}/enable

Changing HTTP method in RequestDispatcher

How do I change HTTP method in javax,servlet.RequestDispatcher?
I have some old service APIs that support GET and POST, The new version supports DELETE method for removing a record which used to happen through POST earlier.
We are decommissioning old version APIs by setting RequestDispatcher.forward() for old end points (stop gap arrangement until clients change). everything was cool except this POST to DELETE mapping.
Any solution there for this problem without adding POST end point for delete operation in new API?>
Although I agree using the next layer after your servlets would be a better choice, this is interesting. It use to be common to wrap an incoming request to add request based functionality (IE: auth state, etc). The HttpServletRequestWrapper was used to accomplish this. You could do the following if you just need to change the method:
class PostDeleteAdapter extends HttpServletRequestWrapper {
public String getMethod(){ return "POST"; }
}
You may also change other aspects of the incoming request if you need to further adapt the request. This may play well with your servlet containers RequestDispatcher, however it's dependent upon the container entirely.
I think you can't do it using servlet API. You can do what you want creating a new request, processing it's response and sending it back through the original response (in the servlet).
Some http clientes might help you. See Apache HTTP client:
http://hc.apache.org/httpclient-3.x/methods/delete.html)

Grizzly HttpServer: Set permanent header for every response

I am using a Grizzly HttpServer and i want to add a specific header in every response. Specifically, i want to avoid CORS problems by adding an 'Access-Control-Allow-Origin' header.
So, ideally, i want something like this:
HttpServer server = GrizzlyServerFactory.createHttpServer(uri, crc);
server.setHeader("Access-Control-Allow-Origin" , "*");
Generally, i am looking for a solution that does not require that i have to manually insert this header in every request-response action.
Is there any way to do this?
As #alexey said, there is no way (from the current Grizzly Server version) to do this. If anyone finds something else that works, i will gladly confirm it as an accepted answer.
The best alternative that works quite well is to extend the 'ContainerResponseFilter' class and override the 'filter' method.
Here is an example for 1.x API
Here is an example for 2.x API (minor changes)

Jersey Client doesn't set Content-Length

I am using dropwizard for writing a webapp and also using Jersey Client as mentioned at
http://dropwizard.codahale.com/manual/client/#man-client-jersey
But it seems that whenever i try to do a post using the jersey client the remote webservice complains that Content-Length header is missing and fails.
public JobResponse createJob(JobRequest job) {
return jerseyClient.resource(URI.create(JOBS_URL))
.type(MediaType.APPLICATION_JSON_TYPE)
.header("Api-Key", job.getApiKey())
.post(JobResponse.class, job);
}
I have confirmed that the request does not contain the header and despite my best efforts I haven't been able to figure out why this is happening. Does anyone know if there is something that I am missing?
PS: The service that i am trying to hit is https://app.zencoder.com/docs/api/jobs/create
This is known "issue" and actually intended behavior.
Problem here is that entity is processed AFTER headers are written out to "the wire", thus Content-Length header value is not know when headers are serialized. If you need to have it, you have several options (with various complexity):
serialize entity by yourself; if you provide entity as string (or byte[]), Content-Length should be set.
create your own MessageBodyWriter, which would compute size of entity in getSize() method call.
there might be some other way how to do it, but I can't think of another right now.. hope it helps.
I was facing the same problem and the answer from Pavel didn't work out for me (I was using a FormMutiPart object).
I was using ApacheHttpClient4 instead of the regular com.sun.jersey.api.client.Client. Changing back to the Jersey Client, the Content-Lenght is calculated (at least in the case of FormMultiPart entity).

GWT RPC security, http header, authentication and requestbuilder

I am presuming that GWT RPC actually uses RequestBuilder.
Is there a way to extract the RequestBuilder instance used by my RPC service async requestor?
Actually, my question is, how do you extract the RequestBuilder instance to insert the authentication token as a http header? Is there a way to insert http headers into an RPC service request?
Even if I could insert a http header into the request, how then would the remote servlet be told to expect that auth token? Therefore, in fact, does GWT RPC provide a framework for secure authentication at all?
I am thinking the answer is NO, or at least not in a convenient way. Am I right?
I am coming from having used RestEasy in combination with RestyGWT over SSL, where we can insert headers anytime we wish. BTW, RestyGWT constructs its request to use RequestBuilder.
My actual motivation is comparing the security effectiveness between GWT RPC and GWT JAX-RS (RestyGWT + RestEasy). So if you, as the answerer, have an alternative detailed discourse comparing the security effectiveness of RPC with direct use of RequestBuilder or REST (rather than answering this question directly) please feel free to elaborate.
Am I right to presume that GWT RPC is not security friendly/effective and I should avoid using GWT RPC for secure authenticated requests?
You can have your async method return a Request or a RequestBuilder instead of void. Request allows you to abort() a pending request, whereas RequestBuilder allows you to modify the request before its sent (if you declare the return-type as RequestBuilder, you're responsible for calling send() to actually make the request).
Alternately, you can use an RpcRequestBuilder to customize the RequestBuilder for each and every call made with a specific async service proxy.
As far as I know there is no built in security solution for gwt rpc.
But If I need such authentication I would make the following steps:
1) To be able to set http headers you can make your custom request builder, as I do myself:
MyServiceAsync myService = GWT.create(MyService.class);
MyRequestBuilder myRequestBuilder = new MyRequestBuilder();
myRequestBuilder.addHeader("header", "value");
((ServiceDefTarget) serviceInstance).setRpcRequestBuilder(myRequestBuilder);
MyRequestBuilder extends RpcRequestBuilder. And inside MyRequestBuilder I override method doFinish(RequestBuilder rb) where I put my headers.
Maybe it is not a super solution, but I haven't yet found anything better.
2) For the server side I would implement the AuthenticationFilter for checking the headers and perform server side auth functions prior calling the Servlet.

Categories