Carsten said:
Cool Wes, I was getting sick of those exceptions!
When you embed a link in a Microsoft word document, Word will use “Microsoft Office Protocol Discovery” to determine if the document can be edited by Word (via DAV for example). This can result in some strange emails littering your inbox if you are running a Ruby on Rails based site with exception notifier.
For example:
A ActionController::NotImplemented occurred in application#index:
Only requests are allowed.
[RAILS_ROOT]/vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:389:in `recognize_path'
-------------------------------
Environment:
-------------------------------
* CONTENT_LENGTH : 0
* HTTP_CONTENT_LENGTH : 0
* HTTP_USER_AGENT : Microsoft Office Protocol Discovery
* HTTP_VERSION : HTTP/1.1
* REQUEST_METHOD : OPTIONS
* REQUEST_URI : /static/
By default RoR routing will route GET, PUT, POST, DELETE and HEAD request methods, but Office is using OPTIONS, which is described in RFC 2616
I suppose that this is useful if you are running an intranet site, but in that case you’re likely using something like Sharepoint, not a custom RoR application. These requests can be served by setting up a catch all route that will intercept any OPTIONS requests, and then return an appropriate header. Since we don’t support any of the features that Office is looking for, a simple 200 status will suffice.
You can serve these requests from whichever controller you feel is appropriate. In my case I’ll use a controller called ‘index’
In config/routes.rb
map.connect '*path',
:controller => 'index',
:action => 'options_for_mopd',
:conditions => {:method => :options}
In app/controllers/index_controller.rb
def options_for_mopd
render :nothing => true, :status => 200
end
Rails doesn’t support the OPTIONS HTTP verb, so we’ll have to monkey patch to add it. In lib/extra_http_verbs.rb
module ActionController
module Routing
HTTP_METHODS = [:get, :head, :post, :put, :delete, :options]
end
end
Make sure to require lib/extra_http_verbs.rb in an initializer.
Testing it is rather easy, even though RoR doesn’t have a function defined for OPTIONS like it does for GET, POST, PUT, DELETE and HEAD. In test/functional/index_controller_test.rb
def test_options_for_mopd
get :options_for_mopd, {}, :REQUEST_METHOD => 'OPTIONS'
assert_response :success
end
For more information about Microsoft Office Protocol Discovery, see this knowledge base article
Two things. I think it should be ‘path’ instead of ‘path’ and to test that it actually works, you can use curl which is available on every platform pretty much for free.
Here’s the curl command: curl -X OPTIONS http://:/
Two things. I think it should be ‘path’ instead of ‘path’ and to test that it actually works, you can use curl which is available on every platform pretty much for free.
Here’s the curl command: curl -X OPTIONS http://:/
Thanks!
Heh, I’m glad you were able to figure out my post even with the HTML interpolation. :) For anyone else who comes along, the curl command example is: curl -X OPTIONS http://host:port/path/whatever/that/is
I’ve run across another issue with this solution and have yet to solve it. Basically, any URI that is invalid generates an exception in my app. For example: http://localhost:3000/asdf/sf/adfs/ads/f <—obviously invalid
This occurs because of http://github.com/rails/rails/commit/dcaa074abf5691a933b9c55159cc7d98a02b3b2f and more information may be found at http://dev.rubyonrails.org/ticket/6953. My expectation is that since the first route doesn’t match that the matching attempts would continue through the routes file irrespective of the HTTP method.