incubator-deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tomas Von Veschler <tvv...@redhat.com>
Subject Re: [PATCH core] New rack middleware for handling Accept headers and returning the correct content type to client
Date Thu, 30 Jun 2011 01:13:42 GMT
On 06/29/2011 08:29 AM, Michal Fojtik wrote:
>
> On Jun 28, 2011, at 6:46 PM, Francesco Vollero wrote:
>
>> Ack, but i had few problems with whitespaces in the code. Fix it please.
>
> Thanks, I tried to remove them.
>
> Pushed. Will ping issue creators to test it.

json/html/xml content is working good for me on Firefox and Chrome, but 
what stopped working is the rest of content like css, png, js, etc. The 
same error as Justin points out:

Request URL:http://127.0.0.1/stylesheets/compiled/screen.css
Request Method:GET
Status Code:406 Not Acceptable

Response Headers
Connection:Keep-Alive
Content-Length:0
Date:Thu, 30 Jun 2011 01:06:21 GMT
Server:WEBrick/1.3.1 (Ruby/1.8.7/2010-06-23)
X-Runtime:0.000203

Regards,
Tomas

>    -- Michal
>
>>
>>
>> On Tue, Jun 28, 2011 at 03:51:42PM +0200, mfojtik@redhat.com wrote:
>>> From: Michal Fojtik<mfojtik@redhat.com>
>>>
>>>
>>> Signed-off-by: Michal fojtik<mfojtik@redhat.com>
>>> ---
>>> client/specs/content_spec.rb                    |  152 ++++++++++++++
>>> server/lib/deltacloud/base_driver/exceptions.rb |    7 +
>>> server/lib/sinatra/rack_accept.rb               |  152 ++++++++++++++
>>> server/lib/sinatra/respond_to.rb                |  248 -----------------------
>>> server/server.rb                                |    7 +-
>>> 5 files changed, 315 insertions(+), 251 deletions(-)
>>> create mode 100644 client/specs/content_spec.rb
>>> create mode 100644 server/lib/sinatra/rack_accept.rb
>>> delete mode 100644 server/lib/sinatra/respond_to.rb
>>>
>>> diff --git a/client/specs/content_spec.rb b/client/specs/content_spec.rb
>>> new file mode 100644
>>> index 0000000..78ae937
>>> --- /dev/null
>>> +++ b/client/specs/content_spec.rb
>>> @@ -0,0 +1,152 @@
>>> +#
>>> +# Copyright (C) 2009-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.
>>> +
>>> +require 'specs/spec_helper'
>>> +
>>> +def client
>>> +  RestClient::Resource.new(API_URL)
>>> +end
>>> +
>>> +def headers(header)
>>> +  encoded_credentials = ["#{API_NAME}:#{API_PASSWORD}"].pack("m0").gsub(/\n/,'')
>>> +  { :authorization =>  "Basic " + encoded_credentials }.merge(header)
>>> +end
>>> +
>>> +describe "return JSON" do
>>> +
>>> +  it 'should return JSON when using application/json, */*' do
>>> +    header_hash = {
>>> +      'Accept' =>  "application/json, */*"
>>> +    }
>>> +    client.get(header_hash) do |response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^application\/json/
>>> +    end
>>> +  end
>>> +
>>> +  it 'should return JSON when using just application/json' do
>>> +    header_hash = {
>>> +      'Accept' =>  "application/json"
>>> +    }
>>> +    client.get(header_hash) do |response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^application\/json/
>>> +    end
>>> +  end
>>> +
>>> +end
>>> +
>>> +describe "return HTML in different browsers" do
>>> +
>>> +  it "wants XML using format parameter" do
>>> +    client['?format=xml'].get('Accept' =>  'application/xhtml+xml') do |response,
request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^application\/xml/
>>> +    end
>>> +  end
>>> +
>>> +  it "wants HTML using format parameter and accept set to XML" do
>>> +    client['?format=html'].get('Accept' =>  'application/xml') do |response,
request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^text\/html/
>>> +    end
>>> +  end
>>> +
>>> +  it "wants a PNG image" do
>>> +    client['instance_states?format=png'].get('Accept' =>  'image/png') do
|response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^image\/png/
>>> +    end
>>> +  end
>>> +
>>> +  it "doesn't have accept header" do
>>> +    client.get('Accept' =>  '') do |response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^application\/xml/
>>> +    end
>>> +  end
>>> +
>>> +  it "can handle unknown formats" do
>>> +    client.get('Accept' =>  'format/unknown') do |response, request,&block|
>>> +      response.code.should == 406
>>> +    end
>>> +  end
>>> +
>>> +  it "wants explicitly XML" do
>>> +    client.get('Accept' =>  'application/xml') do |response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^application\/xml/
>>> +    end
>>> +  end
>>> +
>>> +  it "Internet Explorer" do
>>> +    header_hash = {
>>> +      'Accept' =>  "text/html, application/xhtml+xml, */*",
>>> +      'User-agent' =>  "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0;
en-US)"
>>> +    }
>>> +    client.get(header_hash) do |response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^text\/html/
>>> +    end
>>> +  end
>>> +
>>> +  it "Mozilla Firefox" do
>>> +    client.get('Accept' =>  "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
do |response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^text\/html/
>>> +    end
>>> +  end
>>> +
>>> +  it "Chrome" do
>>> +    header_hash = {
>>> +      'Accept' =>  "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
>>> +      'User-agent' =>  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/535.1
(KHTML, like Gecko) Chrome/14.0.790.0 Safari/535.1"
>>> +    }
>>> +    client.get(header_hash) do |response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^text\/html/
>>> +    end
>>> +  end
>>> +
>>> +  it "Safari" do
>>> +    header_hash = {
>>> +      'Accept' =>  "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
>>> +      'User-agent' =>  "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7;
da-dk) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
>>> +    }
>>> +    client.get(header_hash) do |response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^text\/html/
>>> +    end
>>> +  end
>>> +
>>> +  it "Opera" do
>>> +    header_hash = {
>>> +      'Accept' =>  "text/html, application/xml;q=0.9, application/xhtml+xml,
image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1",
>>> +      'User-agent' =>  "Opera/9.80 (X11; Linux i686; U; ru) Presto/2.8.131
Version/11.11"
>>> +    }
>>> +    client.get(header_hash) do |response, request,&block|
>>> +      response.code.should == 200
>>> +      response.headers[:content_type].should =~ /^text\/html/
>>> +    end
>>> +  end
>>> +
>>> +
>>> +
>>> +
>>> +
>>> +end
>>> diff --git a/server/lib/deltacloud/base_driver/exceptions.rb b/server/lib/deltacloud/base_driver/exceptions.rb
>>> index 391910f..d95191c 100644
>>> --- a/server/lib/deltacloud/base_driver/exceptions.rb
>>> +++ b/server/lib/deltacloud/base_driver/exceptions.rb
>>> @@ -21,6 +21,13 @@ module Deltacloud
>>>        end
>>>      end
>>>
>>> +    class UnknownMediaTypeError<  DeltacloudException
>>> +      def initialize(e, message=nil)
>>> +        message ||= e.message
>>> +        super(406, e.class.name, message, e.backtrace)
>>> +      end
>>> +    end
>>> +
>>>      class ValidationFailure<  DeltacloudException
>>>        def initialize(e, message=nil)
>>>          message ||= e.message
>>> diff --git a/server/lib/sinatra/rack_accept.rb b/server/lib/sinatra/rack_accept.rb
>>> new file mode 100644
>>> index 0000000..9dddadd
>>> --- /dev/null
>>> +++ b/server/lib/sinatra/rack_accept.rb
>>> @@ -0,0 +1,152 @@
>>> +# respond_to (The MIT License)
>>> +
>>> +# Permission is hereby granted, free of charge, to any person obtaining a copy
of this software
>>> +# and associated documentation files (the 'Software'), to deal in the Software
without restriction,
>>> +# including without limitation the rights to use, copy, modify, merge, publish,
distribute,
>>> +# sublicense, and/or sell copies of the Software, and to permit persons to whom
the Software is
>>> +# furnished to do so, subject to the following conditions:
>>> +#
>>> +# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT
>>> +# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND
>>> +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM,
>>> +# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM,
>>> +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE
>>> +
>>> +require 'sinatra/base'
>>> +require 'rack/accept'
>>> +
>>> +use Rack::Accept
>>> +
>>> +module Rack
>>> +
>>> +  module RespondTo
>>> +
>>> +    # This method is triggered after this helper is registred
>>> +    # within Sinatra.
>>> +    # We need to overide the default render method to supply correct path to
the
>>> +    # template, since Sinatra is by default looking in the current __FILE__
path
>>> +    def self.registered(app)
>>> +      app.helpers Rack::RespondTo::Helpers
>>> +      app.class_eval do
>>> +        alias :render_without_format :render
>>> +        def render(*args,&block)
>>> +          begin
>>> +            assumed_layout = args[1] == :layout
>>> +            args[1] = "#{args[1]}.#{format}".to_sym if args[1].is_a?(::Symbol)
>>> +            render_without_format *args,&block
>>> +          rescue Errno::ENOENT =>  e
>>> +            raise "ERROR: Missing template: #{args[1]}.#{args[0]}" unless assumed_layout
>>> +            raise e
>>> +          end
>>> +        end
>>> +        private :render
>>> +      end
>>> +    end
>>> +
>>> +      module Helpers
>>> +
>>> +        # This code was inherited from respond_to plugin
>>> +        # http://github.com/cehoffman/sinatra-respond_to
>>> +        #
>>> +        # This method is used to overide the default content_type returned from
>>> +        # rack-accept middleware.
>>> +        def self.included(klass)
>>> +          klass.class_eval do
>>> +            alias :content_type_without_save :content_type
>>> +            def content_type(*args)
>>> +              content_type_without_save *args
>>> +              request.env['rack-accept.format'] = args.first.to_sym
>>> +              response['Content-Type']
>>> +            end
>>> +          end
>>> +        end
>>> +
>>> +        def format(val=nil)
>>> +          request.env['rack-accept.format'] ||= val
>>> +          request.env['rack-accept.format'].to_sym
>>> +        end
>>> +
>>> +        def static_file?(path)
>>> +          public_dir = File.expand_path(options.public)
>>> +          path = File.expand_path(File.join(public_dir, unescape(path)))
>>> +          path[0, public_dir.length] == public_dir&&  File.file?(path)
>>> +        end
>>> +
>>> +        def respond_to(&block)
>>> +          wants = {}
>>> +          def wants.method_missing(type, *args,&handler)
>>> +            self[type] = handler
>>> +          end
>>> +          yield wants
>>> +          raise Deltacloud::ExceptionHandler::UnknownMediaTypeError::new(nil,
"Unknown format") unless wants[format]
>>> +          wants[format].call
>>> +        end
>>> +
>>> +    end
>>> +
>>> +  end
>>> +
>>> +  class MediaType<  Sinatra::Base
>>> +
>>> +    include Rack::RespondTo::Helpers
>>> +
>>> +    # Define supported media types here
>>> +    # The :return key stands for content-type which will be returned
>>> +    # The :match key stands for the matching Accept header
>>> +    ACCEPTED_MEDIA_TYPES = {
>>> +      :xml =>  { :return =>  'application/xml', :match =>  ['application/xml',
'text/xml'] },
>>> +      :json =>  { :return =>  'application/json', :match =>  ['application/json']
},
>>> +      :html =>  { :return =>  'text/html', :match =>  ['application/xhtml+xml',
'text/html'] },
>>> +      :png =>  { :return =>  'image/png', :match =>  ['image/png']
},
>>> +      :gv =>  { :return =>  'application/ghostscript', :match =>  ['application/ghostscript']
}
>>> +    }
>>> +
>>> +    def call(env)
>>> +      accept, index = env['rack-accept.request'], {}
>>> +
>>> +      # Skip everything when 'format' parameter is set in URL
>>> +      if env['rack.request.query_hash']["format"]
>>> +         media_type = case env['rack.request.query_hash']["format"]
>>> +            when 'html' then :html
>>> +            when 'xml' then :xml
>>> +            when 'json' then :json
>>> +            when 'gv' then :gv
>>> +            when 'png' then :png
>>> +          end
>>> +        index[media_type] = 1 if media_type
>>> +      else
>>> +        # Sort all requested media types in Accept using their 'q' values
>>> +        sorted_media_types = accept.media_type.qvalues.to_a.sort{ |a,b| b[1]<=>a[1]
}.collect { |t| t.first }
>>> +        # If Accept header is missing or is empty, fallback to XML format
>>> +        sorted_media_types<<  'application/xml' if sorted_media_types.empty?
>>> +        # Choose the right format with the media type according to the priority
>>> +        ACCEPTED_MEDIA_TYPES.each do |format, definition|
>>> +          definition[:match].each do |media_type|
>>> +            break if index[format] = sorted_media_types.index(media_type)
>>> +          end
>>> +        end
>>> +        # Reject formats with no/nil priority
>>> +        index.reject! { |format, priority| not priority }
>>> +      end
>>> +
>>> +      # If after all we don't have any matching format assume that client has
>>> +      # requested unknown/wrong media type and throw an 406 error with no body
>>> +      if index.keys.empty?
>>> +        status, headers, response = 406, {}, ""
>>> +      else
>>> +        media_type = index.to_a.sort{ |a, b| a[1]<=>b[1] }.first[0]
>>> +        # Set this environment variable for futher pickup by the 'format' helper
>>> +        # on top
>>> +        env['rack-accept.format'] = media_type
>>> +        status, headers, response = @app.call(env)
>>> +        # Overide the Content-type with :return value of matching format
>>> +        headers['Content-Type'] = ACCEPTED_MEDIA_TYPES[media_type][:return]
>>> +      end
>>> +
>>> +      [status, headers, response]
>>> +    end
>>> +
>>> +  end
>>> +
>>> +end
>>> +
>>> diff --git a/server/lib/sinatra/respond_to.rb b/server/lib/sinatra/respond_to.rb
>>> deleted file mode 100644
>>> index 139573b..0000000
>>> --- a/server/lib/sinatra/respond_to.rb
>>> +++ /dev/null
>>> @@ -1,248 +0,0 @@
>>> -# respond_to (The MIT License)
>>> -
>>> -# Permission is hereby granted, free of charge, to any person obtaining a copy
of this software
>>> -# and associated documentation files (the 'Software'), to deal in the Software
without restriction,
>>> -# including without limitation the rights to use, copy, modify, merge, publish,
distribute,
>>> -# sublicense, and/or sell copies of the Software, and to permit persons to whom
the Software is
>>> -# furnished to do so, subject to the following conditions:
>>> -#
>>> -# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT
>>> -# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND
>>> -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM,
>>> -# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM,
>>> -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE
>>> -
>>> -require 'sinatra/base'
>>> -require 'rack/accept'
>>> -
>>> -use Rack::Accept
>>> -
>>> -module Sinatra
>>> -  module RespondTo
>>> -
>>> -    class MissingTemplate<  Sinatra::NotFound; end
>>> -
>>> -    # Define all MIME types you want to support here.
>>> -    # This conversion table will be used for auto-negotiation
>>> -    # with browser in sinatra when no 'format' parameter is specified.
>>> -
>>> -    SUPPORTED_ACCEPT_HEADERS = {
>>> -      :xml =>  [
>>> -        'text/xml',
>>> -        'application/xml'
>>> -      ],
>>> -      :html =>  [
>>> -        'text/html',
>>> -        'application/xhtml+xml'
>>> -      ],
>>> -      :json =>  [
>>> -        'application/json'
>>> -      ]
>>> -    }
>>> -
>>> -    # We need to pass array of available response types to
>>> -    # best_media_type method
>>> -    def accept_to_array
>>> -      SUPPORTED_ACCEPT_HEADERS.keys.collect do |key|
>>> -        SUPPORTED_ACCEPT_HEADERS[key]
>>> -      end.flatten
>>> -    end
>>> -
>>> -    # Then, when we get best media type for response, we need
>>> -    # to know which format to choose
>>> -    def lookup_format_from_mime(mime)
>>> -      SUPPORTED_ACCEPT_HEADERS.keys.each do |format|
>>> -        return format if SUPPORTED_ACCEPT_HEADERS[format].include?(mime)
>>> -      end
>>> -    end
>>> -
>>> -    def self.registered(app)
>>> -
>>> -      app.helpers RespondTo::Helpers
>>> -
>>> -      app.before do
>>> -
>>> -        # Skip development error image and static content
>>> -        next if self.class.development?&&  request.path_info =~ %r{/__sinatra__/.*?.png}
>>> -        next if options.static?&&  options.public?&&  (request.get?
|| request.head?)&&  static_file?(request.path_info)
>>> -
>>> -        # Remove extension from URI
>>> -        # Extension will be available as a 'extension' method (extension=='txt')
>>> -
>>> -        extension request.path_info.match(/\.([^\.\/]+)$/).to_a.first
>>> -
>>> -        # If ?format= is present, ignore all Accept negotiations because
>>> -        # we are not dealing with browser
>>> -        if request.params.has_key? 'format'
>>> -          format params['format'].to_sym
>>> -        end
>>> -
>>> -        # Let's make a little exception here to handle
>>> -        # /api/instance_states[.gv/.png] calls
>>> -        if extension.eql?('gv')
>>> -          format :gv
>>> -        elsif extension.eql?('png')
>>> -          format :png
>>> -        end
>>> -
>>> -        # Get Rack::Accept::Response object and find best possible
>>> -        # mime type to output.
>>> -        # This negotiation works fine with latest rest-client gem:
>>> -        #
>>> -        # RestClient.get 'http://localhost:3001/api', {:accept =>  :json
} =>
>>> -        # 'application/json'
>>> -        # RestClient.get 'http://localhost:3001/api', {:accept =>  :xml }
=>
>>> -        # 'application/xml'
>>> -        #
>>> -        # Also browsers like Firefox (3.6.x) and Chromium reporting
>>> -        # 'application/xml+xhtml' which is recognized as :html reponse
>>> -        # In browser you can force output using ?format=[format] parameter.
>>> -
>>> -        rack_accept = env['rack-accept.request']
>>> -
>>> -        if rack_accept.media_type.to_s.strip.eql?('Accept:')
>>> -          format :xml
>>> -        elsif is_chrome?
>>> -          format :html
>>> -        else
>>> -          format lookup_format_from_mime(rack_accept.best_media_type(accept_to_array))
>>> -        end
>>> -
>>> -      end
>>> -
>>> -      app.class_eval do
>>> -
>>> -        # Simple helper to detect Chrome based browsers
>>> -        # which have screwed up they Accept headers.
>>> -        # Set HTML as default output format here
>>> -        def is_chrome?
>>> -          true if env['HTTP_USER_AGENT'] =~ /Chrome/
>>> -        end
>>> -
>>> -        # This code was copied from respond_to plugin
>>> -        # http://github.com/cehoffman/sinatra-respond_to
>>> -        # MIT License
>>> -        alias :render_without_format :render
>>> -        def render(*args,&block)
>>> -          assumed_layout = args[1] == :layout
>>> -          args[1] = "#{args[1]}.#{format}".to_sym if args[1].is_a?(::Symbol)
>>> -          render_without_format *args,&block
>>> -        rescue Errno::ENOENT =>  e
>>> -          raise MissingTemplate, "#{args[1]}.#{args[0]}" unless assumed_layout
>>> -          raise e
>>> -        end
>>> -        private :render
>>> -      end
>>> -
>>> -      # This code was copied from respond_to plugin
>>> -      # http://github.com/cehoffman/sinatra-respond_to
>>> -      app.configure :development do |dev|
>>> -        dev.error MissingTemplate do
>>> -          content_type :html, :charset =>  'utf-8'
>>> -          response.status = request.env['sinatra.error'].code
>>> -
>>> -          engine = request.env['sinatra.error'].message.split('.').last
>>> -          engine = 'haml' unless ['haml', 'builder', 'erb'].include? engine
>>> -
>>> -          path = File.basename(request.path_info)
>>> -          path = "root" if path.nil? || path.empty?
>>> -
>>> -          format = engine == 'builder' ? 'xml' : 'html'
>>> -
>>> -          layout = case engine
>>> -                   when 'haml' then "!!!\n%html\n  %body= yield"
>>> -                   when 'erb' then "<html>\n<body>\n<%= yield
%>\n</body>\n</html>"
>>> -                   end
>>> -
>>> -          layout = "<small>app.#{format}.#{engine}</small>\n<pre>#{escape_html(layout)}</pre>"
>>> -
>>> -          (<<-HTML).gsub(/^ {10}/, '')
>>> -<!DOCTYPE html>
>>> -<html>
>>> -<head>
>>> -<style type="text/css">
>>> -            body { text-align:center;font-family:helvetica,arial;font-size:22px;
>>> -              color:#888;margin:20px}
>>> -            #c {margin:0 auto;width:500px;text-align:left;}
>>> -            small {float:right;clear:both;}
>>> -            pre {clear:both;text-align:left;font-size:70%;width:500px;margin:0
auto;}
>>> -</style>
>>> -</head>
>>> -<body>
>>> -<h2>Sinatra can't find #{request.env['sinatra.error'].message}</h2>
>>> -<img src='/__sinatra__/500.png'>
>>> -<pre>#{request.env['sinatra.error'].backtrace.join("\n")}</pre>
>>> -<div id="c">
>>> -<small>application.rb</small>
>>> -<pre>#{request.request_method.downcase} '#{request.path_info}' do\n  respond_to
do |wants|\n    wants.#{format} { #{engine} :#{path} }\n  end\nend</pre>
>>> -</div>
>>> -</body>
>>> -</html>
>>> -          HTML
>>> -        end
>>> -
>>> -      end
>>> -    end
>>> -
>>> -    module Helpers
>>> -
>>> -      # This code was copied from respond_to plugin
>>> -      # http://github.com/cehoffman/sinatra-respond_to
>>> -      def self.included(klass)
>>> -        klass.class_eval do
>>> -          alias :content_type_without_save :content_type
>>> -          def content_type(*args)
>>> -            content_type_without_save *args
>>> -            @_format = args.first.to_sym
>>> -            response['Content-Type']
>>> -          end
>>> -        end
>>> -      end
>>> -
>>> -      def static_file?(path)
>>> -        public_dir = File.expand_path(options.public)
>>> -        path = File.expand_path(File.join(public_dir, unescape(path)))
>>> -
>>> -        path[0, public_dir.length] == public_dir&&  File.file?(path)
>>> -      end
>>> -
>>> -
>>> -      # Extension holds trimmed extension. This is extra usefull
>>> -      # when you want to build original URI (with extension)
>>> -      # You can simply call "#{request.env['REQUEST_URI']}.#{extension}"
>>> -      def extension(val=nil)
>>> -        @_extension ||= val
>>> -        @_extension
>>> -      end
>>> -
>>> -      # This helper will holds current format. Helper should be
>>> -      # accesible from all places in Sinatra
>>> -      def format(val=nil)
>>> -        @_format ||= val
>>> -        @_format
>>> -      end
>>> -
>>> -      def respond_to(&block)
>>> -        wants = {}
>>> -
>>> -        def wants.method_missing(type, *args,&handler)
>>> -          self[type] = handler
>>> -        end
>>> -
>>> -        # Set proper content-type and encoding for
>>> -        # text based formats
>>> -        if [:xml, :gv, :html, :json].include?(format)
>>> -          content_type format, :charset =>  'utf-8'
>>> -        end
>>> -        yield wants
>>> -        # Raise this error if requested format is not defined
>>> -        # in respond_to { } block.
>>> -        raise MissingTemplate if wants[format].nil?
>>> -
>>> -        wants[format].call
>>> -      end
>>> -
>>> -    end
>>> -
>>> -  end
>>> -end
>>> diff --git a/server/server.rb b/server/server.rb
>>> index 104ea9c..787d8e4 100644
>>> --- a/server/server.rb
>>> +++ b/server/server.rb
>>> @@ -17,7 +17,7 @@ require 'sinatra'
>>> require 'deltacloud'
>>> require 'drivers'
>>> require 'json'
>>> -require 'sinatra/respond_to'
>>> +require 'sinatra/rack_accept'
>>> require 'sinatra/static_assets'
>>> require 'sinatra/rabbit'
>>> require 'sinatra/lazy_auth'
>>> @@ -35,10 +35,13 @@ set :version, '0.3.0'
>>> include Deltacloud::Drivers
>>> set :drivers, Proc.new { driver_config }
>>>
>>> +Sinatra::Application.register Rack::RespondTo
>>> +
>>> use Rack::ETag
>>> use Rack::Runtime
>>> use Rack::MatrixParams
>>> use Rack::DriverSelect
>>> +use Rack::MediaType
>>>
>>> configure do
>>>    set :raise_errors =>  false
>>> @@ -63,8 +66,6 @@ error do
>>>    report_error
>>> end
>>>
>>> -Sinatra::Application.register Sinatra::RespondTo
>>> -
>>> # Redirect to /api
>>> get '/' do redirect root_url, 301; end
>>>
>>> --
>>> 1.7.4.1
>>>
>
> ------------------------------------------------------
> Michal Fojtik, mfojtik@redhat.com
> Deltacloud API: http://deltacloud.org
>

-- 
Tomas Von Veschler
Solution Architect    Tel: +34 662 388 666
Red Hat, S.L.                Madrid office

Mime
View raw message