Last active
December 17, 2015 21:39
-
-
Save godfat/5676447 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rest-core' | |
module RestCore | |
middleware = Class.new | |
middleware.module_eval do | |
def initialize app | |
@app = app | |
end | |
def call env, &k | |
puts "Calling" | |
@app.call(env, &k) | |
end | |
end | |
Circular = Builder.client do | |
use middleware | |
end | |
Circular::Middleware = middleware | |
end | |
puts RC::Circular | |
puts RC::Circular::Middleware | |
puts RC::Circular.new.head('http://example.com/') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rest-core' | |
module RestCore | |
middleware = Class.new | |
middleware.module_eval do | |
def initialize app | |
@app = app | |
end | |
def call env, &k | |
puts env['secret'] | |
@app.call(env, &k) | |
end | |
end | |
Secret = Builder.client(:secret) do | |
use middleware | |
end | |
Secret::Middleware = middleware | |
end | |
puts RC::Secret.new(:secret => 'mission').head('http://example.com/') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rest-core/middleware' | |
require 'rest-core/util/hmac' | |
class RestCore::Signature | |
def self.members; [:secret]; end | |
include RestCore::Middleware | |
def call env, &k | |
uri = request_uri(env) | |
sig = Hmac.sha1(secret(env), uri) | |
app.call(env.merge(REQUEST_QUERY => {}, | |
REQUEST_PATH => "#{uri}&Signature=#{sig}", &k)) | |
end | |
end |
對,一方面給一些方便的 methods 可用,另一方面則是讓 client 也可以記得一份可改變的設定(變數)
對,Builder.client
給的參數是額外需要記得的變數,確實如 RC::Facebook
的 app_id
, 不過這裡並沒有例外,這個 app_id
也同樣會傳到 env 裡面,只是 middleware 裡面可能不會用到而已。
意思就是,在之前的版本裡(現已修好),如果 Builder.client
和 middleware 都給 secret
, 則 client 實際上會有兩個 secret
(!) 修正好的版本在所有的 attributes 中取 uniq
, 因此 secret 會只剩一個。
這樣並不會造成任何問題(在新的版本裡),只是沒有意義而已。也可以寫成:
class Signature
def initialize app; @app = app; end
def call env, &k
puts env['secret']
app.call(&k)
end
end
Client = RC::Builder.client(:secret){ use Signature }
也就是說,middleware 裡面就不自己記得一份 secret 了,一律靠 client 傳過去。這樣做的缺點是,使用 middleware 的人要自己記得這個 middleware 可能需要一份 secret 傳進去。
至於 api_key 如果要放在每個 request 中,那取決於要放在 query 或是 payload 甚或 headers 裡,
我會用對應的 middleware 並定義 default_query. 範例:
Client = RC::Builder.client(:api_key){ use RC::DefaultQuery }
class Client
def default_query
{:api_key => api_key}
end
end
這樣 client 可記得 api_key, 同時會自動夾在 query 裡面。payload 或 headers 亦然。
請問一下,你說的 dry run是原本就會丟出 timeout 囉?
2.0.0-p0 :002 > client = RC::Facebook.new
=> #<struct RestCore::Facebook timeout=10, site="https://gra..., headers={"Accept"=>"..., access_token=nil, log_method=nil, cache=nil, expires_in=600, error_handler=#<Proc:0x007..., error_detector=#<Proc:0x007..., json_response=true, defaults={:old_site=>..., data={}, app_id=nil, secret=nil, old_site="https://api...>
2.0.0-p0 :003 > client.request_full({RC::REQUEST_PATH => '/'}, client.dry)
=> {"REQUEST_METHOD"=>:get, "REQUEST_PATH"=>"https://graph.facebook.com//", "REQUEST_QUERY"=>{}, "REQUEST_PAYLOAD"=>{}, "REQUEST_HEADERS"=>{"Accept"=>"application/json", "Accept-Language"=>"en-us"}, "core.fail"=>[], "core.log"=>[#<struct RestCore::Event::Requested duration=0.010871, message="GET https://graph.facebook.com//">], "timeout"=>10, "site"=>"https://graph.facebook.com/", "headers"=>{"Accept"=>"application/json", "Accept-Language"=>"en-us"}, "access_token"=>nil, "log_method"=>nil, "cache"=>nil, "expires_in"=>600, "error_handler"=>#<Proc:0x007fd739686420@Code/rest-more/lib/rest-core/client/facebook.rb:18 (lambda)>, "error_detector"=>#<Proc:0x007fd7396864c0@Code/rest-more/lib/rest-core/client/facebook.rb:19 (lambda)>, "json_response"=>true, "defaults"=>{:old_site=>"https://api.facebook.com/"}, "data"=>{}, "app_id"=>nil, "secret"=>nil, "old_site"=>"https://api.facebook.com/", "async.callback"=>false, "async.timer"=>#<RestCore::Timeout::TimerThread:0x007fd7396a6dd8 @timeout=10, @error=#<Timeout::Error: execution expired>, @block=#<Proc:0x007fd7396a6d88@Code/rest-more/rest-core/lib/rest-core/middleware/timeout/timer_thread.rb:9 (lambda)>, @canceled=false, @thread=#<Thread:0x007fd7396a6d60 sleep>>, "RESPONSE_BODY"=>nil}
2.0.0-p0 :004 > .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/input-method.rb:152:in `readline': execution expired (Timeout::Error)
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/input-method.rb:152:in `gets'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb.rb:472:in `block (2 levels) in eval_input'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb.rb:624:in `signal_status'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb.rb:471:in `block in eval_input'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:190:in `call'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:190:in `buf_input'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:105:in `getc'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/slex.rb:206:in `match_io'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/slex.rb:76:in `match'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:290:in `token'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:266:in `lex'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:237:in `block (2 levels) in each_top_level_statement'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:233:in `loop'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:233:in `block in each_top_level_statement'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:232:in `catch'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb/ruby-lex.rb:232:in `each_top_level_statement'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb.rb:488:in `eval_input'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb.rb:397:in `block in start'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb.rb:396:in `catch'
from .rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/irb.rb:396:in `start'
from .rvm/rubies/ruby-2.0.0-p0/bin/irb:16:in `<main>'
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
啊然後想問,要是得把 api_key放在每個 request 中,這是那個 default_payload 還是 default_query 的範圍嗎?