405 Error response when processing POST requests to page cached Rails resources

Discussion in 'Ruby/Rails' started by aehso, Aug 15, 2008.

  1. aehso

    aehso New Member

    Hi,
    I have a rails application that is set up to cache pages for certain URLs for lsws to serve (when they exist) without hitting the rails application. Most of these URLs represent RESTful rails resource (i.e. using map.resource in routes.rb and restful controller implementations). An example resource is a feed url like /v1/feeds/1.app. GET the url and rails generates a cached version.

    My problem is that while the resource URL is cached correctly, whenever I try to subsequently POST (create a new resource), PUT (update the resource) or DELETE (delete a resource), lwsw always returns a 405 "Method Not Allowed" response.

    I suspect lsws thinks that since the static file exists on disk, it should refuse the request instead of dispatching it to the rails application. Is there any way to stop litespeed from returning the 405?

    I have looked at using rewrite to fudge it, and while I can write a condition like
    #RewriteCond %{REQUEST_METHOD} ^(POST|DELETE|PUT)$

    to detect the incoming request is not a GET, I'm not sure what I can write the subsequent RewriteRule as in order to stop lsws from finding the cached page and instead dispatch to the rails application.

    Any suggestions?

    John.
  2. mistwang

    mistwang LiteSpeed Staff

    Yes, it is a bit tricky.
    You can use a rewrite rule at vhost level to work around this like what you thought.

    RewriteCond %{REQUEST_METHOD} ^(POST|DELETE|PUT)$
    RewriteRule .* /dispatch.lsapi [L]
  3. aehso

    aehso New Member

    Yep, I came up with a similar solution. I was creating an lsapi external app for use by an LSAPI context (using http://www.litespeedtech.com/support/wiki/doku.php?id=litespeed_wiki:ruby_rails) thinking that might be more flexible and in doing so I ended up adding the following rewrite rules to the vhost rewrite config:

    RewriteRule ^/$ /index.html [QSA]
    RewriteRule ^/([^.]+)$ /$1.html [QSA]
    RewriteCond %{REQUEST_METHOD} ^(POST|DELETE|PUT)$
    RewriteRule ^/(.*)$ /dispatch.lsapi [QSA,L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^/(.*)$ /dispatch.lsapi [QSA,L]

    The second rule sends any POST|DELETE|PUT requests to rails, the last rule makes sure that it will still serve any cached pages (for GETs only)

    Then I realised that the lsapi context wasn't necessary as the above rules would dispatch to my original Rails context properly.

    All working nicely now!
  4. mistwang

    mistwang LiteSpeed Staff

    The rails context implicitly creates the "/dispatch.lsapi" LSAPI context. but you are free to configure everything manually.

Share This Page