Skip to content
This repository
Browse code

Remove --http.

  • Loading branch information...
commit 6db930cb5bbff9ad824590b5844e04768de240b1 1 parent 1efeb07
José Valim authored March 14, 2012

Showing 30 changed files with 7 additions and 1,020 deletions. Show diff stats Hide diff stats

  1. 2  actionpack/CHANGELOG.md
  2. 1  actionpack/lib/action_controller.rb
  3. 134  actionpack/lib/action_controller/http.rb
  4. 4  actionpack/test/abstract_unit.rb
  5. 19  actionpack/test/controller/http/action_methods_test.rb
  6. 55  actionpack/test/controller/http/conditional_get_test.rb
  7. 27  actionpack/test/controller/http/data_streaming_test.rb
  8. 20  actionpack/test/controller/http/force_ssl_test.rb
  9. 19  actionpack/test/controller/http/redirect_to_test.rb
  10. 37  actionpack/test/controller/http/renderers_test.rb
  11. 20  actionpack/test/controller/http/url_for_test.rb
  12. 271  railties/guides/source/api_app.textile
  13. 20  railties/lib/rails/configuration.rb
  14. 23  railties/lib/rails/generators.rb
  15. 8  railties/lib/rails/generators/rails/app/app_generator.rb
  16. 6  railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt
  17. 9  railties/lib/rails/generators/rails/app/templates/config/application.rb
  18. 1  railties/lib/rails/generators/rails/resource/resource_generator.rb
  19. 3  railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
  20. 60  railties/lib/rails/generators/rails/scaffold_controller/templates/http_controller.rb
  21. 6  railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
  22. 50  railties/lib/rails/generators/test_unit/scaffold/templates/http_functional_test.rb
  23. 28  railties/test/application/generators_test.rb
  24. 27  railties/test/application/initializers/frameworks_test.rb
  25. 30  railties/test/application/middleware_test.rb
  26. 20  railties/test/application/rake_test.rb
  27. 33  railties/test/generators/app_generator_test.rb
  28. 6  railties/test/generators/resource_generator_test.rb
  29. 37  railties/test/generators/scaffold_controller_generator_test.rb
  30. 51  railties/test/generators_test.rb
2  actionpack/CHANGELOG.md
Source Rendered
... ...
@@ -1,7 +1,5 @@
1 1
 ## Rails 4.0.0 (unreleased) ##
2 2
 
3  
-*   Support API apps http://edgeguides.rubyonrails.org/api_app.html *Santiago Pastorino and Carlos Antonio da Silva*
4  
-
5 3
 *   Add `include_hidden` option to select tag. With `:include_hidden => false` select with `multiple` attribute doesn't generate hidden input with blank value. *Vasiliy Ermolovich*
6 4
 
7 5
 *   Removed default `size` option from the `text_field`, `search_field`, `telephone_field`, `url_field`, `email_field` helpers. *Philip Arndt*
1  actionpack/lib/action_controller.rb
@@ -6,7 +6,6 @@ module ActionController
6 6
 
7 7
   autoload :Base
8 8
   autoload :Caching
9  
-  autoload :HTTP
10 9
   autoload :Metal
11 10
   autoload :Middleware
12 11
 
134  actionpack/lib/action_controller/http.rb
... ...
@@ -1,134 +0,0 @@
1  
-require "action_controller/log_subscriber"
2  
-
3  
-module ActionController
4  
-  # HTTP Controller is a lightweight version of <tt>ActionController::Base</tt>,
5  
-  # created for applications that don't require all functionality that a complete
6  
-  # \Rails controller provides, allowing you to create faster controllers. The
7  
-  # main scenario where HTTP Controllers could be used is API only applications.
8  
-  #
9  
-  # An HTTP Controller is different from a normal controller in the sense that
10  
-  # by default it doesn't include a number of features that are usually required
11  
-  # by browser access only: layouts and templates rendering, cookies, sessions,
12  
-  # flash, assets, and so on. This makes the entire controller stack thinner and
13  
-  # faster, suitable for API applications. It doesn't mean you won't have such
14  
-  # features if you need them: they're all available for you to include in
15  
-  # your application, they're just not part of the default HTTP Controller stack.
16  
-  #
17  
-  # By default, only the ApplicationController in a \Rails application inherits
18  
-  # from <tt>ActionController::HTTP</tt>. All other controllers in turn inherit
19  
-  # from ApplicationController.
20  
-  #
21  
-  # A sample controller could look like this:
22  
-  #
23  
-  #   class PostsController < ApplicationController
24  
-  #     def index
25  
-  #       @posts = Post.all
26  
-  #       render json: @posts
27  
-  #     end
28  
-  #   end
29  
-  #
30  
-  # Request, response and parameters objects all work the exact same way as
31  
-  # <tt>ActionController::Base</tt>.
32  
-  #
33  
-  # == Renders
34  
-  #
35  
-  # The default HTTP Controller stack includes all renderers, which means you
36  
-  # can use <tt>render :json</tt> and brothers freely in your controllers. Keep
37  
-  # in mind that templates are not going to be rendered, so you need to ensure
38  
-  # your controller is calling either <tt>render</tt> or <tt>redirect</tt> in
39  
-  # all actions.
40  
-  #
41  
-  #   def show
42  
-  #     @post = Post.find(params[:id])
43  
-  #     render json: @post
44  
-  #   end
45  
-  #
46  
-  # == Redirects
47  
-  #
48  
-  # Redirects are used to move from one action to another. You can use the
49  
-  # <tt>redirect</tt> method in your controllers in the same way as
50  
-  # <tt>ActionController::Base</tt>. For example:
51  
-  #
52  
-  #   def create
53  
-  #     redirect_to root_url and return if not_authorized?
54  
-  #     # do stuff here
55  
-  #   end
56  
-  #
57  
-  # == Adding new behavior
58  
-  #
59  
-  # In some scenarios you may want to add back some functionality provided by
60  
-  # <tt>ActionController::Base</tt> that is not present by default in
61  
-  # <tt>ActionController::HTTP</tt>, for instance <tt>MimeResponds</tt>. This
62  
-  # module gives you the <tt>respond_to</tt> and <tt>respond_with</tt> methods.
63  
-  # Adding it is quite simple, you just need to include the module in a specific
64  
-  # controller or in <tt>ApplicationController</tt> in case you want it
65  
-  # available to your entire app:
66  
-  #
67  
-  #   class ApplicationController < ActionController::HTTP
68  
-  #     include ActionController::MimeResponds
69  
-  #   end
70  
-  #
71  
-  #   class PostsController < ApplicationController
72  
-  #     respond_to :json, :xml
73  
-  #
74  
-  #     def index
75  
-  #       @posts = Post.all
76  
-  #       respond_with @posts
77  
-  #     end
78  
-  #   end
79  
-  #
80  
-  # Quite straightforward. Make sure to check <tt>ActionController::Base</tt>
81  
-  # available modules if you want to include any other functionality that is
82  
-  # not provided by <tt>ActionController::HTTP</tt> out of the box.
83  
-  class HTTP < Metal
84  
-    abstract!
85  
-
86  
-    # Shortcut helper that returns all the ActionController::HTTP modules except the ones passed in the argument:
87  
-    #
88  
-    #   class MetalController
89  
-    #     ActionController::HTTP.without_modules(:ParamsWrapper, :Streaming).each do |left|
90  
-    #       include left
91  
-    #     end
92  
-    #   end
93  
-    #
94  
-    # This gives better control over what you want to exclude and makes it easier
95  
-    # to create a bare controller class, instead of listing the modules required manually.
96  
-    def self.without_modules(*modules)
97  
-      modules = modules.map do |m|
98  
-        m.is_a?(Symbol) ? ActionController.const_get(m) : m
99  
-      end
100  
-
101  
-      MODULES - modules
102  
-    end
103  
-
104  
-    MODULES = [
105  
-      HideActions,
106  
-      UrlFor,
107  
-      Redirecting,
108  
-      Rendering,
109  
-      Renderers::All,
110  
-      ConditionalGet,
111  
-      RackDelegation,
112  
-
113  
-      ForceSSL,
114  
-      DataStreaming,
115  
-
116  
-      # Before callbacks should also be executed the earliest as possible, so
117  
-      # also include them at the bottom.
118  
-      AbstractController::Callbacks,
119  
-
120  
-      # Append rescue at the bottom to wrap as much as possible.
121  
-      Rescue,
122  
-
123  
-      # Add instrumentations hooks at the bottom, to ensure they instrument
124  
-      # all the methods properly.
125  
-      Instrumentation
126  
-    ]
127  
-
128  
-    MODULES.each do |mod|
129  
-      include mod
130  
-    end
131  
-
132  
-    ActiveSupport.run_load_hooks(:action_controller, self)
133  
-  end
134  
-end
4  actionpack/test/abstract_unit.rb
@@ -293,10 +293,6 @@ def self.test_routes(&block)
293 293
     end
