From 4d594cffcfc93b37fad4e423ec8593299e50133c Mon Sep 17 00:00:00 2001 From: Rick Olson Date: Tue, 8 Apr 2008 05:05:54 +0000 Subject: Automatically parse posted JSON content for Mime::JSON requests. [rick] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9242 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/CHANGELOG | 10 ++++++++++ actionpack/lib/action_controller/base.rb | 5 +++-- actionpack/lib/action_controller/request.rb | 15 ++++++++++---- .../lib/action_view/template_handlers/erb.rb | 2 +- actionpack/test/controller/request_test.rb | 23 +++++++++++++++++++++- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index dd1447a25e..1e53a39667 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,15 @@ *SVN* +* Automatically parse posted JSON content for Mime::JSON requests. [rick] + + POST /posts + {"post": {"title": "Breaking News"}} + + def create + @post = Post.create params[:post] + # ... + end + * add json_escape ERB util to escape html entities in json strings that are output in HTML pages. [rick] * Provide a helper proxy to access helper methods from outside views. Closes #10839 [Josh Peek] diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index d7e4116581..7c838ba769 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -316,9 +316,10 @@ module ActionController #:nodoc: # A YAML parser is also available and can be turned on with: # # ActionController::Base.param_parsers[Mime::YAML] = :yaml - @@param_parsers = { Mime::MULTIPART_FORM => :multipart_form, + @@param_parsers = { Mime::MULTIPART_FORM => :multipart_form, Mime::URL_ENCODED_FORM => :url_encoded_form, - Mime::XML => :xml_simple } + Mime::XML => :xml_simple, + Mime::JSON => :json } cattr_accessor :param_parsers # Controls the default charset for all renders. diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 745161def8..823271d13f 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -402,6 +402,14 @@ EOM body.blank? ? {} : Hash.from_xml(body).with_indifferent_access when :yaml YAML.load(body) + when :json + if body.blank? + {} + else + data = ActiveSupport::JSON.decode(body) + data = {:_json => data} unless data.is_a?(Hash) + data.with_indifferent_access + end else {} end @@ -507,7 +515,6 @@ EOM end end - MULTIPART_BOUNDARY = %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n EOL = "\015\012" @@ -604,12 +611,12 @@ EOM end raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/ - begin + begin body.rewind if body.respond_to?(:rewind) - rescue Errno::ESPIPE + rescue Errno::ESPIPE # Handles exceptions raised by input streams that cannot be rewound # such as when using plain CGI under Apache - end + end params end diff --git a/actionpack/lib/action_view/template_handlers/erb.rb b/actionpack/lib/action_view/template_handlers/erb.rb index 6535dd2e25..f30cf0203c 100644 --- a/actionpack/lib/action_view/template_handlers/erb.rb +++ b/actionpack/lib/action_view/template_handlers/erb.rb @@ -3,7 +3,7 @@ require 'erb' class ERB module Util HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' } - JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C'} + JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' } # A utility method for escaping HTML tag characters. # This method is also aliased as h. diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index 6916e13417..82ddfec8e8 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -851,8 +851,13 @@ class MultipartRequestParameterParsingTest < Test::Unit::TestCase end end - class XmlParamsParsingTest < Test::Unit::TestCase + def test_hash_params + person = parse_body("David")[:person] + assert_kind_of Hash, person + assert_equal 'David', person['name'] + end + def test_single_file person = parse_body("David#{ActiveSupport::Base64.encode64('ABC')}") @@ -899,3 +904,19 @@ class LegacyXmlParamsParsingTest < XmlParamsParsingTest ActionController::CgiRequest.new(cgi).request_parameters end end + +class JsonParamsParsingTest < Test::Unit::TestCase + def test_hash_params + person = parse_body({:person => {:name => "David"}}.to_json)[:person] + assert_kind_of Hash, person + assert_equal 'David', person['name'] + end + + private + def parse_body(body) + env = { 'CONTENT_TYPE' => 'application/json', + 'CONTENT_LENGTH' => body.size.to_s } + cgi = ActionController::Integration::Session::StubCGI.new(env, body) + ActionController::CgiRequest.new(cgi).request_parameters + end +end -- cgit v1.2.3