Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 6823

Show
Ignore:
Timestamp:
05/23/07 19:09:37 (1 year ago)
Author:
bitsweat
Message:

Set RAW_POST_DATA when request parameters are parsed.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/lib/action_controller/cgi_process.rb

    r6764 r6823  
    7373 
    7474    def request_parameters 
    75       @request_parameters ||= self.class.parse_formatted_request_parameters(body, content_type_with_parameters, content_length, env) 
     75      @request_parameters ||= parse_formatted_request_parameters 
    7676    end 
    7777 
  • trunk/actionpack/lib/action_controller/request.rb

    r6815 r6823  
    232232 
    233233 
    234     # Receive the raw post data. 
    235     # This is useful for services such as REST, XMLRPC and SOAP 
    236     # which communicate over HTTP POST but don't use the traditional parameter format. 
     234    # Read the request body. This is useful for web services that need to 
     235    # work with raw requests directly. 
    237236    def raw_post 
    238       @env['RAW_POST_DATA'] ||= body.read 
     237      unless env.include? 'RAW_POST_DATA' 
     238        env['RAW_POST_DATA'] = body.read(content_length) 
     239        body.rewind if body.respond_to?(:rewind) 
     240      end 
     241      env['RAW_POST_DATA'] 
    239242    end 
    240243 
     
    313316      end 
    314317 
    315  
    316     class << self 
    317       def extract_content_type_without_parameters(content_type_with_parameters) 
    318         $1.strip.downcase if content_type_with_parameters =~ /^([^,\;]*)/ 
    319       end 
    320  
    321       def parse_formatted_request_parameters(body, content_type_with_parameters, content_length, env = {}) 
    322         content_length = content_length.to_i 
     318      def parse_formatted_request_parameters 
    323319        return {} if content_length.zero? 
    324320 
    325         content_type, boundary = extract_multipart_boundary(content_type_with_parameters.to_s) 
     321        content_type, boundary = self.class.extract_multipart_boundary(content_type_with_parameters) 
    326322        return {} if content_type.blank? 
    327323 
     
    330326 
    331327        # Only multipart form parsing expects a stream. 
    332         if strategy && strategy != :multipart_form 
    333           data = body.read(content_length) 
    334           body.rewind if body.respond_to?(:rewind) 
    335           body = data 
    336         end 
     328        body = raw_post if strategy && strategy != :multipart_form 
    337329 
    338330        case strategy 
     
    340332            strategy.call(body) 
    341333          when :url_encoded_form 
    342             clean_up_ajax_request_body! body 
    343             parse_query_parameters(body) 
     334            self.class.clean_up_ajax_request_body! body 
     335            self.class.parse_query_parameters(body) 
    344336          when :multipart_form 
    345             parse_multipart_form_parameters(body, boundary, content_length, env) 
     337            self.class.parse_multipart_form_parameters(body, boundary, content_length, env) 
    346338          when :xml_simple, :xml_node 
    347339            body.blank? ? {} : Hash.from_xml(body).with_indifferent_access 
     
    360352      end 
    361353 
     354    class << self 
    362355      def parse_query_parameters(query_string) 
    363356        return {} if query_string.blank? 
     
    403396      end 
    404397 
     398      def extract_multipart_boundary(content_type_with_parameters) 
     399        if content_type_with_parameters =~ MULTIPART_BOUNDARY 
     400          ['multipart/form-data', $1.dup] 
     401        else 
     402          extract_content_type_without_parameters(content_type_with_parameters) 
     403        end 
     404      end 
     405 
     406      def extract_content_type_without_parameters(content_type_with_parameters) 
     407        $1.strip.downcase if content_type_with_parameters =~ /^([^,\;]*)/ 
     408      end 
     409 
     410      def clean_up_ajax_request_body!(body) 
     411        body.chop! if body[-1] == 0 
     412        body.gsub!(/&_=$/, '') 
     413      end 
     414 
     415 
    405416      private 
    406417        def get_typed_value(value) 
     
    454465 
    455466        MULTIPART_BOUNDARY = %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n 
    456  
    457         def extract_multipart_boundary(content_type_with_parameters) 
    458           if content_type_with_parameters =~ MULTIPART_BOUNDARY 
    459             ['multipart/form-data', $1.dup] 
    460           else 
    461             extract_content_type_without_parameters(content_type_with_parameters) 
    462           end 
    463         end 
    464  
    465         def clean_up_ajax_request_body!(body) 
    466           body.chop! if body[-1] == 0 
    467           body.gsub!(/&_=$/, '') 
    468         end 
    469  
    470467 
    471468        EOL = "\015\012" 
  • trunk/actionpack/test/controller/request_test.rb

    r6764 r6823  
    709709    def process(name) 
    710710      File.open(File.join(FIXTURE_PATH, name), 'rb') do |file| 
    711         content_length = file.stat.size.to_s 
    712         content_type  = 'multipart/form-data, boundary=AaB03x' 
    713         ActionController::AbstractRequest.parse_formatted_request_parameters(file, content_type, content_length) 
     711        ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {}) 
    714712      end 
    715713    end 
     
    719717class XmlParamsParsingTest < Test::Unit::TestCase 
    720718  def test_single_file 
    721     body = "<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{Base64.encode64('ABC')}</avatar></person>" 
    722  
    723     person = ActionController::AbstractRequest.parse_formatted_request_parameters(StringIO.new(body), 'application/xml', body.size) 
     719    person = parse_body("<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{Base64.encode64('ABC')}</avatar></person>") 
    724720 
    725721    assert_equal "image/jpg", person['person']['avatar'].content_type 
     
    729725 
    730726  def test_multiple_files 
    731     body = <<-end_body 
     727    person = parse_body(<<-end_body) 
    732728      <person> 
    733729        <name>David</name> 
     
    739735    end_body 
    740736 
    741     person = ActionController::AbstractRequest.parse_formatted_request_parameters(StringIO.new(body), 'application/xml', body.size) 
    742  
    743737    assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type 
    744738    assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename 
     
    749743    assert_equal "DEF", person['person']['avatars']['avatar'].last.read 
    750744  end 
     745 
     746  private 
     747    def parse_body(body) 
     748      env = { 'CONTENT_TYPE'   => 'application/xml', 
     749              'CONTENT_LENGTH' => body.size.to_s } 
     750      cgi = ActionController::Integration::Session::MockCGI.new(env, body) 
     751      ActionController::CgiRequest.new(cgi).request_parameters 
     752    end 
    751753end