Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I code my servlet so it works nicely with Cloudfront Cache

My servlet application is deployed to direct.albunack.net and there is a CloudFront cache at www.albunack.net.

The default page (index.jsp) is an (artist) search. Assuming for just a moment we are using direct.albunack.net when you enter search and submit the search goes to direct.albunack.net/artist/search. Everything under /artist maps to a servlet, this servlet does the search, if it finds only one result it then does a redirect to direct.albunack.net/artist/artistid - this uses the same servlet to construct a page for that artist and return it.

If instead it finds multiple results it then forwards results back to index.jsp but displaying the multiple results, if user then clicks on one of these results they are again redirected to direct.albunack.net/artist/artistid

So far so good, the problem occurs when I use www.albunack.net. The Cloudfront default (*) behaviour is to cache all requests, not forward headers ectera. But we add another behaviour for the /artist/search path so that it doesn't cache the actual search.

When it finds multiple results it redirects to http://www.albunack.net/index.jsp and then subsequently clicking on one of the choices redirects to http://www.albunack.net/artist/artistid.

But the problem I have (I think) is that because the search delegates down to direct.albunack.net when there is only one choice it redirects to http://direct.albunack.net/artist/artistid bypassing the cache and exposing our direct interface.

So how do I code this, if i actually hardcode the complete path including server then its not going to work when running locally, what is the right way.

Servlet code extract:

if (!Strings.isNullOrEmpty(artistName))
{
    //Look up artist for that id
    MusicBrainzSearchArtist mbArtistSearch = new MusicBrainzSearchArtist();
    List<Artist> mbArtists = mbArtistSearch.queryByArtistName(artistName);

    if (mbArtists.size() == 0)
    {
        request.setAttribute(ERROR, InfoMessage.MSG_NO_RESULTS_FOUND.getMsg(artistName));
        request.getRequestDispatcher("/index.jsp").forward(request, response);
        return;
    }
    else if (mbArtists.size() == 1)
    {
        response.sendRedirect("/artist/" + mbArtists.get(0).getId());
        return;
    }
    else
    {
        request.setAttribute(ERROR, InfoMessage.MSG_MULTIPLE_RESULTS_FOUND.getMsg(artistName));
        request.setAttribute("results", mbArtists);
        request.getRequestDispatcher("/index.jsp").forward(request, response);
        return;
    }
}

Update

Ive modified

 response.sendRedirect("/artist/" + mbArtists.get(0).getId());

to

response.sendRedirect(getRedirectServePath(request) + "/artist/" + mbArtists.get(0).getId());

 public String getRedirectServerPath(HttpServletRequest request)
    {
        return "http://" + request.getServerName() + ":" + request.getServerPort();
    }

and that works, but this seems ever so hacky and Im not sure quite sure why it works as I thought request.getServerName() would return direct.albunack.net or is it www.albunack.net because getServerName() returns the name of the original entry point onto the server but without it the path /artist will resolve the current server when doing a redirect ?

like image 669
Paul Taylor Avatar asked Apr 09 '15 14:04

Paul Taylor


1 Answers

Add something unique to the request (like timestamp to the url) and it will be not cached any more.

like image 98
Alex Avatar answered Sep 22 '22 13:09

Alex