rest-core 2.1.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.gitignore +1 -2
 - data/.travis.yml +3 -5
 - data/CHANGES.md +65 -5
 - data/Gemfile +10 -5
 - data/NOTE.md +1 -1
 - data/README.md +194 -128
 - data/Rakefile +8 -34
 - data/TODO.md +3 -2
 - data/example/simple.rb +6 -4
 - data/example/use-cases.rb +39 -122
 - data/lib/rest-core.rb +14 -5
 - data/lib/rest-core/builder.rb +12 -2
 - data/lib/rest-core/client.rb +31 -25
 - data/lib/rest-core/engine.rb +39 -0
 - data/lib/rest-core/engine/http-client.rb +41 -0
 - data/lib/rest-core/engine/net-http-persistent.rb +21 -0
 - data/lib/rest-core/engine/rest-client.rb +13 -42
 - data/lib/rest-core/event_source.rb +91 -0
 - data/lib/rest-core/middleware.rb +17 -11
 - data/lib/rest-core/middleware/error_detector.rb +1 -6
 - data/lib/rest-core/middleware/oauth1_header.rb +1 -0
 - data/lib/rest-core/middleware/oauth2_header.rb +20 -8
 - data/lib/rest-core/middleware/oauth2_query.rb +1 -0
 - data/lib/rest-core/middleware/timeout.rb +5 -19
 - data/lib/rest-core/promise.rb +137 -0
 - data/lib/rest-core/test.rb +2 -43
 - data/lib/rest-core/thread_pool.rb +122 -0
 - data/lib/rest-core/timer.rb +30 -0
 - data/lib/rest-core/util/hmac.rb +0 -8
 - data/lib/rest-core/version.rb +1 -1
 - data/lib/rest-core/wrapper.rb +1 -1
 - data/rest-core.gemspec +36 -25
 - data/task/README.md +54 -0
 - data/task/gemgem.rb +150 -156
 - data/test/test_builder.rb +2 -2
 - data/test/test_cache.rb +8 -8
 - data/test/test_client.rb +16 -6
 - data/test/test_client_oauth1.rb +1 -1
 - data/test/test_event_source.rb +77 -0
 - data/test/test_follow_redirect.rb +1 -1
 - data/test/test_future.rb +16 -0
 - data/test/test_oauth2_header.rb +28 -0
 - data/test/test_promise.rb +89 -0
 - data/test/test_rest-client.rb +21 -0
 - data/test/test_thread_pool.rb +10 -0
 - data/test/test_timeout.rb +13 -8
 - metadata +61 -37
 - data/example/multi.rb +0 -44
 - data/lib/rest-core/engine/auto.rb +0 -25
 - data/lib/rest-core/engine/em-http-request.rb +0 -90
 - data/lib/rest-core/engine/future/future.rb +0 -107
 - data/lib/rest-core/engine/future/future_fiber.rb +0 -32
 - data/lib/rest-core/engine/future/future_thread.rb +0 -29
 - data/lib/rest-core/middleware/timeout/timer_em.rb +0 -26
 - data/lib/rest-core/middleware/timeout/timer_thread.rb +0 -36
 - data/task/.gitignore +0 -1
 - data/test/test_em-http-request.rb +0 -186
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 58ed90f247d23da6267042bf108e50637e8dba98
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: a0d0b5f7dd766fee5426fc0faf5c5d0dd6adb229
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: a45a9c11e364a08414a7e583feedbe3a289a59fba42aa8d0180e0144e91279b7a77662737c489ec466402a72db4a2833f9e674ad27954d93e325e33713f4766d
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 3f3b2e09cd1131543a677e9a61cf4872c70fb272aad936eccd0f005d6490646b6589e0128ffd33f6107b644c77ef772a34f6433bd6c3d37fffe0aa1a53b72010
         
     | 
    
        data/.gitignore
    CHANGED
    
    | 
         @@ -1,2 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            pkg
         
     | 
| 
       2 
     | 
    
         
            -
            *.rbc
         
     | 
| 
      
 1 
     | 
    
         
            +
            /pkg/
         
     | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/CHANGES.md
    CHANGED
    
    | 
         @@ -1,5 +1,65 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # CHANGES
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## rest-core 3.0.0 -- ?
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Highlights:
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * Hijack for streaming responses
         
     | 
| 
      
 8 
     | 
    
         
            +
            * EventSource for SSE (server-sent events)
         
     | 
| 
      
 9 
     | 
    
         
            +
            * Thread pool
         
     | 
| 
      
 10 
     | 
    
         
            +
            * Keep-alive connections from httpclient
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            ### Incompatible changes
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            * Since eventmachine is buggy, and fibers without eventmachine doesn't make
         
     | 
| 
      
 15 
     | 
    
         
            +
              too much sense, we have removed the support for eventmachine and fibers.
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            * We also changed the default HTTP client from rest-client to httpclient.
         
     | 
| 
      
 18 
     | 
    
         
            +
              If you still want to use rest-client, switch it like this:
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  RC::Builder.default_engine = RC::RestClient
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              Be warned, we might remove rest-client support in the future.
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            * `RC::Client#options` would now return the headers instead of response body.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            * Removed support for Ruby 1.8.7 without openssl installed.
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            * `RC::Future` is renamed to `RC::Promise`, and `RC::Future::Proxy` is
         
     | 
| 
      
 29 
     | 
    
         
            +
              renamed to `RC::Promise::Future`.
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ### Enhancement
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            * HIJACK support, which is similar to Rack's HIJACK feature. If you're
         
     | 
| 
      
 34 
     | 
    
         
            +
              passing `{RC::HIJACK => true}` whenever making a request, rest-core would
         
     | 
| 
      
 35 
     | 
    
         
            +
              rather set the `RC::RESPONSE_BODY` as an empty string, and set
         
     | 
| 
      
 36 
     | 
    
         
            +
              `RC::RESPONSE_SOCKET` as a socket for the response. This is used for
         
     | 
| 
      
 37 
     | 
    
         
            +
              `RC::EventSource`, and you could also use this for streaming the response.
         
     | 
| 
      
 38 
     | 
    
         
            +
              Note that this only works for default engine, httpclient.
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            * Introduce `RC::EventSource`. You could obtain the object via
         
     | 
| 
      
 41 
     | 
    
         
            +
              `RC::Client#event_source`, and then setup `onopen`, `onmessage`, and
         
     | 
| 
      
 42 
     | 
    
         
            +
              `onerror` respectively, and then call `RC::EventSource#start` to begin
         
     | 
| 
      
 43 
     | 
    
         
            +
              making the request, and receive the SSE (sever-sent events) from the server.
         
     | 
| 
      
 44 
     | 
    
         
            +
              This is used in `RC::Firebase` from rest-more.
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            * Now we have thread pool support. We could set the pool size with:
         
     | 
| 
      
 47 
     | 
    
         
            +
              `RC::YourClient.pool_size = 10` and thread idle time with:
         
     | 
| 
      
 48 
     | 
    
         
            +
              `RC::YourClient.pool_idle_time = 60`. By default, `pool_size` is 0
         
     | 
| 
      
 49 
     | 
    
         
            +
              which means we don't use a thread pool. Setting it to a negative number
         
     | 
| 
      
 50 
     | 
    
         
            +
              would mean do not spawn any threads, just make a blocking request.
         
     | 
| 
      
 51 
     | 
    
         
            +
              `pool_idle_time` is default to 60, meaning an idle thread would be shut
         
     | 
