HTTP Options method is not working as expected - rest

I have a Jersey 2.x application running in tomcat. All the method implementations are working as expected, and even I am able to get WADL by navigating to http://{host}:{port}/JerseyRESTWebapp/ws/rest/application.wadl.
Everything is great so far.
Now, Out of curiosity I tried navigating to http://{host}:{port}/JerseyRESTWebapp/ws/rest/employees URL using using HTTP OPTIONS method expecting i will get 405 Method not allowed but i got the 200 OK and response body contains the WADL. Can someone let me know why is this happening? I am using POSTMAN chrome extension as REST client.
Also in the Response Allow Header, i am getting POST,GET,DELETE,OPTIONS,HEAD. I am missing PUT method here. why?

This is how the resource discovery works by default. It's implemented to follow the spec in regards to OPTIONS resource discovery
This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.
If you want to disable the WADL, you can by setting the property ServerProperties.WADL_FEATURE_DISABLE to true.
If you're curious about how this is implemented, check out the source for the WadlModelProcessor. It goes through all the resource models and adds an extra OPTIONS resource method. You can read more about the ModelProcessor in the Jersey docs Programmatic API for Building Resources

Related

How to redirect the url from nested site in pencilblue?

I want to 301 redirect the URLs from previous site that are nested, as pencilblue doesn’t support them,
e.g. a/b to page/b
For this I have been experimenting in include/http/request_handler.js but facing some issues.
Call never comes inside RequestHandler.prototype.handleRequest or even RequestHandler.prototype.onSessionRetrieved (seems these methods are not being called from anywhere)
Therefore I placed the code in RequestHandler and after confirming that req is not for public resource or api, I create a new url and execute
return this.doRedirect(newUrl, 301)
This actually works but at the same time I receive
Can’t render headers after they are sent error
#1075 has not helped me much as I’m not sure which specific controller I should modify. I need to catch the req as early as possible and see if it’s a page then redirect to page prefixed url.
Thanks in advance.
There are couple of ways to do redirects. You can do them from a controller or from middleware. You are correct in that, some of the functions in the request handler are not called. These are deprecated despite the fact pencilblue team didn't mark them as such. They replaced a good deal of the request handler functionality with /include/http/router.js and include/http/middleware/index.js. Plugins can register their own middleware to hijack the request pipeline.
See Advanced Routing on wiki for more info about creating your own middleware.
Using the routing framework your plugin would be able to register middleware that would be able to inspect the request and then redirect based on your specific criteria. The Router will be accessible from req.router and from there you could call req.router.redirect (Source).
Reference: #1224

How to enable/disable HTTP methods for RESTful Web service?