294 294
   end
295 295
 
296  
-  class HTTP
297  
-    include SharedTestRoutes.url_helpers
298  
-  end
299  
-
300 296
   class TestCase
301 297
     include ActionDispatch::TestProcess
302 298
 
19  actionpack/test/controller/http/action_methods_test.rb
... ...
@@ -1,19 +0,0 @@
1  
-require 'abstract_unit'
2  
-
3  
-class ActionMethodsHTTPController < ActionController::HTTP
4  
-  def one; end
5  
-  def two; end
6  
-  hide_action :two
7  
-end
8  
-
9  
-class ActionMethodsHTTPTest < ActiveSupport::TestCase
10  
-  def setup
11  
-    @controller = ActionMethodsHTTPController.new
12  
-  end
13  
-
14  
-  def test_action_methods
15  
-    assert_equal Set.new(%w(one)),
16  
-                 @controller.class.action_methods,
17  
-                 "#{@controller.controller_path} should not be empty!"
18  
-  end
19  
-end
55  actionpack/test/controller/http/conditional_get_test.rb
... ...
@@ -1,55 +0,0 @@
1  
-require 'abstract_unit'
2  
-
3  
-class ConditionalGetHTTPController < ActionController::HTTP
4  
-  before_filter :handle_last_modified_and_etags, :only => :two
5  
-
6  
-  def one
7  
-    if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123])
8  
-      render :text => "Hi!"
9  
-    end
10  
-  end
11  
-
12  
-  def two
13  
-    render :text => "Hi!"
14  
-  end
15  
-
16  
-  private
17  
-
18  
-  def handle_last_modified_and_etags
19  
-    fresh_when(:last_modified => Time.now.utc.beginning_of_day, :etag => [ :foo, 123 ])
20  
-  end
21  
-end
22  
-
23  
-class ConditionalGetHTTPTest < ActionController::TestCase
24  
-  tests ConditionalGetHTTPController
25  
-
26  
-  def setup
27  
-    @last_modified = Time.now.utc.beginning_of_day.httpdate
28  
-  end
29  
-
30  
-  def test_request_with_bang_gets_last_modified
31  
-    get :two
32  
-    assert_equal @last_modified, @response.headers['Last-Modified']
33  
-    assert_response :success
34  
-  end
35  
-
36  
-  def test_request_with_bang_obeys_last_modified
37  
-    @request.if_modified_since = @last_modified
38  
-    get :two
39  
-    assert_response :not_modified
40  
-  end
41  
-
42  
-  def test_last_modified_works_with_less_than_too
43  
-    @request.if_modified_since = 5.years.ago.httpdate
44  
-    get :two
45  
-    assert_response :success
46  
-  end
47  
-
48  
-  def test_request_not_modified
49  
-    @request.if_modified_since = @last_modified
50  
-    get :one
51  
-    assert_equal 304, @response.status.to_i
52  
-    assert_blank @response.body
53  
-    assert_equal @last_modified, @response.headers['Last-Modified']
54  
-  end
55  
-end
27  actionpack/test/controller/http/data_streaming_test.rb
... ...
@@ -1,27 +0,0 @@
1  
-require 'abstract_unit'
2  
-
3  
-module TestHTTPFileUtils
4  
-  def file_name() File.basename(__FILE__) end
5  
-  def file_path() File.expand_path(__FILE__) end
6  
-  def file_data() @data ||= File.open(file_path, 'rb') { |f| f.read } end
7  
-end
8  
-
9  
-class DataStreamingHTTPController < ActionController::HTTP
10  
-  include TestHTTPFileUtils
11  
-
12  
-  def one; end
13  
-  def two
14  
-    send_data(file_data, {})
15  
-  end
16  
-end
17  
-
18  
-class DataStreamingHTTPTest < ActionController::TestCase
19  
-  include TestHTTPFileUtils
20  
-  tests DataStreamingHTTPController
21  
-
22  
-  def test_data
23  
-    response = process('two')
24  
-    assert_kind_of String, response.body
25  
-    assert_equal file_data, response.body
26  
-  end
27  
-end
20  actionpack/test/controller/http/force_ssl_test.rb
... ...
@@ -1,20 +0,0 @@
1  
-require 'abstract_unit'
2  
-
3  
-class ForceSSLHTTPController < ActionController::HTTP
4  
-  force_ssl
5  
-
6  
-  def one; end
7  
-  def two
8  
-    head :ok
9  
-  end
10  
-end
11  
-
12  
-class ForceSSLHTTPTest < ActionController::TestCase
13  
-  tests ForceSSLHTTPController
14  
-
15  
-  def test_banana_redirects_to_https
16  
-    get :two
17  
-    assert_response 301
18  
-    assert_equal "https://test.host/force_sslhttp/two", redirect_to_url
19  
-  end
20  
-end
19  actionpack/test/controller/http/redirect_to_test.rb
... ...
@@ -1,19 +0,0 @@
1  
-require 'abstract_unit'
2  
-
3  
-class RedirectToHTTPController < ActionController::HTTP
4  
-  def one
5  
-    redirect_to :action => "two"
6  
-  end
7  
-
8  
-  def two; end
9  
-end
10  
-
11  
-class RedirectToHTTPTest < ActionController::TestCase
12  
-  tests RedirectToHTTPController
13  
-
14  
-  def test_redirect_to
15  
-    get :one
16  
-    assert_response :redirect
17  
-    assert_equal "http://test.host/redirect_to_http/two", redirect_to_url
18  
-  end
19  
-end
37  actionpack/test/controller/http/renderers_test.rb
... ...
@@ -1,37 +0,0 @@
1  
-require 'abstract_unit'
2  
-
3  
-class Model
4  
-  def to_json(options = {})
5  
-    { :a => 'b' }.to_json(options)
6  
-  end
7  
-
8  
-  def to_xml(options = {})
9  
-    { :a => 'b' }.to_xml(options)
10  
-  end
11  
-end
12  
-
13  
-class RenderersHTTPController < ActionController::HTTP
14  
-  def one
15  
-    render :json => Model.new
16  
-  end
17  
-
18  
-  def two
19  
-    render :xml => Model.new
20  
-  end
21  
-end
22  
-
23  
-class RenderersHTTPTest < ActionController::TestCase
24  
-  tests RenderersHTTPController
25  
-
26  
-  def test_render_json
27  
-    get :one
28  
-    assert_response :success
29  
-    assert_equal({ :a => 'b' }.to_json, @response.body)
30  
-  end
31  
-
32  
-  def test_render_xml
33  
-    get :two
34  
-    assert_response :success
35  
-    assert_equal({ :a => 'b' }.to_xml, @response.body)
36  
-  end
37  
-end
20  actionpack/test/controller/http/url_for_test.rb
... ...
@@ -1,20 +0,0 @@
1  
-require 'abstract_unit'
2  
-
3  
-class UrlForHTTPController < ActionController::HTTP
4  
-  def one; end
5  
-  def two; end
6  
-end
7  
-
8  
-class UrlForHTTPTest < ActionController::TestCase
9  
-  tests UrlForHTTPController
10  
-
11  
-  def setup
12  
-    super
13  
-    @request.host = 'www.example.com'
14  
-  end
15  
-
16  
-  def test_url_for
17  
-    get :one
18  
-    assert_equal "http://www.example.com/url_for_http/one", @controller.url_for
19  
-  end
20  
-end
271  railties/guides/source/api_app.textile
Source Rendered
... ...
@@ -1,271 +0,0 @@
1  
-h2. Using Rails for API-only Apps
2  
-
3  
-In this guide you will learn:
4  
-
5  
-* What Rails provides for API-only applications
6  
-* How to configure Rails to start without any browser features
7  
-* How to decide which middlewares you will want to include
8  
-* How to decide which modules to use in your controller
9  
-
10  
-endprologue.
11  
-
12  
-h3. What is an API app?
13  
-
14  
-Traditionally, when people said that they used Rails as an "API", they meant providing a programmatically accessible API alongside their web application.
15  
-For example, GitHub provides "an API":http://developer.github.com that you can use from your own custom clients.
16  
-
17  
-With the advent of client-side frameworks, more developers are using Rails to build a backend that is shared between their web application and other native applications.
18  
-
19  
-For example, Twitter uses its "public API":https://dev.twitter.com in its web application, which is built as a static site that consumes JSON resources.
20  
-
21  
-Instead of using Rails to generate dynamic HTML that will communicate with the server through forms and links, many developers are treating their web application as just another client, delivered as static HTML, CSS and JavaScript, and consuming a simple JSON API
22  
-
23  
-This guide covers building a Rails application that serves JSON resources to an API client *or* client-side framework.
24  
-
25  
-h3. Why use Rails for JSON APIs?
26  
-
27  
-The first question a lot of people have when thinking about building a JSON API using Rails is: "isn't using Rails to spit out some JSON overkill? Shouldn't I just use something like Sinatra?"
28  
-
29  
-For very simple APIs, this may be true. However, even in very HTML-heavy applications, most of an application's logic is actually outside of the view layer.
30  
-
31  
-The reason most people use Rails is that it provides a set of defaults that allows us to get up and running quickly without having to make a lot of trivial decisions.
32  
-
33  
-Let's take a look at some of the things that Rails provides out of the box that are still applicable to API applications.
34  
-
35  
-Handled at the middleware layer:
36  
-
37  
-* Reloading: Rails applications support transparent reloading. This works even if your application gets big and restarting the server for every request becomes non-viable.
38  
-* Development Mode: Rails application come with smart defaults for development, making development pleasant without compromising production-time performance.
39  
-* Test Mode: Ditto test mode.
40  
-* Logging: Rails applications log every request, with a level of verbosity appropriate for the current mode. Rails logs in development include information about the request environment, database queries, and basic performance information.
41  
-* Security: Rails detects and thwarts "IP spoofing attacks":http://en.wikipedia.org/wiki/IP_address_spoofing and handles cryptographic signatures in a "timing attack":http://en.wikipedia.org/wiki/Timing_attack aware way. Don't know what an IP spoofing attack or a timing attack is? Exactly.
42  
-* Parameter Parsing: Want to specify your parameters as JSON instead of as a URL-encoded String? No problem. Rails will decode the JSON for you and make it available in +params+. Want to use nested URL-encoded params? That works too.
43  
-* Conditional GETs: Rails handles conditional +GET+, (+ETag+ and +Last-Modified+), processing request headers and returning the correct response headers and status code. All you need to do is use the "stale?":http://api.rubyonrails.org/classes/ActionController/ConditionalGet.html#method-i-stale-3F check in your controller, and Rails will handle all of the HTTP details for you.
44  
-* Caching: If you use +dirty?+ with public cache control, Rails will automatically cache your responses. You can easily configure the cache store.
45  
-* HEAD requests: Rails will transparently convert +HEAD+ requests into +GET+ requests, and return just the headers on the way out. This makes +HEAD+ work reliably in all Rails APIs.
46  
-
47  
-While you could obviously build these up in terms of existing Rack middlewares, I think this list demonstrates that the default Rails middleware stack provides a lot of value, even if you're "just generating JSON".
48  
-
49  
-Handled at the ActionPack layer:
50  
-
51  
-* Resourceful Routing: If you're building a RESTful JSON API, you want to be using the Rails router. Clean and conventional mapping from HTTP to controllers means not having to spend time thinking about how to model your API in terms of HTTP.
52  
-* URL Generation: The flip side of routing is URL generation. A good API based on HTTP includes URLs (see "the GitHub gist API":http://developer.github.com/v3/gists/ for an example).
53  
-* Header and Redirection Responses: +head :no_content+ and +redirect_to user_url(current_user)+ come in handy. Sure, you could manually add the response headers, but why?
54  
-* Caching: Rails provides page, action and fragment caching. Fragment caching is especially helpful when building up a nested JSON object.
55  
-* Basic, Digest and Token Authentication: Rails comes with out-of-the-box support for three kinds of HTTP authentication.
56  
-* Instrumentation: Rails 3.0 added an instrumentation API that will trigger registered handlers for a variety of events, such as action processing, sending a file or data, redirection, and database queries. The payload of each event comes with relevant information (for the action processing event, the payload includes the controller, action, params, request format, request method and the request's full path).
57  
-* Generators: This may be passé for advanced Rails users, but it can be nice to generate a resource and get your model, controller, test stubs, and routes created for you in a single command.
58  
-* Plugins: Many third-party libraries come with support for Rails that reduces or eliminates the cost of setting up and gluing together the library and the web framework. This includes things like overriding default generators, adding rake tasks, and honoring Rails choices (like the logger and cache backend).
59  
-
60  
-Of course, the Rails boot process also glues together all registered components. For example, the Rails boot process is what uses your +config/database.yml+ file when configuring ActiveRecord.
61  
-
62  
-**The short version is**: you may not have thought about which parts of Rails are still applicable even if you remove the view layer, but the answer turns out to be "most of it".
63  
-
64  
-h3. The Basic Configuration
65  
-
66  
-If you're building a Rails application that will be an API server first and foremost, you can start with a more limited subset of Rails and add in features as needed.
67  
-
68  
-You can generate a new bare Rails app:
69  
-
70  
-<shell>
71  
-$ rails new my_api --http
72  
-</shell>
73  
-
74  
-This will do three main things for you:
75  
-
76  
-* Configure your application to start with a more limited set of middleware than normal. Specifically, it will not include any middleware primarily useful for browser applications (like cookie support) by default.
77  
-* Make +ApplicationController+ inherit from +ActionController::HTTP+ instead of +ActionController::Base+. As with middleware, this will leave out any +ActionController+ modules that provide functionality primarily used by browser applications.
78  
-* Configure the generators to skip generating views, helpers and assets when you generate a new resource.
79  
-
80  
-If you want to take an existing app and make it an API app, follow the following steps.
81  
-
82  
-In +config/application.rb+ add the following lines at the top of the +Application+ class:
83  
-
84  
-<ruby>
85  
-config.middleware.http_only!
86  
-config.generators.http_only!
87  
-</ruby>
88  
-
89  
-Change +app/controllers/application_controller.rb+:
90  
-
91  
-<ruby>
92  
-# instead of
93  
-class ApplicationController < ActionController::Base
94  
-end
95  
-
96  
-# do
97  
-class ApplicationController < ActionController::HTTP
98  
-end
99  
-</ruby>
100  
-
101  
-h3. Choosing Middlewares
102  
-
103  
-An API application comes with the following middlewares by default.
104  
-
105  
-* +Rack::Cache+: Caches responses with public +Cache-Control+ headers using HTTP caching semantics. See below for more information.
106  
-* +Rack::Sendfile+: Uses a front-end server's file serving support from your Rails application.
107  
-* +Rack::Lock+: If your application is not marked as threadsafe (+config.threadsafe!+), this middleware will add a mutex around your requests.
108  
-* +ActionDispatch::RequestId+:
109  
-* +Rails::Rack::Logger+:
110  
-* +Rack::Runtime+: Adds a header to the response listing the total runtime of the request.
111  
-* +ActionDispatch::ShowExceptions+: Rescue exceptions and re-dispatch them to an exception handling application
112  
-* +ActionDispatch::DebugExceptions+: Log exceptions
113  
-* +ActionDispatch::RemoteIp+: Protect against IP spoofing attacks
114  
-* +ActionDispatch::Reloader+: In development mode, support code reloading.
115  
-* +ActionDispatch::ParamsParser+: Parse XML, YAML and JSON parameters when the request's +Content-Type+ is one of those.
116  
-* +ActionDispatch::Head+: Dispatch +HEAD+ requests as +GET+ requests, and return only the status code and headers.
117  
-* +Rack::ConditionalGet+: Supports the +stale?+ feature in Rails controllers.
118  
-* +Rack::ETag+: Automatically set an +ETag+ on all string responses. This means that if the same response is returned from a controller for the same URL, the server will return a +304 Not Modified+, even if no additional caching steps are taken. This is primarily a client-side optimization; it reduces bandwidth costs but not server processing time.
119  
-
120  
-Other plugins, including +ActiveRecord+, may add additional middlewares. In general, these middlewares are agnostic to the type of app you are building, and make sense in an API-only Rails application.
121  
-
122  
-You can get a list of all middlewares in your application via:
123  
-
124  
-<shell>
125  
-$ rake middleware
126  
-</shell>
127  
-
128  
-h4. Using Rack::Cache
129  
-
130  
-When used with Rails, +Rack::Cache+ uses the Rails cache store for its entity and meta stores. This means that if you use memcache, for your Rails app, for instance, the built-in HTTP cache will use memcache.
131  
-
132  
-To make use of +Rack::Cache+, you will want to use +stale?+ in your controller. Here's an example of +stale?+ in use.
133  
-
134  
-<ruby>
135  
-def show
136  
-  @post = Post.find(params[:id])
137  
-
138  
-  if stale?(:last_modified => @post.updated_at)
139  
-    render json: @post
140  
-  end
141  
-end
142  
-</ruby>
143  
-
144  
-The call to +stale?+ will compare the +If-Modified-Since+ header in the request with +@post.updated_at+. If the header is newer than the last modified, this action will return a +304 Not Modified+ response. Otherwise, it will render the response and include a +Last-Modified+ header with the response.
145  
-
146  
-Normally, this mechanism is used on a per-client basis. +Rack::Cache+ allows us to share this caching mechanism across clients. We can enable cross-client caching in the call to +stale?+
147  
-
148  
-<ruby>
149  
-def show
150  
-  @post = Post.find(params[:id])
151  
-
152  
-  if stale?(:last_modified => @post.updated_at, :public => true)
153  
-    render json: @post
154  
-  end
155  
-end
156  
-</ruby>
157  
-
158  
-This means that +Rack::Cache+ will store off +Last-Modified+ value for a URL in the Rails cache, and add an +If-Modified-Since+ header to any subsequent inbound requests for the same URL.
159  
-
160  
-Think of it as page caching using HTTP semantics.
161  
-
162  
-NOTE: The +Rack::Cache+ middleware is always outside of the +Rack::Lock+ mutex, even in single-threaded apps.
163  
-
164  
-h4. Using Rack::Sendfile
165  
-
166  
-When you use the +send_file+ method in a Rails controller, it sets the +X-Sendfile+ header. +Rack::Sendfile+ is responsible for actually sending the file.
167  
-
168  
-If your front-end server supports accelerated file sending, +Rack::Sendfile+ will offload the actual file sending work to the front-end server.
169  
-
170  
-You can configure the name of the header that your front-end server uses for this purposes using +config.action_dispatch.x_sendfile_header+ in the appropriate environment config file.
171  
-
172  
-You can learn more about how to use +Rack::Sendfile+ with popular front-ends in "the Rack::Sendfile documentation":http://rubydoc.info/github/rack/rack/master/Rack/Sendfile
173  
-
174  
-The values for popular servers once they are configured to support accelerated file sending:
175  
-
176  
-<ruby>
177  
-# Apache and lighttpd
178  
-config.action_dispatch.x_sendfile_header = "X-Sendfile"
179  
-
180  
-# nginx
181  
-config.action_dispatch.x_sendfile_header = "X-Accel-Redirect"
182  
-</ruby>
183  
-
184  
-Make sure to configure your server to support these options following the instructions in the +Rack::Sendfile+ documentation.
185  
-
186  
-NOTE: The +Rack::Sendfile+ middleware is always outside of the +Rack::Lock+ mutex, even in single-threaded apps.
187  
-
188  
-h4. Using ActionDispatch::ParamsParser
189  
-
190  
-+ActionDispatch::ParamsParser+ will take parameters from the client in JSON and make them available in your controller as +params+.
191  
-
192  
-To use this, your client will need to make a request with JSON-encoded parameters and specify the +Content-Type+ as +application/json+.
193  
-
194  
-Here's an example in jQuery:
195  
-
196  
-<plain>
197  
-jQuery.ajax({
198  
-  type: 'POST',
199  
-  url: '/people'
200  
-  dataType: 'json',
201  
-  contentType: 'application/json',
202  
-  data: JSON.stringify({ person: { firstName: "Yehuda", lastName: "Katz" } }),
203  
-
204  
-  success: function(json) { }
205  
-});
206  
-</plain>
207  
-
208  
-+ActionDispatch::ParamsParser+ will see the +Content-Type+ and your params will be +{ :person => { :firstName => "Yehuda", :lastName => "Katz" } }+.
209  
-
210  
-h4. Other Middlewares
211  
-
212  
-Rails ships with a number of other middlewares that you might want to use in an API app, especially if one of your API clients is the browser:
213  
-
214  
-* +Rack::MethodOverride+: Allows the use of the +_method+ hack to route POST requests to other verbs.
215  
-* +ActionDispatch::Cookies+: Supports the +cookie+ method in +ActionController+, including support for signed and encrypted cookies.
216  
-* +ActionDispatch::Flash+: Supports the +flash+ mechanism in +ActionController+.
217  
-* +ActionDispatch::BestStandards+: Tells Internet Explorer to use the most standards-compliant available renderer. In production mode, if ChromeFrame is available, use ChromeFrame.
218  
-* Session Management: If a +config.session_store+ is supplied, this middleware makes the session available as the +session+ method in +ActionController+.
219  
-
220  
-Any of these middlewares can be adding via:
221  
-
222  
-<ruby>
223  
-config.middleware.use Rack::MethodOverride
224  
-</ruby>
225  
-
226  
-h4. Removing Middlewares
227  
-
228  
-If you don't want to use a middleware that is included by default in the API-only middleware set, you can remove it using +config.middleware.delete+:
229  
-
230  
-<ruby>
231  
-config.middleware.delete ::Rack::Sendfile
232  
-</ruby>
233  
-
234  
-Keep in mind that removing these features may remove support for certain features in +ActionController+.
235  
-
236  
-h3. Choosing Controller Modules
237  
-
238  
-An API application (using +ActionController::HTTP+) comes with the following controller modules by default:
239  
-
240  
-* +ActionController::UrlFor+: Makes +url_for+ and friends available
241  
-* +ActionController::Redirecting+: Support for +redirect_to+
242  
-* +ActionController::Rendering+: Basic support for rendering
243  
-* +ActionController::Renderers::All+: Support for +render :json+ and friends
244  
-* +ActionController::ConditionalGet+: Support for +stale?+
245  
-* +ActionController::ForceSSL+: Support for +force_ssl+
246  
-* +ActionController::RackDelegation+: Support for the +request+ and +response+ methods returning +ActionDispatch::Request+ and +ActionDispatch::Response+ objects.
247  
-* +ActionController::DataStreaming+: Support for +send_file+ and +send_data+
248  
-* +AbstractController::Callbacks+: Support for +before_filter+ and friends
249  
-* +ActionController::Instrumentation+: Support for the instrumentation hooks defined by +ActionController+ (see "the source":https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/instrumentation.rb for more).
250  
-* +ActionController::Rescue+: Support for +rescue_from+.
251  
-
252  
-Other plugins may add additional modules. You can get a list of all modules included into +ActionController::HTTP+ in the rails console:
253  
-
254  
-<shell>
255  
-$ irb
256  
->> ActionController::HTTP.ancestors - ActionController::Metal.ancestors
257  
-</shell>
258  
-
259  
-h4. Adding Other Modules
260  
-
261  
-All ActionController modules know about their dependent modules, so you can feel free to include any modules into your controllers, and all dependencies will be included and set up as well.
262  
-
263  
-Some common modules you might want to add:
264  
-
265  
-* +AbstractController::Translation+: Support for the +l+ and +t+ localization and translation methods. These delegate to +I18n.translate+ and +I18n.localize+.
266  
-* +ActionController::HTTPAuthentication::Basic+ (or +Digest+ or +Token): Support for basic, digest or token HTTP authentication.
267  
-* +AbstractController::Layouts+: Support for layouts when rendering.
268  
-* +ActionController::MimeResponds+: Support for content negotiation (+respond_to+, +respond_with+).
269  
-* +ActionController::Cookies+: Support for +cookies+, which includes support for signed and encrypted cookies. This requires the cookie middleware.
270  
-
271  
-The best place to add a module is in your +ApplicationController+. You can also add modules to individual controllers.
20  railties/lib/rails/configuration.rb
@@ -6,20 +6,6 @@
6 6
 
7 7
 module Rails
8 8
   module Configuration
9  
-    module HttpOnly #:nodoc:
10  
-      def initialize
11  
-        @http_only = false
12  
-      end
13  
-
14  
-      def http_only!
15  
-        @http_only = true
16  
-      end
17  
-
18  
-      def http_only?
19  
-        @http_only
20  
-      end
21  
-    end
22  
-
23 9
     # MiddlewareStackProxy is a proxy for the Rails middleware stack that allows
24 10
     # you to configure middlewares in your application. It works basically as a
25 11
     # command recorder, saving each command to be applied after initialization
@@ -58,10 +44,7 @@ def http_only?
58 44
     # Cookies, Session and Flash, BestStandardsSupport, and MethodOverride. You
59 45
     # can always add any of them later manually if you want.
60 46
     class MiddlewareStackProxy
61  
-      include HttpOnly
62  
-
63 47
       def initialize
64  
-        super
65 48
         @operations = []
66 49
       end
67 50
 
@@ -99,10 +82,7 @@ class Generators #:nodoc:
99 82
       attr_accessor :aliases, :options, :templates, :fallbacks, :colorize_logging
100 83
       attr_reader :hidden_namespaces
101 84
 
102  
-      include HttpOnly
103  
-
104 85
       def initialize
105  
-        super
106 86
         @aliases = Hash.new { |h,k| h[k] = {} }
107 87
         @options = Hash.new { |h,k| h[k] = {} }
108 88
         @fallbacks = {}
23  railties/lib/rails/generators.rb
@@ -46,7 +46,6 @@ module Generators
46 46
         :assets => true,
47 47
         :force_plural => false,
48 48
         :helper => true,
49  
-        :http => false,
50 49
         :integration_tool => nil,
51 50
         :javascripts => true,
52 51
         :javascript_engine => :js,
@@ -62,7 +61,6 @@ module Generators
62 61
     }
63 62
 
64 63
     def self.configure!(config) #:nodoc:
65  
-      http_only! if config.http_only?
66 64
       no_color! unless config.colorize_logging
67 65
       aliases.deep_merge! config.aliases
68 66
       options.deep_merge! config.options
@@ -72,7 +70,7 @@ def self.configure!(config) #:nodoc:
72 70
       hide_namespaces(*config.hidden_namespaces)
73 71
     end
74 72
 
75  
-    def self.templates_path
  73
+    def self.templates_path #:nodoc:
76 74
       @templates_path ||= []
77 75
     end
78 76
 
@@ -106,25 +104,6 @@ def self.no_color!
106 104
       Thor::Base.shell = Thor::Shell::Basic
107 105
     end
108 106
 
109  
-    # Configure generators for http only applications. It basically hides
110  
-    # everything that is usually browser related, such as assets and session
111  
-    # migration generators, and completely disable views, helpers and assets
112  
-    # so generators such as scaffold won't create them.
113  
-    def self.http_only!
114  
-      hide_namespaces "assets", "css", "js", "session_migration"
115  
-
116  
-      options[:rails].merge!(
117  
-        :assets => false,
118  
-        :helper => false,
119  
-        :http => true,
120  
-        :javascripts => false,
121  
-        :javascript_engine => nil,
122  
-        :stylesheets => false,
123  
-        :stylesheet_engine => nil,
124  
-        :template_engine => nil
125  
-      )
126  
-    end
127  
-
128 107
     # Track all generators subclasses.
129 108
     def self.subclasses
130 109
       @subclasses ||= []
8  railties/lib/rails/generators/rails/app/app_generator.rb
@@ -144,9 +144,6 @@ module Generators
144 144
     class AppGenerator < AppBase
145 145
       add_shared_options_for "application"
146 146
 
147  
-      class_option :http, :type => :boolean, :default => false,
148  
-                          :desc => "Preconfigure smaller stack for HTTP only apps"
149  
-
150 147
       # Add bin/rails options
151 148
       class_option :version, :type => :boolean, :aliases => "-v", :group => :rails,
152 149
                              :desc => "Show Rails version number and quit"
@@ -159,10 +156,6 @@ def initialize(*args)
159 156
         if !options[:skip_active_record] && !DATABASES.include?(options[:database])
160 157
           raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
161 158
         end
162  
-
163  
-        # Force sprockets to be skipped when generating http only app.
164  
-        # Can't modify options hash as it's frozen by default.
165  
-        self.options = options.merge(:skip_sprockets => true).freeze if options.http?
166 159
       end
167 160
 
168 161
       public_task :create_root
@@ -177,7 +170,6 @@ def create_root_files
177 170
 
178 171
       def create_app_files
179 172
         build(:app)
180  
-        remove_file("app/views") if options.http?
181 173
       end
182 174
 
183 175
       def create_config_files
6  railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt
... ...
@@ -1,5 +1,5 @@
1  
-class ApplicationController < ActionController::<%= options.http? ? "HTTP" : "Base" %>
  1
+class ApplicationController < ActionController::Base
2 2
   # Prevent CSRF attacks by raising an exception.
3 3
   # For APIs, you may want to use :reset_session instead.
4  
-  <%= comment_if :http %>protect_from_forgery :with => :exception
5  
-end
  4
+  protect_from_forgery :with => :exception
  5
+end
9  railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -67,14 +67,5 @@ class Application < Rails::Application
67 67
     # Version of your assets, change this if you want to expire all your assets.
68 68
     config.assets.version = '1.0'
69 69
 <% end -%>
70  
-<% if options.http? -%>
71  
-
72  
-    # Only loads a smaller set of middleware suitable for HTTP only apps.
73  
-    # Middleware like session, flash, cookies can be added back manually.
74  
-    config.middleware.http_only!
75  
-
76  
-    # Skip views, helpers and assets when generating a new resource.
77  
-    config.generators.http_only!
78  
-<% end -%>
79 70
   end
80 71
 end
1  railties/lib/rails/generators/rails/resource/resource_generator.rb
@@ -21,7 +21,6 @@ def add_resource_route
21 21
         return if options[:actions].present?
22 22
         route_config =  regular_class_path.collect{ |namespace| "namespace :#{namespace} do " }.join(" ")
23 23
         route_config << "resources :#{file_name.pluralize}"
24  
-        route_config << ", except: :edit" if options.http?
25 24
         route_config << " end" * regular_class_path.size
26 25
         route route_config
27 26
       end
3  railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
@@ -14,8 +14,7 @@ class ScaffoldControllerGenerator < NamedBase
14 14
                           :desc => "Generate controller with HTTP actions only"
15 15
 
16 16
       def create_controller_files
17  
-        template_file = options.http? ? "http_controller.rb" : "controller.rb"
18  
-        template template_file, File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb")
  17
+        template "controller.rb", File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb")
19 18
       end
20 19
 
21 20
       hook_for :template_engine, :test_framework, :as => :scaffold
60  railties/lib/rails/generators/rails/scaffold_controller/templates/http_controller.rb
... ...
@@ -1,60 +0,0 @@
1  
-<% module_namespacing do -%>
2  
-class <%= controller_class_name %>Controller < ApplicationController
3  
-  # GET <%= route_url %>
4  
-  # GET <%= route_url %>.json
5  
-  def index
6  
-    @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
7  
-
8  
-    render json: @<%= plural_table_name %>
9  
-  end
10  
-
11  
-  # GET <%= route_url %>/1
12  
-  # GET <%= route_url %>/1.json
13  
-  def show
14  
-    @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
15  
-
16  
-    render json: @<%= singular_table_name %>
17  
-  end
18  
-
19  
-  # GET <%= route_url %>/new
20  
-  # GET <%= route_url %>/new.json
21  
-  def new
22  
-    @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
23  
-
24  
-    render json: @<%= singular_table_name %>
25  
-  end
26  
-
27  
-  # POST <%= route_url %>
28  
-  # POST <%= route_url %>.json
29  
-  def create
30  
-    @<%= singular_table_name %> = <%= orm_class.build(class_name, "params[:#{singular_table_name}]") %>
31  
-
32  
-    if @<%= orm_instance.save %>
33  
-      render json: @<%= singular_table_name %>, status: :created, location: @<%= singular_table_name %>
34  
-    else
35  
-      render json: @<%= orm_instance.errors %>, status: :unprocessable_entity
36  
-    end
37  
-  end
38  
-
39  
-  # PATCH/PUT <%= route_url %>/1
40  
-  # PATCH/PUT <%= route_url %>/1.json
41  
-  def update
42  
-    @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
43  
-
44  
-    if @<%= orm_instance.update_attributes("params[:#{singular_table_name}]") %>
45  
-      head :no_content
46  
-    else
47  
-      render json: @<%= orm_instance.errors %>, status: :unprocessable_entity
48  
-    end
49  
-  end
50  
-
51  
-  # DELETE <%= route_url %>/1
52  
-  # DELETE <%= route_url %>/1.json
53  
-  def destroy
54  
-    @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
55  
-    @<%= orm_instance.destroy %>
56  
-
57  
-    head :no_content
58  
-  end
59  
-end
60  
-<% end -%>
6  railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
@@ -14,10 +14,8 @@ class ScaffoldGenerator < Base
14 14
                           :desc => "Generate functional test with HTTP actions only"
15 15
 
16 16
       def create_test_files
17  
-        template_file = options.http? ? "http_functional_test.rb" : "functional_test.rb"
18  
-
19  
-        template template_file,
20  
-                 File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb")
  17
+        template "functional_test.rb",
  18
+                 File.join("test/functional", controller_class_path, "#{controller_file_name}_controller_test.rb")
21 19
       end
22 20
 
23 21
       private
50  railties/lib/rails/generators/test_unit/scaffold/templates/http_functional_test.rb
... ...
@@ -1,50 +0,0 @@
1  
-require 'test_helper'
2  
-
3  
-<% module_namespacing do -%>
4  
-class <%= controller_class_name %>ControllerTest < ActionController::TestCase
5  
-  setup do
6  
-    @<%= singular_table_name %> = <%= table_name %>(:one)
7  
-    @request.accept = "application/json"
8  
-  end
9  
-
10  
-  test "should get index" do
11  
-    get :index
12  
-    assert_response :success
13  
-    assert_not_nil assigns(:<%= table_name %>)
14  
-  end
15  
-
16  
-  test "should get new" do
17  
-    get :new
18  
-    assert_response :success
19  
-  end
20  
-
21  
-  test "should create <%= singular_table_name %>" do
22  
-    assert_difference('<%= class_name %>.count') do
23  
-      post :create, <%= "#{singular_table_name}: { #{attributes_hash} }" %>
24  
-    end
25  
-
26  
-    assert_response 201
27  
-    assert_not_nil assigns(:<%= singular_table_name %>)
28  
-  end
29  
-
30  
-  test "should show <%= singular_table_name %>" do
31  
-    get :show, id: @<%= singular_table_name %>
32  
-    assert_response :success
33  
-  end
34  
-
35  
-  test "should update <%= singular_table_name %>" do
36  
-    put :update, id: @<%= singular_table_name %>, <%= "#{singular_table_name}: { #{attributes_hash} }" %>
37  
-    assert_response 204
38  
-    assert_not_nil assigns(:<%= singular_table_name %>)
39  
-  end
40  
-
41  
-  test "should destroy <%= singular_table_name %>" do
42  
-    assert_difference('<%= class_name %>.count', -1) do
43  
-      delete :destroy, id: @<%= singular_table_name %>
44  
-    end
45  
-
46  
-    assert_response 204
47  
-    assert_not_nil assigns(:<%= singular_table_name %>)
48  
-  end
49  
-end
50  
-<% end -%>
28  railties/test/application/generators_test.rb
@@ -125,33 +125,5 @@ def with_bare_config
125 125
         assert_equal expected, c.generators.options
126 126
       end
127 127
     end
128  
-
129  
-    test "http only disables options from generators" do
130  
-      add_to_config <<-RUBY
131  
-        config.generators.http_only!
132  
-      RUBY
133  
-
134  
-      # Initialize the application
135  
-      require "#{app_path}/config/environment"
136  
-      Rails.application.load_generators
137  
-
138  
-      assert !Rails::Generators.options[:rails][:template_engine],
139  
-        "http only should have disabled generator options"
140  
-    end
141  
-
142  
-    test "http only allow overriding generators options" do
143  
-      add_to_config <<-RUBY
144  
-        config.generators.helper = true
145  
-        config.generators.http_only!
146  
-        config.generators.template_engine = :my_template
147  
-      RUBY
148  
-
149  
-      # Initialize the application
150  
-      require "#{app_path}/config/environment"
151  
-      Rails.application.load_generators
152  
-
153  
-      assert_equal :my_template, Rails::Generators.options[:rails][:template_engine]
154  
-      assert_equal true, Rails::Generators.options[:rails][:helper]
155  
-    end
156 128
   end
157 129
 end
27  railties/test/application/initializers/frameworks_test.rb
@@ -130,33 +130,6 @@ def from_bar_helper
130 130
       assert_equal "false", last_response.body
131 131
     end
132 132
 
133  
-    test "action_controller http initializes successfully" do
134  
-      app_file "app/controllers/application_controller.rb", <<-RUBY
135  
-        class ApplicationController < ActionController::HTTP
136  
-        end
137  
-      RUBY
138  
-
139  
-      app_file "app/controllers/omg_controller.rb", <<-RUBY
140  
-        class OmgController < ApplicationController
141  
-          def show
142  
-            render :json => { :omg => 'omg' }
143  
-          end
144  
-        end
145  
-      RUBY
146  
-
147  
-      app_file "config/routes.rb", <<-RUBY
148  
-        AppTemplate::Application.routes.draw do
149  
-          match "/:controller(/:action)"
150  
-        end
151  
-      RUBY
152  
-
153  
-      require 'rack/test'
154  
-      extend Rack::Test::Methods
155  
-
156  
-      get '/omg/show'
157  
-      assert_equal '{"omg":"omg"}', last_response.body
158  
-    end
159  
-
160 133
     # AD
161 134
     test "action_dispatch extensions are applied to ActionDispatch" do
162 135
       add_to_config "config.action_dispatch.tld_length = 2"
30  railties/test/application/middleware_test.rb
@@ -52,36 +52,6 @@ def app
52 52
       ], middleware