| 
      
 52 
     | 
    
         
            +
              down after 60 seconds without being used.
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            * Since we're now using httpclient by default, we should also take the
         
     | 
| 
      
 55 
     | 
    
         
            +
              advantage of using keep-alive connections for the same host.
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            * Now `RC::Middleware#fail` and `RC::Middleware#log` could accept `nil` as
         
     | 
| 
      
 58 
     | 
    
         
            +
              an input, which would then do nothing. This could much simplify the code
         
     | 
| 
      
 59 
     | 
    
         
            +
              building middleware.
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            * Now we're using timers gem which should be less buggy from previous timeout.
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
       3 
63 
     | 
    
         
             
            ## rest-core 2.1.2 -- 2013-05-31
         
     | 
| 
       4 
64 
     | 
    
         | 
| 
       5 
65 
     | 
    
         
             
            ### Incompatible changes
         
     | 
| 
         @@ -160,7 +220,7 @@ It's a bit outdated, but you can also checkout my blog post. 
     | 
|
| 
       160 
220 
     | 
    
         
             
            [rest-core 2.0 roadmap, thunk based response][post]
         
     | 
| 
       161 
221 
     | 
    
         
             
            (p.s. now thunk is renamed to future)
         
     | 
| 
       162 
222 
     | 
    
         | 
| 
       163 
     | 
    
         
            -
            [use-cases.rb]: https://github.com/ 
     | 
| 
      
 223 
     | 
    
         
            +
            [use-cases.rb]: https://github.com/godfat/rest-core/blob/master/example/use-cases.rb
         
     | 
| 
       164 
224 
     | 
    
         
             
            [post]: http://blogger.godfat.org/2012/06/rest-core-20-roadmap-thunk-based.html
         
     | 
| 
       165 
225 
     | 
    
         | 
| 
       166 
226 
     | 
    
         
             
            ### Incompatible changes
         
     | 
| 
         @@ -263,8 +323,8 @@ This is a very significant release. The most important change is now we 
     | 
|
| 
       263 
323 
     | 
    
         
             
            support asynchronous requests, by either passing a callback block or using
         
     | 
| 
       264 
324 
     | 
    
         
             
            fibers in Ruby 1.9 to make the whole program still look synchronous.
         
     | 
| 
       265 
325 
     | 
    
         | 
