This will allow to use 'matrix' params in requests, like:
example.com/library;section=nw/books;topic=money;binding=hardcover
Will result in this params matrix:
All HTTP methods are supported, in case of POST they will be passed as a regular <form> parameters.
# File lib/sinatra/rack_matrix_params.rb, line 40 def call(env) # Copy PATH_INFO to REQUEST_URI if Rack::Test env['REQUEST_URI'] = env['PATH_INFO'] if env['rack.test'] env['REQUEST_PATH'] = env['PATH_INFO'] if env['rack.test'] # Split URI to components and then extract ;var=value pairs uri_components = env['REQUEST_URI'].split('/') matrix_params = {} uri_components.each do |component| sub_components, value = component.split(/\;(\w+)\=/), nil next unless sub_components.first # Skip subcomponent if it's empty (usually /) while param=sub_components.pop do if value matrix_params[sub_components.first] ||= {} matrix_params[sub_components.first].merge!( param => value ) value=nil next else value = param.gsub(/\?.*$/, '') end end end # Two things need to happen to make matrix params work: # (1) the parameters need to be appended to the 'normal' params # for the request. 'Normal' really depends on the content # type of the request, which does not seem accessible from # Middleware, so we use the existence of # rack.request.form_hash in the environment to distinguish # between basic and application/x-www-form-urlencoded # requests # (2) the parameters need to be stripped from the appropriate # path related env variables, so that request dispatching # does not trip over them # (1) Rewrite current path by stripping all matrix params from it if env['REQUEST_PATH'] == '/' env['REQUEST_URI'] = env['REQUEST_PATH'] env['REQUEST_PATH'] = env['PATH_INFO'] end # This is needed for OpenShift deployment / Passenger if env['REQUEST_PATH'] env['REQUEST_PATH'] = env['REQUEST_PATH'].gsub(/;([^\/]*)/, '').gsub(/\?(.*)$/, '') env['PATH_INFO'] = env['REQUEST_PATH'] end # (2) Append the matrix params to the 'normal' request params # FIXME: Make this work for multipart/form-data if env['rack.request.form_hash'] # application/x-www-form-urlencoded, most likely a POST env['rack.request.form_hash'].merge!(matrix_params) else # For other methods it's more complicated if env['REQUEST_METHOD']!='POST' and not matrix_params.keys.empty? env['QUERY_STRING'].gsub!(/;([^\/]*)/, '') new_params = matrix_params.collect do |component, params| params.collect { |k,v| "#{component}[#{k}]=#{CGI::escape(v.to_s)}" } end.flatten # Add matrix params as a regular GET params env['QUERY_STRING'] += '&' if not env['QUERY_STRING'].empty? env['QUERY_STRING'] += "#{new_params.join('&')}" end end @app.call(env) end
Generated with the Darkfish Rdoc Generator 2.