53 53
     end
54 54
 
55  
-    test "http only middleware stack" do
56  
-      add_to_config "config.middleware.http_only!"
57  
-      add_to_config "config.force_ssl = true"
58  
-      add_to_config "config.action_dispatch.x_sendfile_header = 'X-Sendfile'"
59  
-
60  
-      boot!
61  
-
62  
-      assert_equal [
63  
-        "Rack::SSL",
64  
-        "Rack::Sendfile",
65  
-        "ActionDispatch::Static",
66  
-        "Rack::Lock",
67  
-        "ActiveSupport::Cache::Strategy::LocalCache",
68  
-        "Rack::Runtime",
69  
-        "ActionDispatch::RequestId",
70  
-        "Rails::Rack::Logger",
71  
-        "ActionDispatch::ShowExceptions",
72  
-        "ActionDispatch::DebugExceptions",
73  
-        "ActionDispatch::RemoteIp",
74  
-        "ActionDispatch::Reloader",
75  
-        "ActionDispatch::Callbacks",
76  
-        "ActiveRecord::ConnectionAdapters::ConnectionManagement",
77  
-        "ActiveRecord::QueryCache",
78  
-        "ActionDispatch::ParamsParser",
79  
-        "ActionDispatch::Head",
80  
-        "Rack::ConditionalGet",
81  
-        "Rack::ETag"
82  
-      ], middleware
83  
-    end
84  
-
85 55
     test "Rack::Sendfile is not included by default" do
86 56
       boot!
87 57
 
20 