| 
       266 
     | 
    
         
            -
            Please read [README.md](https://github.com/ 
     | 
| 
       267 
     | 
    
         
            -
            or [example](https://github.com/ 
     | 
| 
      
 326 
     | 
    
         
            +
            Please read [README.md](https://github.com/godfat/rest-core/blob/master/README.md)
         
     | 
| 
      
 327 
     | 
    
         
            +
            or [example](https://github.com/godfat/rest-core/tree/master/example)
         
     | 
| 
       268 
328 
     | 
    
         
             
            for more detail.
         
     | 
| 
       269 
329 
     | 
    
         | 
| 
       270 
330 
     | 
    
         
             
            * [`Client`] Client#inspect is fixed for clients which do not have any
         
     | 
| 
         @@ -472,7 +532,7 @@ others are moved to [rest-more][]. Since bundler didn't like cyclic 
     | 
|
| 
       472 
532 
     | 
    
         
             
            dependency, so rest-core is not depending on rest-more. Please install
         
     | 
| 
       473 
533 
     | 
    
         
             
            _rest-more_ if you want to use them.
         
     | 
| 
       474 
534 
     | 
    
         | 
| 
       475 
     | 
    
         
            -
            [rest-more]: https://github.com/ 
     | 
| 
      
 535 
     | 
    
         
            +
            [rest-more]: https://github.com/godfat/rest-more
         
     | 
| 
       476 
536 
     | 
    
         | 
| 
       477 
537 
     | 
    
         
             
            ## rest-core 0.4.0 -- 2011-09-26
         
     | 
| 
       478 
538 
     | 
    
         | 
| 
         @@ -563,7 +623,7 @@ _rest-more_ if you want to use them. 
     | 
|
| 
       563 
623 
     | 
    
         
             
                    twitter:
         
     | 
| 
       564 
624 
     | 
    
         
             
                      consumer_key: abc
         
     | 
| 
       565 
625 
     | 
    
         | 
| 
       566 
     | 
    
         
            -
            [rest-graph]: https://github.com/ 
     | 
| 
      
 626 
     | 
    
         
            +
            [rest-graph]: https://github.com/godfat/rest-graph
         
     | 
| 
       567 
627 
     | 
    
         | 
| 
       568 
628 
     | 
    
         
             
            ## rest-core 0.2.3 -- 2011-08-27
         
     | 
| 
       569 
629 
     | 
    
         | 
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -4,11 +4,10 @@ source 'https://rubygems.org/' 
     | 
|
| 
       4 
4 
     | 
    
         
             
            gemspec
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            gem 'rest-client'
         
     | 
| 
       7 
     | 
    
         
            -
            gem 'em-http-request'
         
     | 
| 
       8 
7 
     | 
    
         | 
| 
       9 
8 
     | 
    
         
             
            gem 'rake'
         
     | 
| 
       10 
9 
     | 
    
         
             
            gem 'bacon'
         
     | 
| 
       11 
     | 
    
         
            -
            gem ' 
     | 
| 
      
 10 
     | 
    
         
            +
            gem 'muack'
         
     | 
| 
       12 
11 
     | 
    
         
             
            gem 'webmock'
         
     | 
| 
       13 
12 
     | 
    
         | 
| 
       14 
13 
     | 
    
         
             
            gem 'json'
         
     | 
| 
         @@ -16,12 +15,18 @@ gem 'json_pure' 
     | 
|
| 
       16 
15 
     | 
    
         
             
            gem 'multi_json'
         
     | 
| 
       17 
16 
     | 
    
         | 
| 
       18 
17 
     | 
    
         
             
            gem 'rack'
         
     | 
| 
       19 
     | 
    
         
            -
            gem 'ruby-hmac'
         
     | 
| 
       20 
18 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
            platforms 
     | 
| 
      
 19 
     | 
    
         
            +
            platforms :ruby do
         
     | 
| 
       22 
20 
     | 
    
         
             
              gem 'yajl-ruby'
         
     | 
| 
       23 
21 
     | 
    
         
             
            end
         
     | 
| 
       24 
22 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
            platforms 
     | 
| 
      
 23 
     | 
    
         
            +
            platforms :rbx do
         
     | 
| 
      
 24 
     | 
    
         
            +
              gem 'rubysl-weakref'    # used in rest-core
         
     | 
| 
      
 25 
     | 
    
         
            +
              gem 'rubysl-singleton'  # used in rake
         
     | 
| 
      
 26 
     | 
    
         
            +
              gem 'rubysl-rexml'      # used in crack used in webmock
         
     | 
| 
      
 27 
     | 
    
         
            +
              gem 'rubysl-bigdecimal' # used in crack used in webmock
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            platforms :jruby do
         
     | 
| 
       26 
31 
     | 
    
         
             
              gem 'jruby-openssl'
         
     | 
| 
       27 
32 
     | 
    
         
             
            end
         
     | 
    
        data/NOTE.md
    CHANGED
    
    | 
         @@ -43,6 +43,6 @@ and use that along with pre-built ones to compose a very customized client. 
     | 
|
| 
       43 
43 
     | 
    
         | 
| 
       44 
44 
     | 
    
         
             
            We present you rest-core.
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
            [rest-core]: https://github.com/ 
     | 
| 
      
 46 
     | 
    
         
            +
            [rest-core]: https://github.com/godfat/rest-core
         
     | 
| 
       47 
47 
     | 
    
         
             
            [Rack]: https://github.com/rack/rack
         
     | 
| 
       48 
48 
     | 
    
         
             
            [Faraday]: https://github.com/technoweenie/faraday
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # rest-core [](http://travis-ci.org/godfat/rest-core)
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            by  
     | 
| 
      
 3 
     | 
    
         
            +
            by Lin Jen-Shin ([godfat](http://godfat.org))
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            Lin Jen-Shin ([godfat][]) had given a talk about rest-core on
         
     | 
| 
       6 
6 
     | 
    
         
             
            [RubyConf Taiwan 2011][talk]. The slide is in English, but the
         
     | 
| 
         @@ -11,9 +11,9 @@ talk is in Mandarin. 
     | 
|
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            ## LINKS:
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
            * [github](https://github.com/ 
     | 
| 
      
 14 
     | 
    
         
            +
            * [github](https://github.com/godfat/rest-core)
         
     | 
| 
       15 
15 
     | 
    
         
             
            * [rubygems](https://rubygems.org/gems/rest-core)
         
     | 
| 
       16 
     | 
    
         
            -
            * [rdoc](http://rdoc.info/projects/ 
     | 
| 
      
 16 
     | 
    
         
            +
            * [rdoc](http://rdoc.info/projects/godfat/rest-core)
         
     | 
| 
       17 
17 
     | 
    
         
             
            * [mailing list](http://groups.google.com/group/rest-core/topics)
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
19 
     | 
    
         
             
            ## DESCRIPTION:
         
     | 
| 
         @@ -27,28 +27,36 @@ that allows you to build a REST client for any REST API. Or in the case of 
     | 
|
| 
       27 
27 
     | 
    
         
             
            common APIs such as Facebook, Github, and Twitter, you can simply use the
         
     | 
| 
       28 
28 
     | 
    
         
             
            dedicated clients provided by [rest-more][].
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
            [rest-more]: https://github.com/ 
     | 
| 
      
 30 
     | 
    
         
            +
            [rest-more]: https://github.com/godfat/rest-more
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
            ## FEATURES:
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
            * Modular interface for REST clients similar to WSGI/Rack for servers.
         
     | 
| 
       35 
35 
     | 
    
         
             
            * Concurrent requests with synchronous or asynchronous interfaces with
         
     | 
| 
       36 
     | 
    
         
            -
               
     | 
| 
      
 36 
     | 
    
         
            +
              threads.
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            ## WHY?
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            Build your own API clients for less dependencies, less codes,
         
     | 
| 
      
 41 
     | 
    
         
            +
            less memory, less conflicts, and run faster.
         
     | 
| 
       37 
42 
     | 
    
         | 
| 
       38 
43 
     | 
    
         
             
            ## REQUIREMENTS:
         
     | 
| 
       39 
44 
     | 
    
         | 
| 
       40 
45 
     | 
    
         
             
            ### Mandatory:
         
     | 
| 
       41 
46 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
            * MRI (official CRuby) 
     | 
| 
       43 
     | 
    
         
            -
            * gem  
     | 
| 
      
 47 
     | 
    
         
            +
            * Tested with MRI (official CRuby), Rubinius and JRuby.
         
     | 
| 
      
 48 
     | 
    
         
            +
            * gem [httpclient][]
         
     | 
| 
      
 49 
     | 
    
         
            +
            * gem [mime-types][]
         
     | 
| 
      
 50 
     | 
    
         
            +
            * gem [timers][]
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            [httpclient]: https://github.com/nahi/httpclient
         
     | 
| 
      
 53 
     | 
    
         
            +
            [mime-types]: https://github.com/halostatue/mime-types
         
     | 
| 
      
 54 
     | 
    
         
            +
            [timers]: https://github.com/celluloid/timers
         
     | 
| 
       44 
55 
     | 
    
         | 
| 
       45 
56 
     | 
    
         
             
            ### Optional:
         
     | 
| 
       46 
57 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
            * gem [em-http-request][] (if using eventmachine)
         
     | 
| 
       48 
58 
     | 
    
         
             
            * gem json or yajl-ruby, or multi_json (if `JsonResponse` or
         
     | 
| 
       49 
     | 
    
         
            -
              `JsonRequest`  
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
            [em-http-request]: https://github.com/igrigorik/em-http-request
         
     | 
| 
      
 59 
     | 
    
         
            +
              `JsonRequest` middleware is used)
         
     | 
| 
       52 
60 
     | 
    
         | 
| 
       53 
61 
     | 
    
         
             
            ## INSTALLATION:
         
     | 
| 
       54 
62 
     | 
    
         | 
| 
         @@ -59,14 +67,14 @@ gem install rest-core 
     | 
|
| 
       59 
67 
     | 
    
         
             
            Or if you want development version, put this in Gemfile:
         
     | 
| 
       60 
68 
     | 
    
         | 
| 
       61 
69 
     | 
    
         
             
            ``` ruby
         
     | 
| 
       62 
     | 
    
         
            -
            gem 'rest-core', :git => 'git://github.com/ 
     | 
| 
      
 70 
     | 
    
         
            +
            gem 'rest-core', :git => 'git://github.com/godfat/rest-core.git',
         
     | 
| 
       63 
71 
     | 
    
         
             
                             :submodules => true
         
     | 
| 
       64 
72 
     | 
    
         
             
            ```
         
     | 
| 
       65 
73 
     | 
    
         | 
| 
       66 
74 
     | 
    
         
             
            If you just want to use Facebook or Twitter clients, please take a look at
         
     | 
| 
       67 
75 
     | 
    
         
             
            [rest-more][] which has a lot of clients built with rest-core.
         
     | 
| 
       68 
76 
     | 
    
         | 
| 
       69 
     | 
    
         
            -
            [rest-more]: http://github.com/ 
     | 
| 
      
 77 
     | 
    
         
            +
            [rest-more]: http://github.com/godfat/rest-more
         
     | 
| 
       70 
78 
     | 
    
         | 
| 
       71 
79 
     | 
    
         
             
            ## Build Your Own Clients:
         
     | 
| 
       72 
80 
     | 
    
         | 
| 
         @@ -90,12 +98,12 @@ configuration, e.g. different cache time or timeout time): 
     | 
|
| 
       90 
98 
     | 
    
         | 
| 
       91 
99 
     | 
    
         
             
            ``` ruby
         
     | 
| 
       92 
100 
     | 
    
         
             
            client = YourClient.new(:cache => {})
         
     | 
| 
       93 
     | 
    
         
            -
            client.get(' 
     | 
| 
       94 
     | 
    
         
            -
            client.get(' 
     | 
| 
      
 101 
     | 
    
         
            +
            client.get('godfat') # cache miss
         
     | 
| 
      
 102 
     | 
    
         
            +
            client.get('godfat') # cache hit
         
     | 
| 
       95 
103 
     | 
    
         | 
| 
       96 
104 
     | 
    
         
             
            client.site = 'http://github.com/api/v2/json/user/show/'
         
     | 
| 
       97 
     | 
    
         
            -
            client.get(' 
     | 
| 
       98 
     | 
    
         
            -
            client.get(' 
     | 
| 
      
 105 
     | 
    
         
            +
            client.get('godfat') # cache miss
         
     | 
| 
      
 106 
     | 
    
         
            +
            client.get('godfat') # cache hit
         
     | 
| 
       99 
107 
     | 
    
         
             
            ```
         
     | 
| 
       100 
108 
     | 
    
         | 
| 
       101 
109 
     | 
    
         
             
            ### Concurrent Requests with Futures:
         
     | 
| 
         @@ -104,7 +112,7 @@ You can also make concurrent requests easily: 
     | 
|
| 
       104 
112 
     | 
    
         
             
            (see "Advanced Concurrent HTTP Requests -- Embrace the Future" for detail)
         
     | 
| 
       105 
113 
     | 
    
         | 
| 
       106 
114 
     | 
    
         
             
            ``` ruby
         
     | 
| 
       107 
     | 
    
         
            -
            a = [client.get(' 
     | 
| 
      
 115 
     | 
    
         
            +
            a = [client.get('godfat'), client.get('cardinalblue')]
         
     | 
| 
       108 
116 
     | 
    
         
             
            puts "It's not blocking... but doing concurrent requests underneath"
         
     | 
| 
       109 
117 
     | 
    
         
             
            p a.map{ |r| r['name'] } # here we want the values, so it blocks here
         
     | 
| 
       110 
118 
     | 
    
         
             
            puts "DONE"
         
     | 
| 
         @@ -165,7 +173,7 @@ should work. 
     | 
|
| 
       165 
173 
     | 
    
         
             
            On the other hand, callback mode also available:
         
     | 
| 
       166 
174 
     | 
    
         | 
| 
       167 
175 
     | 
    
         
             
            ``` ruby
         
     | 
| 
       168 
     | 
    
         
            -
            client.get(' 
     | 
| 
      
 176 
     | 
    
         
            +
            client.get('godfat'){ |v| p v }
         
     | 
| 
       169 
177 
     | 
    
         
             
            puts "It's not blocking... but doing concurrent requests underneath"
         
     | 
| 
       170 
178 
     | 
    
         
             
            client.wait # we block here to wait for the request done
         
     | 
| 
       171 
179 
     | 
    
         
             
            puts "DONE"
         
     | 
| 
         @@ -191,6 +199,108 @@ client.wait # we block here to wait for the request done 
     | 
|
| 
       191 
199 
     | 
    
         
             
            puts "DONE"
         
     | 
| 
       192 
200 
     | 
    
         
             
            ```
         
     | 
| 
       193 
201 
     | 
    
         | 
| 
      
 202 
     | 
    
         
            +
            ### Thread Pool / Connection Pool
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
            Underneath, rest-core would spawn a thread for each request, freeing you
         
     | 
| 
      
 205 
     | 
    
         
            +
            from blocking. However, occasionally we would not want this behaviour,
         
     | 
| 
      
 206 
     | 
    
         
            +
            giving that we might have limited resource and cannot maximize performance.
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
            For example, maybe we could not afford so many threads running concurrently,
         
     | 
| 
      
 209 
     | 
    
         
            +
            or the target server cannot accept so many concurrent connections. In those
         
     | 
| 
      
 210 
     | 
    
         
            +
            cases, we would want to have limited concurrent threads or connections.
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
            ``` ruby
         
     | 
| 
      
 213 
     | 
    
         
            +
            YourClient.pool_size = 10
         
     | 
| 
      
 214 
     | 
    
         
            +
            YourClient.pool_idle_time = 60
         
     | 
| 
      
 215 
     | 
    
         
            +
            ```
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
            This could set the thread pool size to 10, having a maximum of 10 threads
         
     | 
| 
      
 218 
     | 
    
         
            +
            running together, growing from requests. Each threads idled more than 60
         
     | 
| 
      
 219 
     | 
    
         
            +
            seconds would be shut down automatically.
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
            Note that `pool_size` should at least be larger than 4, or it might be
         
     | 
| 
      
 222 
     | 
    
         
            +
            very likely to have _deadlock_ if you're using nested callbacks and having
         
     | 
| 
      
 223 
     | 
    
         
            +
            a large number of concurrent calls.
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
            Also, setting `pool_size` to `-1` would mean we want to make blocking
         
     | 
| 
      
 226 
     | 
    
         
            +
            requests, without spawning any threads. This might be useful for debugging.
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
            ### Persistent connections (keep-alive connections)
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
            Since we're using [httpclient][] by default now, we would reuse connections,
         
     | 
| 
      
 231 
     | 
    
         
            +
            making it much faster for hitting the same host repeatedly.
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
            ### Streaming Requests
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
            Suppose we want to POST a file, instead of trying to read all the contents
         
     | 
| 
      
 236 
     | 
    
         
            +
            in memory and send them, we could stream it from the file system directly.
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
            ``` ruby
         
     | 
| 
      
 239 
     | 
    
         
            +
            client.post('path', File.open('README.md'))
         
     | 
| 
      
 240 
     | 
    
         
            +
            ```
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
            Basically, payloads could be any IO object. Check out
         
     | 
| 
      
 243 
     | 
    
         
            +
            [RC::Payload](lib/rest-core/util/payload.rb) for more information.
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
            ### Streaming Responses
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
      
 247 
     | 
    
         
            +
            This one is much harder then streaming requests, since all built-in
         
     | 
| 
      
 248 
     | 
    
         
            +
            middleware actually assume the responses should be blocking and buffered.
         
     | 
| 
      
 249 
     | 
    
         
            +
            Say, some JSON parser could not really parse from streams.
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
            We solve this issue similarly to the way Rack solves it. That is, we hijack
         
     | 
| 
      
 252 
     | 
    
         
            +
            the socket. This would be how we're doing:
         
     | 
| 
      
 253 
     | 
    
         
            +
             
     | 
| 
      
 254 
     | 
    
         
            +
            ``` ruby
         
     | 
| 
      
 255 
     | 
    
         
            +
            sock = client.get('path', {}, RC::HIJACK => true)
         
     | 
| 
      
 256 
     | 
    
         
            +
            p sock.read(10)
         
     | 
| 
      
 257 
     | 
    
         
            +
            p sock.read(10)
         
     | 
| 
      
 258 
     | 
    
         
            +
            p sock.read(10)
         
     | 
| 
      
 259 
     | 
    
         
            +
            ```
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
            Of course, if we don't want to block in order to get the socket, we could
         
     | 
| 
      
 262 
     | 
    
         
            +
            always use the callback form:
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
            ``` ruby
         
     | 
| 
      
 265 
     | 
    
         
            +
            client.get('path', {}, RC::HIJACK => true) do |sock|
         
     | 
| 
      
 266 
     | 
    
         
            +
              p sock.read(10)
         
     | 
| 
      
 267 
     | 
    
         
            +
              p sock.read(10)
         
     | 
| 
      
 268 
     | 
    
         
            +
              p sock.read(10)
         
     | 
| 
      
 269 
     | 
    
         
            +
            end
         
     | 
| 
      
 270 
     | 
    
         
            +
            ```
         
     | 
| 
      
 271 
     | 
    
         
            +
             
     | 
| 
      
 272 
     | 
    
         
            +
            Note that since the socket would be put inside `RC::RESPONSE_SOCKET`
         
     | 
| 
      
 273 
     | 
    
         
            +
            instead of `RC::RESPONSE_BODY`, not all middleware would handle the socket.
         
     | 
| 
      
 274 
     | 
    
         
            +
            In the case of hijacking, `RC::RESPONSE_BODY` would always be mapped to an
         
     | 
| 
      
 275 
     | 
    
         
            +
            empty string, as it does not make sense to store the response in this case.
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
            ### SSE (Server-Sent Events)
         
     | 
| 
      
 278 
     | 
    
         
            +
             
     | 
| 
      
 279 
     | 
    
         
            +
            Not only JavaScript could receive server-sent events, any languages could.
         
     | 
| 
      
 280 
     | 
    
         
            +
            Doing so would establish a keep-alive connection to the server, and receive
         
     | 
| 
      
 281 
     | 
    
         
            +
            data periodically. We'll take Firebase as an example:
         
     | 
| 
      
 282 
     | 
    
         
            +
             
     | 
| 
      
 283 
     | 
    
         
            +
            ``` ruby
         
     | 
| 
      
 284 
     | 
    
         
            +
            es = RC::Universal.new.event_source(
         
     | 
| 
      
 285 
     | 
    
         
            +
                   'https://SampleChat.firebaseIO-demo.com/users/tom/.json')
         
     | 
| 
      
 286 
     | 
    
         
            +
             
     | 
| 
      
 287 
     | 
    
         
            +
            es.onopen{ |sock| p "Socket: #{sock}" }
         
     | 
| 
      
 288 
     | 
    
         
            +
            es.onmessage{ |event| p "Event: #{event}" }
         
     | 
| 
      
 289 
     | 
    
         
            +
            es.onerror{ |error| p "Error: #{error}" }
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
            es.start # Start making the request
         
     | 
| 
      
 292 
     | 
    
         
            +
            sleep(5) # Sleep awhile to see anything is happening
         
     | 
| 
      
 293 
     | 
    
         
            +
            es.close # Close the connection when we're done
         
     | 
| 
      
 294 
     | 
    
         
            +
            ```
         
     | 
| 
      
 295 
     | 
    
         
            +
             
     | 
| 
      
 296 
     | 
    
         
            +
            Those callbacks would be called in a separate background thread,
         
     | 
| 
      
 297 
     | 
    
         
            +
            so we don't have to worry about blocking it. If we want to wait for
         
     | 
| 
      
 298 
     | 
    
         
            +
            the connection to be closed, we could call `wait`:
         
     | 
| 
      
 299 
     | 
    
         
            +
             
     | 
| 
      
 300 
     | 
    
         
            +
            ``` ruby
         
     | 
| 
      
 301 
     | 
    
         
            +
            es.wait # This would block until the connection is closed
         
     | 
| 
      
 302 
     | 
    
         
            +
            ```
         
     | 
| 
      
 303 
     | 
    
         
            +
             
     | 
| 
       194 
304 
     | 
    
         
             
            ### More Control with `request_full`:
         
     | 
| 
       195 
305 
     | 
    
         | 
| 
       196 
306 
     | 
    
         
             
            You can also use `request_full` to retrieve everything including response
         
     | 
| 
         @@ -202,17 +312,15 @@ including the path. 
     | 
|
| 
       202 
312 
     | 
    
         
             
            ``` ruby
         
     | 
| 
       203 
313 
     | 
    
         
             
            client.request_full({})[RC::RESPONSE_BODY] # {"message"=>"Not Found"}
         
     | 
| 
       204 
314 
     | 
    
         
             
            # This would print something like this:
         
     | 
| 
       205 
     | 
    
         
            -
            # RestCore:  
     | 
| 
       206 
     | 
    
         
            -
            # RestCore: Future picked: RestCore::Future::FutureThread
         
     | 
| 
       207 
     | 
    
         
            -
            # RestCore: spent 1.135713 Requested GET https://api.github.com/users//
         
     | 
| 
      
 315 
     | 
    
         
            +
            # RestCore: spent 1.135713 Requested GET https://api.github.com/users/
         
     | 
| 
       208 
316 
     | 
    
         | 
| 
       209 
     | 
    
         
            -
            client.request_full(RC::REQUEST_PATH => ' 
     | 
| 
       210 
     | 
    
         
            -
            client.request_full(RC::REQUEST_PATH => ' 
     | 
| 
      
 317 
     | 
    
         
            +
            client.request_full(RC::REQUEST_PATH => 'godfat')[RC::RESPONSE_STATUS]
         
     | 
| 
      
 318 
     | 
    
         
            +
            client.request_full(RC::REQUEST_PATH => 'godfat')[RC::RESPONSE_HEADERS]
         
     | 
| 
       211 
319 
     | 
    
         
             
            # Headers are normalized with all upper cases and
         
     | 
| 
       212 
320 
     | 
    
         
             
            # dashes are replaced by underscores.
         
     | 
| 
       213 
321 
     | 
    
         | 
| 
       214 
322 
     | 
    
         
             
            # To make POST (or any other request methods) request:
         
     | 
| 
       215 
     | 
    
         
            -
            client.request_full(RC::REQUEST_PATH   => ' 
     | 
| 
      
 323 
     | 
    
         
            +
            client.request_full(RC::REQUEST_PATH   => 'godfat',
         
     | 
| 
       216 
324 
     | 
    
         
             
                                RC::REQUEST_METHOD => :post)[RC::RESPONSE_STATUS] # 404
         
     | 
| 
       217 
325 
     | 
    
         
             
            ```
         
     | 
| 
       218 
326 
     | 
    
         | 
| 
         @@ -222,15 +330,15 @@ Runnable example is at: [example/simple.rb][]. Please see [rest-more][] 
     | 
|
| 
       222 
330 
     | 
    
         
             
            for more complex examples to build clients, and [slides][] from
         
     | 
| 
       223 
331 
     | 
    
         
             
            [rubyconf.tw/2011][rubyconf.tw] for concepts.
         
     | 
| 
       224 
332 
     | 
    
         | 
| 
       225 
     | 
    
         
            -
            [example/simple.rb]:  
     | 
| 
       226 
     | 
    
         
            -
            [rest-more]: https://github.com/ 
     | 
| 
      
 333 
     | 
    
         
            +
            [example/simple.rb]: example/simple.rb
         
     | 
| 
      
 334 
     | 
    
         
            +
            [rest-more]: https://github.com/godfat/rest-more
         
     | 
| 
       227 
335 
     | 
    
         
             
            [slides]: http://www.godfat.org/slide/2011-08-27-rest-core.html
         
     | 
| 
       228 
336 
     | 
    
         
             
            [rubyconf.tw]: http://rubyconf.tw/2011/#6
         
     | 
| 
       229 
337 
     | 
    
         | 
| 
       230 
338 
     | 
    
         
             
            ## Playing Around:
         
     | 
| 
       231 
339 
     | 
    
         | 
| 
       232 
340 
     | 
    
         
             
            You can also play around with `RC::Universal` client, which has installed
         
     | 
| 
       233 
     | 
    
         
            -
            _all_ reasonable  
     | 
| 
      
 341 
     | 
    
         
            +
            _all_ reasonable middleware built-in rest-core. So the above example could
         
     | 
| 
       234 
342 
     | 
    
         
             
            also be achieved by:
         
     | 
| 
       235 
343 
     | 
    
         | 
| 
       236 
344 
     | 
    
         
             
            ``` ruby
         
     | 
| 
         @@ -238,7 +346,7 @@ require 'rest-core' 
     | 
|
| 
       238 
346 
     | 
    
         
             
            client = RC::Universal.new(:site          => 'https://api.github.com/users/',
         
     | 
| 
       239 
347 
     | 
    
         
             
                                       :json_response => true,
         
     | 
| 
       240 
348 
     | 
    
         
             
                                       :log_method    => method(:puts))
         
     | 
| 
       241 
     | 
    
         
            -
            client.get(' 
     | 
| 
      
 349 
     | 
    
         
            +
            client.get('godfat')
         
     | 
| 
       242 
350 
     | 
    
         
             
            ```
         
     | 
| 
       243 
351 
     | 
    
         | 
| 
       244 
352 
     | 
    
         
             
            `RC::Universal` is defined as:
         
     | 
| 
         @@ -276,7 +384,7 @@ rib rest-core 
     | 
|
| 
       276 
384 
     | 
    
         
             
            And you will be entering a rib shell, which `self` is an instance of
         
     | 
| 
       277 
385 
     | 
    
         
             
            `RC::Universal` you can play:
         
     | 
| 
       278 
386 
     | 
    
         | 
| 
       279 
     | 
    
         
            -
                rest-core>> get 'https://api.github.com/users/ 
     | 
| 
      
 387 
     | 
    
         
            +
                rest-core>> get 'https://api.github.com/users/godfat'
         
     | 
| 
       280 
388 
     | 
    
         | 
| 
       281 
389 
     | 
    
         
             
            will print out the response from Github. You can also do this to make
         
     | 
| 
       282 
390 
     | 
    
         
             
            calling Github easier:
         
     | 
| 
         @@ -286,36 +394,56 @@ calling Github easier: 
     | 
|
| 
       286 
394 
     | 
    
         | 
| 
       287 
395 
     | 
    
         
             
            Then it would do exactly like the original example:
         
     | 
| 
       288 
396 
     | 
    
         | 
| 
       289 
     | 
    
         
            -
                rest-core>> get ' 
     | 
| 
      
 397 
     | 
    
         
            +
                rest-core>> get 'godfat' # you get a nice parsed hash
         
     | 
| 
       290 
398 
     | 
    
         | 
| 
       291 
399 
     | 
    
         
             
            This is mostly for fun and experimenting, so it's only included in
         
     | 
| 
       292 
400 
     | 
    
         
             
            [rest-more][] and [rib][]. Please make sure you have both of them
         
     | 
| 
       293 
401 
     | 
    
         
             
            installed before trying this.
         
     | 
| 
       294 
402 
     | 
    
         | 
| 
       295 
403 
     | 
    
         
             
            [rib]: https://github.com/godfat/rib
         
     | 
| 
       296 
     | 
    
         
            -
            [rest-more]: https://github.com/ 
     | 
| 
      
 404 
     | 
    
         
            +
            [rest-more]: https://github.com/godfat/rest-more
         
     | 
| 
       297 
405 
     | 
    
         | 
| 
       298 
406 
     | 
    
         
             
            ## List of built-in Middleware:
         
     | 
| 
       299 
407 
     | 
    
         | 
| 
       300 
     | 
    
         
            -
            *  
     | 
| 
       301 
     | 
    
         
            -
            *  
     | 
| 
       302 
     | 
    
         
            -
            *  
     | 
| 
       303 
     | 
    
         
            -
            *  
     | 
| 
       304 
     | 
    
         
            -
            *  
     | 
| 
       305 
     | 
    
         
            -
            *  
     | 
| 
       306 
     | 
    
         
            -
            *  
     | 
| 
       307 
     | 
    
         
            -
            *  
     | 
| 
       308 
     | 
    
         
            -
            *  
     | 
| 
       309 
     | 
    
         
            -
            *  
     | 
| 
       310 
     | 
    
         
            -
            *  
     | 
| 
       311 
     | 
    
         
            -
            *  
     | 
| 
       312 
     | 
    
         
            -
            *  
     | 
| 
       313 
     | 
    
         
            -
            *  
     | 
| 
       314 
     | 
    
         
            -
            *  
     | 
| 
       315 
     | 
    
         
            -
            *  
     | 
| 
       316 
     | 
    
         
            -
            *  
     | 
| 
       317 
     | 
    
         
            -
            *  
     | 
| 
       318 
     | 
    
         
            -
            *  
     | 
| 
      
 408 
     | 
    
         
            +
            * [RC::AuthBasic][]
         
     | 
| 
      
 409 
     | 
    
         
            +
            * [RC::Bypass][]
         
     | 
| 
      
 410 
     | 
    
         
            +
            * [RC::Cache][]
         
     | 
| 
      
 411 
     | 
    
         
            +
            * [RC::CommonLogger][]
         
     | 
| 
      
 412 
     | 
    
         
            +
            * [RC::DefaultHeaders][]
         
     | 
| 
      
 413 
     | 
    
         
            +
            * [RC::DefaultPayload][]
         
     | 
| 
      
 414 
     | 
    
         
            +
            * [RC::DefaultQuery][]
         
     | 
| 
      
 415 
     | 
    
         
            +
            * [RC::DefaultSite][]
         
     | 
| 
      
 416 
     | 
    
         
            +
            * [RC::Defaults][]
         
     | 
| 
      
 417 
     | 
    
         
            +
            * [RC::ErrorDetector][]
         
     | 
| 
      
 418 
     | 
    
         
            +
            * [RC::ErrorDetectorHttp][]
         
     | 
| 
      
 419 
     | 
    
         
            +
            * [RC::ErrorHandler][]
         
     | 
| 
      
 420 
     | 
    
         
            +
            * [RC::FollowRedirect][]
         
     | 
| 
      
 421 
     | 
    
         
            +
            * [RC::JsonRequest][]
         
     | 
| 
      
 422 
     | 
    
         
            +
            * [RC::JsonResponse][]
         
     | 
| 
      
 423 
     | 
    
         
            +
            * [RC::Oauth1Header][]
         
     | 
| 
      
 424 
     | 
    
         
            +
            * [RC::Oauth2Header][]
         
     | 
| 
      
 425 
     | 
    
         
            +
            * [RC::Oauth2Query][]
         
     | 
| 
      
 426 
     | 
    
         
            +
            * [RC::Timeout][]
         
     | 
| 
      
 427 
     | 
    
         
            +
             
     | 
| 
      
 428 
     | 
    
         
            +
            [RC::AuthBasic]: lib/rest-core/middleware/auth_basic.rb
         
     | 
| 
      
 429 
     | 
    
         
            +
            [RC::Bypass]: lib/rest-core/middleware/bypass.rb
         
     | 
| 
      
 430 
     | 
    
         
            +
            [RC::Cache]: lib/rest-core/middleware/cache.rb
         
     | 
| 
      
 431 
     | 
    
         
            +
            [RC::CommonLogger]: lib/rest-core/middleware/common_logger.rb
         
     | 
| 
      
 432 
     | 
    
         
            +
            [RC::DefaultHeaders]: lib/rest-core/middleware/default_headers.rb
         
     | 
| 
      
 433 
     | 
    
         
            +
            [RC::DefaultPayload]: lib/rest-core/middleware/default_payload.rb
         
     | 
| 
      
 434 
     | 
    
         
            +
            [RC::DefaultQuery]: lib/rest-core/middleware/default_query.rb
         
     | 
| 
      
 435 
     | 
    
         
            +
            [RC::DefaultSite]: lib/rest-core/middleware/default_site.rb
         
     | 
| 
      
 436 
     | 
    
         
            +
            [RC::Defaults]: lib/rest-core/middleware/defaults.rb
         
     | 
| 
      
 437 
     | 
    
         
            +
            [RC::ErrorDetector]: lib/rest-core/middleware/error_detector.rb
         
     | 
| 
      
 438 
     | 
    
         
            +
            [RC::ErrorDetectorHttp]: lib/rest-core/middleware/error_detector_http.rb
         
     | 
| 
      
 439 
     | 
    
         
            +
            [RC::ErrorHandler]: lib/rest-core/middleware/error_handler.rb
         
     | 
| 
      
 440 
     | 
    
         
            +
            [RC::FollowRedirect]: lib/rest-core/middleware/follow_redirect.rb
         
     | 
| 
      
 441 
     | 
    
         
            +
            [RC::JsonRequest]: lib/rest-core/middleware/json_request.rb
         
     | 
| 
      
 442 
     | 
    
         
            +
            [RC::JsonResponse]: lib/rest-core/middleware/json_response.rb
         
     | 
| 
      
 443 
     | 
    
         
            +
            [RC::Oauth1Header]: lib/rest-core/middleware/oauth1_header.rb
         
     | 
| 
      
 444 
     | 
    
         
            +
            [RC::Oauth2Header]: lib/rest-core/middleware/oauth2_header.rb
         
     | 
| 
      
 445 
     | 
    
         
            +
            [RC::Oauth2Query]: lib/rest-core/middleware/oauth2_query.rb
         
     | 
| 
      
 446 
     | 
    
         
            +
            [RC::Timeout]: lib/rest-core/middleware/timeout.rb
         
     | 
| 
       319 
447 
     | 
    
         | 
| 
       320 
448 
     | 
    
         
             
            ## Build Your Own Middleware:
         
     | 
| 
       321 
449 
     | 
    
         | 
| 
         @@ -425,8 +553,8 @@ YourClient = RC::Builder.client do 
     | 
|
| 
       425 
553 
     | 
    
         
             
            end
         
     | 
| 
       426 
554 
     | 
    
         | 
| 
       427 
555 
     | 
    
         
             
            client = YourClient.new
         
     | 
| 
       428 
     | 
    
         
            -
            puts " 
     | 
| 
       429 
     | 
    
         
            -
            a = [client.get(' 
     | 
| 
      
 556 
     | 
    
         
            +
            puts "httpclient with threads doing concurrent requests"
         
     | 
| 
      
 557 
     | 
    
         
            +
            a = [client.get('godfat'), client.get('cardinalblue')]
         
     | 
| 
       430 
558 
     | 
    
         
             
            puts "It's not blocking... but doing concurrent requests underneath"
         
     | 
| 
       431 
559 
     | 
    
         
             
            p a.map{ |r| r['name'] } # here we want the values, so it blocks here
         
     | 
| 
       432 
560 
     | 
    
         
             
            puts "DONE"
         
     | 
| 
         @@ -443,11 +571,11 @@ YourClient = RC::Builder.client do 
     | 
|
| 
       443 
571 
     | 
    
         
             
            end
         
     | 
| 
       444 
572 
     | 
    
         | 
| 
       445 
573 
     | 
    
         
             
            client = YourClient.new
         
     | 
| 
       446 
     | 
    
         
            -
            puts " 
     | 
| 
       447 
     | 
    
         
            -
            client.get(' 
     | 
| 
      
 574 
     | 
    
         
            +
            puts "httpclient with threads doing concurrent requests"
         
     | 
| 
      
 575 
     | 
    
         
            +
            client.get('godfat'){ |v|
         
     | 
| 
       448 
576 
     | 
    
         
             
                     p v['name']
         
     | 
| 
       449 
577 
     | 
    
         
             
                   }.
         
     | 
| 
       450 
     | 
    
         
            -
                   get(' 
     | 
| 
      
 578 
     | 
    
         
            +
                   get('cardinalblue'){ |v|
         
     | 
| 
       451 
579 
     | 
    
         
             
                     p v['name']
         
     | 
| 
       452 
580 
     | 
    
         
             
                   }
         
     | 
| 
       453 
581 
     | 
    
         
             
            puts "It's not blocking... but doing concurrent requests underneath"
         
     | 
| 
         @@ -459,85 +587,21 @@ You can pick whatever works for you. 
     | 
|
| 
       459 
587 
     | 
    
         | 
| 
       460 
588 
     | 
    
         
             
            [future]: http://en.wikipedia.org/wiki/Futures_and_promises
         
     | 
| 
       461 
589 
     | 
    
         | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
       463 
     | 
    
         
            -
             
     | 
| 
       464 
     | 
    
         
            -
            In the above example, we're using rest-client with threads, which works
         
     | 
| 
       465 
     | 
    
         
            -
            for most of cases. But you might also want to use em-http-request with
         
     | 
| 
       466 
     | 
    
         
            -
            EventMachine, which is using a faster HTTP parser. In theory, it should
         
     | 
| 
       467 
     | 
    
         
            -
            be much more efficient than rest-client and threads.
         
     | 
| 
       468 
     | 
    
         
            -
             
     | 
| 
       469 
     | 
    
         
            -
            To pick em-http-request, you must run the requests inside the EventMachine's
         
     | 
| 
       470 
     | 
    
         
            -
            event loop, and also wrap your request with either a thread or a fiber,
         
     | 
| 
       471 
     | 
    
         
            -
            because we can't block the event loop and ask em-http-request to finish
         
     | 
| 
       472 
     | 
    
         
            -
            its job making requests.
         
     | 
| 
       473 
     | 
    
         
            -
             
     | 
| 
       474 
     | 
    
         
            -
            Here's an example of using em-http-request with threads:
         
     | 
| 
       475 
     | 
    
         
            -
             
     | 
| 
       476 
     | 
    
         
            -
            ``` ruby
         
     | 
| 
       477 
     | 
    
         
            -
            require 'em-http-request'
         
     | 
| 
       478 
     | 
    
         
            -
            require 'rest-core'
         
     | 
| 
       479 
     | 
    
         
            -
            YourClient = RC::Builder.client do
         
     | 
| 
       480 
     | 
    
         
            -
              use RC::DefaultSite , 'https://api.github.com/users/'
         
     | 
| 
       481 
     | 
    
         
            -
              use RC::JsonResponse, true
         
     | 
| 
       482 
     | 
    
         
            -
              use RC::CommonLogger, method(:puts)
         
     | 
| 
       483 
     | 
    
         
            -
            end
         
     | 
| 
       484 
     | 
    
         
            -
             
     | 
| 
       485 
     | 
    
         
            -
            client = YourClient.new
         
     | 
| 
       486 
     | 
    
         
            -
            puts "eventmachine with threads doing concurrent requests"
         
     | 
| 
       487 
     | 
    
         
            -
            EM.run{
         
     | 
| 
       488 
     | 
    
         
            -
              Thread.new{
         
     | 
| 
       489 
     | 
    
         
            -
                a = [client.get('cardinalblue'), client.get('godfat')]
         
     | 
| 
       490 
     | 
    
         
            -
                p a.map{ |r| r['name'] } # here we want the values, so it blocks here
         
     | 
| 
       491 
     | 
    
         
            -
                puts "DONE"
         
     | 
| 
       492 
     | 
    
         
            -
                EM.stop
         
     | 
| 
       493 
     | 
    
         
            -
              }
         
     | 
| 
       494 
     | 
    
         
            -
              puts "It's not blocking... but doing concurrent requests underneath"
         
     | 
| 
       495 
     | 
    
         
            -
            }
         
     | 
| 
       496 
     | 
    
         
            -
            ```
         
     | 
| 
       497 
     | 
    
         
            -
             
     | 
| 
       498 
     | 
    
         
            -
            And here's an example of using em-http-request with fibers:
         
     | 
| 
       499 
     | 
    
         
            -
             
     | 
| 
       500 
     | 
    
         
            -
            ``` ruby
         
     | 
| 
       501 
     | 
    
         
            -
            require 'fiber'           # remember to require fiber first,
         
     | 
| 
       502 
     | 
    
         
            -
            require 'em-http-request' # or rest-core won't pick fibers
         
     | 
| 
       503 
     | 
    
         
            -
            require 'rest-core'
         
     | 
| 
       504 
     | 
    
         
            -
            YourClient = RC::Builder.client do
         
     | 
| 
       505 
     | 
    
         
            -
              use RC::DefaultSite , 'https://api.github.com/users/'
         
     | 
| 
       506 
     | 
    
         
            -
              use RC::JsonResponse, true
         
     | 
| 
       507 
     | 
    
         
            -
              use RC::CommonLogger, method(:puts)
         
     | 
| 
       508 
     | 
    
         
            -
            end
         
     | 
| 
       509 
     | 
    
         
            -
             
     | 
| 
       510 
     | 
    
         
            -
            client = YourClient.new
         
     | 
| 
       511 
     | 
    
         
            -
            puts "eventmachine with fibers doing concurrent requests"
         
     | 
| 
       512 
     | 
    
         
            -
            EM.run{
         
     | 
| 
       513 
     | 
    
         
            -
              Fiber.new{
         
     | 
| 
       514 
     | 
    
         
            -
                a = [client.get('cardinalblue'), client.get('godfat')]
         
     | 
| 
       515 
     | 
    
         
            -
                p a.map{ |r| r['name'] } # here we want the values, so it blocks here
         
     | 
| 
       516 
     | 
    
         
            -
                puts "DONE"
         
     | 
| 
       517 
     | 
    
         
            -
                EM.stop
         
     | 
| 
       518 
     | 
    
         
            -
              }
         
     | 
| 
       519 
     | 
    
         
            -
              puts "It's not blocking... but doing concurrent requests underneath"
         
     | 
| 
       520 
     | 
    
         
            -
            }
         
     | 
| 
       521 
     | 
    
         
            -
            ```
         
     | 
| 
       522 
     | 
    
         
            -
             
     | 
| 
       523 
     | 
    
         
            -
            As you can see, both of them are quite similar to each other, because the
         
     | 
| 
       524 
     | 
    
         
            -
            idea behind the scene is the same. If you don't know what concurrency model
         
     | 
| 
       525 
     | 
    
         
            -
            to pick, start with rest-client since it's the easiest one to setup.
         
     | 
| 
       526 
     | 
    
         
            -
             
     | 
| 
       527 
     | 
    
         
            -
            A full runnable example is at: [example/multi.rb][]. If you want to know
         
     | 
| 
      
 590 
     | 
    
         
            +
            A full runnable example is at: [example/simple.rb][]. If you want to know
         
     | 
| 
       528 
591 
     | 
    
         
             
            all the possible use cases, you can also see: [example/use-cases.rb][]. It's
         
     | 
| 
       529 
592 
     | 
    
         
             
            also served as a test for each possible combinations, so it's quite complex
         
     | 
| 
       530 
593 
     | 
    
         
             
            and complete.
         
     | 
| 
       531 
594 
     | 
    
         | 
| 
       532 
     | 
    
         
            -
            [example/ 
     | 
| 
       533 
     | 
    
         
            -
             
     | 
| 
       534 
     | 
    
         
            -
            [example/use-cases.rb]: https://github.com/cardinalblue/rest-core/blob/master/example/use-cases.rb
         
     | 
| 
      
 595 
     | 
    
         
            +
            [example/simple.rb]: example/simple.rb
         
     | 
| 
      
 596 
     | 
    
         
            +
            [example/use-cases.rb]: example/use-cases.rb
         
     | 
| 
       535 
597 
     | 
    
         | 
| 
       536 
598 
     | 
    
         
             
            ## rest-core users:
         
     | 
| 
       537 
599 
     | 
    
         | 
| 
       538 
     | 
    
         
            -
            * [ 
     | 
| 
      
 600 
     | 
    
         
            +
            * [rest-more][]
         
     | 
| 
      
 601 
     | 
    
         
            +
            * [rest-more-yahoo_buy](https://github.com/GoodLife/rest-more-yahoo_buy)
         
     | 
| 
       539 
602 
     | 
    
         
             
            * [s2sync](https://github.com/brucehsu/s2sync)
         
     | 
| 
       540 
603 
     | 
    
         
             
            * [s2sync_web](https://github.com/brucehsu/s2sync_web)
         
     | 
| 
      
 604 
     | 
    
         
            +
            * [topcoder](https://github.com/miaout17/topcoder)
         
     | 
| 
       541 
605 
     | 
    
         | 
| 
       542 
606 
     | 
    
         
             
            ## Powered sites:
         
     | 
| 
       543 
607 
     | 
    
         | 
| 
         @@ -545,7 +609,7 @@ and complete. 
     | 
|
| 
       545 
609 
     | 
    
         | 
| 
       546 
610 
     | 
    
         
             
            ## CHANGES:
         
     | 
| 
       547 
611 
     | 
    
         | 
| 
       548 
     | 
    
         
            -
            * [CHANGES]( 
     | 
| 
      
 612 
     | 
    
         
            +
            * [CHANGES](CHANGES.md)
         
     | 
| 
       549 
613 
     | 
    
         | 
| 
       550 
614 
     | 
    
         
             
            ## CONTRIBUTORS:
         
     | 
| 
       551 
615 
     | 
    
         | 
| 
         @@ -557,7 +621,9 @@ and complete. 
     | 
|
| 
       557 
621 
     | 
    
         
             
            * Florent Vaucelle (@florent)
         
     | 
| 
       558 
622 
     | 
    
         
             
            * Jaime Cham (@jcham)
         
     | 
| 
       559 
623 
     | 
    
         
             
            * John Fan (@johnfan)
         
     | 
| 
      
 624 
     | 
    
         
            +
            * khoa nguyen (@khoan)
         
     | 
| 
       560 
625 
     | 
    
         
             
            * Lin Jen-Shin (@godfat)
         
     | 
| 
      
 626 
     | 
    
         
            +
            * lulalala (@lulalala)
         
     | 
| 
       561 
627 
     | 
    
         
             
            * Mariusz Pruszynski (@snicky)
         
     | 
| 
       562 
628 
     | 
    
         
             
            * Mr. Big Cat (@miaout17)
         
     | 
| 
       563 
629 
     | 
    
         
             
            * Nicolas Fouché (@nfo)
         
     | 
| 
         @@ -567,7 +633,7 @@ and complete. 
     | 
|
| 
       567 
633 
     | 
    
         | 
| 
       568 
634 
     | 
    
         
             
            Apache License 2.0
         
     | 
| 
       569 
635 
     | 
    
         | 
| 
       570 
     | 
    
         
            -
            Copyright (c) 2011- 
     | 
| 
      
 636 
     | 
    
         
            +
            Copyright (c) 2011-2014, Lin Jen-Shin (godfat)
         
     | 
| 
       571 
637 
     | 
    
         | 
| 
       572 
638 
     | 
    
         
             
            Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
       573 
639 
     | 
    
         
             
            you may not use this file except in compliance with the License.
         
     |