I'm writing a RESTful Web service.
Technologies that I use:
Eclipse EE Kepler IDE
GlassFish 3 (based on Java 6)
Jersey
JDK v7
When I annotate a Java method with, for example, the #DELETE annotation
I get the following HTTP error (invoked via URI):
HTTP Status 405 - Method Not Allowed
I would like to know how to enable/disable (so that to enable/disable the above HTTP error) those methods (PUT, HEAD, etc.) and at which level it can be done (Glassfish, Web.xml, etc). As well, can you invoke all of those resource methods (annotated with HTTP method type) from either Web browser's URI, within the <form>, or stand-alone client application (non-browser)?
For example, whether or not the following config line on deployment descriptor is present, it makes no difference:
<security-constraint>
<web-resource-collection>
<web-resource-name>RESTfulServiceDrill</web-resource-name>
<url-pattern>/drill/rest/resource/*</url-pattern>
<http-method>DELETE</http-method>
</web-resource-collection>
Of course, one's can disable a specific resource method by throwing an exception from it (and map it to an HTTP error) as the indication of it. That would indicate that the implementation is not available, for example.
So far, only #GET and #POST (on the <form>) resource methods work out, the other annotated methods, such as #POST (via URI), #PUT, #DELETE, #OPTIONS returns the above HTTP error. And this is where my question needs solutions. Why does the mentioned resource methods cause HTTP error when the former two don't?
An example of a resource method:
#DELETE
#Consumes(MediaType.TEXT_PLAIN)
#Produces(MediaType.TEXT_PLAIN)
#Path("/getDelete/{value}/{cat}")
public String getDelete(#PathParam("value") String value, #PathParam("cat") String cat){
return value+" : "+cat;
}
Invoking URL:
getDelete
The deployment descriptor is empty, except for the above lines of XML code. So far, I made the app to work by using annotations, no Web.xml (only contains some default values, such as index.jsp files).
Any ideas out there?
To my understanding, You have your REST APIs exposed and you are trying to access it from HTML <form>.Now you are able to access the GET and POST methods(REST APIs) from HTML <form> but not PUT, DELETE and other HTTP methods.
The reason why you get Method Not Allowed exception when you try to access DELETE or PUT or other HTTP methods is, HTML <form> does not support methods other than GET and POST.
Even if you try
<form method="delete"> or <form method="put">
HTML will not understand these methods and consider this as simply <form> (i.e) default form method is GET.
So even you have mentioned method as DELETE or PUT. It is a GET request.
And when the call is made, the jersey container tries to find the requestpath(here"/getDelete/{value}/{cat}") with the specified method(here GET).
Though this path exists,you have mentioned DELETE as acceptable method in your resource(#DELETE annotation says so). But Jersey is looking for GET now.Since it cant find #GET, it returns Method not allowed Exception.
So, how to solve it?
In HTML <form> you cant use HTTP methods other than GET and POST. It is better to have a wrapper in between the REST layer and HTML. So that you can make a POST call from your HTML, then the wrapper handles that call and which in-turns calls the DELETE of REST layer.
And, why POST method is not working from browser is, By default Browser makes a GET call. Have a look at Postman to make REST calls with different Http methods.

Using JSON Search Queries with a GET request in JMeter

My org is trying to use JMeter as part of a test automation suite to test some back end REST APIs. Currently one of them supports using JSON queries as a way to get filtered results back from a GET request.
We are using the JMeter UI to create these tests and since all the other API calls work under the HttpClient3.1 HTTP Request implementation that is the implementation that I am currently using to get this to work. With this implementation I get the following when looking at the failure in the results tree (response data portion) I have made the error slightly more generic to protect some IP:
java.lang.IllegalArgumentException: Invalid uri 'https://server:port/restservice/v1/users?firstname_query={"in":["User1FirstName","User2FirstName"]}': Invalid query
at org.apache.commons.httpclient.HttpMethodBase.(HttpMethodBase.java:222)
at org.apache.commons.httpclient.methods.GetMethod.(GetMethod.java:89)
at org.apache.jmeter.protocol.http.sampler.HTTPHC3Impl.sample(HTTPHC3Impl.java:229)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1146)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1135)
at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:434)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:261)
at java.lang.Thread.run(Unknown Source)
I have also tried the same request using the Java implementation and get a similar result.
If anyone has any ideas or if you need more information let me know and thank you again in advance for any help you may be able to provide.
Your HTTP Request configuration is a little bit incorrect. JSON entities contain braces {} which are not allowed in URLs so you need to encode them.
Configure your HTTP Request sampler like:
Make sure "Encode" box is ticked.
And this way you will be able to send JSON with HTTP GET Requests. You can use View Results Tree listener to inspect request and response details:
You might also need to add HTTP Header Manager to your Test Plan and configure it to send Content-Type header with the value of application/json. See Testing SOAP/REST Web Services Using JMeter article for more details on properly configuring JMeter for testing REST APIs.

Firefox SDK: Get type of observed http request

I need to intercept HTTP request done by Firefox to set an additional header to the request (like described here: https://developer.mozilla.org/en-US/docs/Setting_HTTP_request_headers) - but I only want to do this if a Javascript resource is requested (or, equivalent, the request got triggered by an <script>tag).
In case of Javascript this sadly cannot be done via looking at the set "accept-encoding" header because this is set to "/".
I already analyzed the objects I get handed over when a request is done - but I cannot find the needed information in there.
Does anybody know how one can detect this?

Grails - integration tests for verifying REST calls

We'd like to add some integration tests for the many REST services that our Grails app exposes, instead of manually verifying them using the Firefox Poster plugin that we are currently using.
BTW, In our case it HAS to be an integration test, not a unit test.
I trust others have gone thru' this before and could save us some time instead of experimenting...
`grails test-app -integration`
Does the above command actually launch the functionality required to do a self-post to our own app (http://localhost/myapp) ? It would have to go through the url mapping pipeline, xml content negotiation, spring/acegi security, etc. If so, I suppose we could use the Groovy RESTClient as documented here:
http://groovy.codehaus.org/modules/http-builder/doc/rest.html
Google tells me another option is the functional-testing plugin:
http://thediscoblog.com/2009/06/15/grails-hip-tip-testing-restful-services/
Any comments or issues from the experienced? It's a Grails 1.2.1 app using plugins.acegi=0.5.2
What you want is
grails test-app integration:
As per http://grails.org/doc/latest/ref/Command%20Line/test-app.html
The REST services are usually created via actions in a controller that are set in the URLMappings to work with the different HTTP methods (GET, PUT, POST, DELETE), so since they are simple actions in a controller an integration test can be just a test method that test the action like any other, sending them the content-type you need, JSON for example and passing the correct data as JSON if that is what your services is expecting.
You can create multiple test methods for the same action to test the difference responses, for example if a non valid resource is requested than test that the service is returning the correct error code 404 for instance.