From: Michal Fojtik <[email protected]> --- server/lib/sinatra/rack_matrix_params.rb | 86 ++++++++++++++++++++++++++++++ server/server.rb | 4 +- server/views/instances/show.xml.haml | 2 +- 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 server/lib/sinatra/rack_matrix_params.rb
diff --git a/server/lib/sinatra/rack_matrix_params.rb b/server/lib/sinatra/rack_matrix_params.rb new file mode 100644 index 0000000..2858abe --- /dev/null +++ b/server/lib/sinatra/rack_matrix_params.rb @@ -0,0 +1,86 @@ +# Copyright (C) 2011 Red Hat, Inc. +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# Methods added to this helper will be available to all templates in the application. + +module Rack + + require 'cgi' + + class MatrixParams + def initialize(app) + @app = app + end + + # This will allow to use 'matrix' params in requests, like: + # + # http://example.com/library;section=nw/books;topic=money;binding=hardcover + # + # Will result in this params matrix: + # + # => params['library']['section'] = 'nw' + # => params['books']['topic'] = 'money' + # => params['books']['binding'] = 'hardcover' + # + # All HTTP methods are supported, in case of POST they will be passed as a + # regular <form> parameters. + + def call(env) + # Return if this header is not set properly (Rack::Test case...) + return @app.call(env) unless env['REQUEST_URI'] + + # 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 + end + end + end + + # If request method is POST, simply include matrix params in form_hash + env['rack.request.form_hash'].merge!(matrix_params) if env['rack.request.form_hash'] + + # For other methods it's a way complicated ;-) + if env['REQUEST_METHOD']!='POST' and not matrix_params.keys.empty? + # Rewrite current path and query string and strip all matrix params from it + env['REQUEST_PATH'], env['PATH_INFO'] = env['REQUEST_URI'].gsub(/;([^\/]*)/, '').gsub(/\?(.*)$/, '') + env['PATH_INFO'] = env['REQUEST_PATH'] + 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 + @app.call(env) + end + end + +end diff --git a/server/server.rb b/server/server.rb index 2618a9c..7eba0ae 100644 --- a/server/server.rb +++ b/server/server.rb @@ -30,15 +30,17 @@ require 'lib/deltacloud/helpers/blob_stream' require 'sinatra/rack_driver_select' require 'sinatra/rack_runtime' require 'sinatra/rack_etag' +require 'sinatra/rack_matrix_params' set :version, '0.2.0' include Deltacloud::Drivers set :drivers, Proc.new { driver_config } -use Rack::DriverSelect use Rack::ETag use Rack::Runtime +use Rack::MatrixParams +use Rack::DriverSelect configure do set :raise_errors => false diff --git a/server/views/instances/show.xml.haml b/server/views/instances/show.xml.haml index ca7e0c6..ec2751a 100644 --- a/server/views/instances/show.xml.haml +++ b/server/views/instances/show.xml.haml @@ -22,7 +22,7 @@ - @instance.actions.compact.each do |instance_action| %link{:rel => instance_action, :method => instance_action_method(instance_action), :href => self.send("#{instance_action}_instance_url", @instance.id)} - if driver.respond_to?(:run_on_instance) - %link{:rel => 'run', :method => :post, :href => run_instance_url(@instance.id)} + %link{:rel => 'run', :method => :post, :href => "#{run_instance_url(@instance.id)};id=#{@instance.id}"} - if @instance.instance_variables.include?("@launch_time") %launch_time< [email protected]_time -- 1.7.4
