Showing posts with label Rest. Show all posts
Showing posts with label Rest. Show all posts

Thursday, November 07, 2013

GAE application behaves abnormally after deployment

I've been playing with Flickr API with a GAE webapp.
 To maximize the performance, I didn't use some framework to build it. Basic APIs such as http connections are used to handle the communication.
The small app has been auto-tested thousands of times on local GAE run-time, and it's working fine totally. And no GAE datastore is used for this app (hence no datastore indexes need to be generated); I expect the app to work fine after a successful deployment.

However I faced the issue that 45% of the http request gave the same error message, complaining the invalid format of the data stream (returned from Flickr REST service). From the debug message trace, it turned out almost half of the requests, which are supposed to get data in JSON format (by setting JSON format as one of the query parameters), got routed to flickr API community guidelines page, resulting in that irrelevant data in html format was returned, although every time the HTTP GET was requested towards the same Flickr url.

I did some googling, and was not able to find out why this happened. I was thinking probably Flickr partially blocked/redirected requests from google (GAE) because it was a Yahoo company. Not sure about that. On the second day, I just tested the same app again. It works totally fine again, just as what I experienced with the local GAE run-time. It seems there's always a delay before a newly deployed GAE app to behave properly.
 This is a Java app; I'll check if Python app behaves similarly.

Monday, August 19, 2013

Httpheaders to enable CORS filter for REST service used by dojo jsonrest data store

Dojo jsonrest datastore provides a simple way to implement ajax communication between dojo data grid (datagrid, enhancegrid, dgrid, or ondemandgrid) and the web service provider.
However, most times people would face CORS access issue when using jsonrest api.
Here's a few key points for the server side to enable the connection with jsonrest:
1. Access-Control-Allow-Origin, this header defines the allowed originate json request client. If not set, errors like "origin not allowed" will be thrown.
2. Access-Control-Allow-Headers, this header defines the allowed requesting headers, such as X-Requested-With, X-Range, Range, and so on. If not set, errors like "header not allowed" will be thrown.
3. Access-Control-Expose-Headers, this header defines the allowed response headers, such as Content-Range. If not set, error like "refused unsafe header" will be thrown.
X-Requested-With, X-Range, Range, Content-Range are the key headers attributes for jsonrest api to communciate with the server. They have to be enabled in the http header.

In order to enable them, we need to add/set a few headers from server side programmatically. Using java servlet/tomcat as an example, we can use server side filter to achieve this.
There's existing CORS filter library available at http://software.dzhuvinov.com/cors-filter-installation.html . However, it didn't work well for me. Implementing a custom CORS filter isn't that difficult as well. Here's the code:
public class CorsFilter implements Filter {

public CorsFilter() { }
public void init(FilterConfig fConfig) throws ServletException { }
public void destroy() { }
public void doFilter(
ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {
HttpServletResponse res=(HttpServletResponse)response;
res.addHeader("Access-Control-Allow-Origin", "*");
if(res.getHeader("Access-Control-Allow-Headers")==null) {
res.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-Range, Range, Content-Type, Accept");
}else{
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-Range, Range, Content-Type, Accept,"+res.getHeader("Access-Control-Allow-Headers"));
}
res.addHeader("Access-Control-Expose-Headers","Accept-Ranges, Content-Encoding, Content-Length, Content-Range");
chain.doFilter(request, response);
}
}
 After configuring this filter to apply to all requesting paths, it'll for sure enable those dojo jsonrest headers.
Please feel free to comment on whether there's easier ways to do this.