Faraday: ๋‹จ์ผ ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ ํ™˜๊ฒฝ ํ”„๋ก์‹œ ์„ค์ •์„ ๋ฌด์‹œํ•˜๋Š” ๊ธฐ๋Šฅ

์— ๋งŒ๋“  2019๋…„ 08์›” 22์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: lostisland/faraday

๊ธฐ๋ณธ ์ •๋ณด

  • ํŒจ๋Ÿฌ๋ฐ์ด ๋ฒ„์ „: 0.15.4
  • ๋ฃจ๋น„ ๋ฒ„์ „: 2.4.3

๋ฌธ์ œ ์„ค๋ช…

์šฐ๋ฆฌ๋Š” Faraday๋ฅผ ์–ด๋Š ์ •๋„ ์‚ฌ์šฉํ•˜๋Š” ์ˆ˜๋ฐฑ ๊ฐœ์˜ ํ•˜์œ„ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ๋Š” ๊ฝค ํฐ ์•ฑ์„ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋Œ€๋ถ€๋ถ„์€ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ http_proxy ๋“ฑ์œผ๋กœ Faraday๋ฅผ ๊ตฌ์„ฑํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์—ฐ๊ฒฐ ์ƒ์„ฑ์ž์— ๋ช…์‹œ์ ์ธ :proxy ์„ค์ •์„ ์ „๋‹ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ถ€ ๊ตฌ์„ฑ ์š”์†Œ(์•ฝ 100๊ฐœ ์ค‘ 2๊ฐœ ๋˜๋Š” 3๊ฐœ)๋Š” ํ”„๋ก์‹œ ์—†์ด ํŒจ๋Ÿฌ๋ฐ์ด ์—ฐ๊ฒฐ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, Faraday.ignore_env_proxy = true ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‚˜๋จธ์ง€ ~100๊ฐœ์˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์†์ƒ๋ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๊ฐ–๊ณ  ์‹ถ์€ ๊ฒƒ์€ ๊ทธ ๋ช‡ ๊ฐ€์ง€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ํ™˜๊ฒฝ์ด๋‚˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํŒจ๋Ÿฌ๋ฐ์ด ์—ฐ๊ฒฐ ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

์žฌํ˜„ ๋‹จ๊ณ„

#752์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ด๊ฒƒ์€ ์—ฐ๊ฒฐํ•  ๋•Œ ํ™˜๊ฒฝ์˜ ํ”„๋ก์‹œ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋Š” ํŒจ๋Ÿฌ๋ฐ์ด ๊ฐœ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

c = Faraday.new('https://www.google.com', proxy: nil)

๋‚˜๋Š” ๋˜ํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งค์šฐ ๋˜‘๋˜‘ํ•˜๊ณ  ๋นˆ ํ•ด์‹œ๋ฅผ ํ”„๋ก์‹œ ์˜ต์…˜์œผ๋กœ ๋Œ€์‹  ์ „๋‹ฌํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.

c = Faraday.new('https://www.google.com', proxy: {})

๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์Œ๊ณผ ํ•จ๊ป˜ ์ด ์—ฐ๊ฒฐ ์˜ค๋ฅ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

NoMethodError: undefined method `hostname' for nil:NilClass
from vendor/bundle/ruby/2.4.0/gems/faraday-0.15.4/lib/faraday/adapter/net_http.rb:97:in `net_http_connection'

์ด(๋˜๋Š” :proxy ์„ค์ •์„ ํ†ตํ•ด "ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค"๋ผ๊ณ  ๋งํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•)๊ฐ€ ์ง€์›๋˜๋ฉด ์ด ๋ฌธ์ œ๊ฐ€ ์™„์ „ํžˆ ํ•ด๊ฒฐ๋  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

OMG, ํ™•์‹คํžˆ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ํ•œ ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฏธ๋“ค์›จ์–ด์˜€์Šต๋‹ˆ๋‹ค(Octokit ์‚ฌ์šฉ์„ ์œ„ํ•ด):

    # A Faraday middleware that throws out any configured proxy away
    # from the request environment, to make connections to GHE work
    # (those must not be proxied).
    class ProxyDroppingMiddleware < Faraday::Middleware
      def call(request_env)
        request_env[:request][:proxy] = nil
        @app.call(request_env)
      end
    end

๊ทธ๋ฆฌ๊ณ  ์˜ฅํ† ํ‚ท์„ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ๊ฐ€ ๋˜๋ฉด:

        stack = Faraday::RackBuilder.new do |builder|
          builder.use ProxyDroppingMiddleware
          # What follows is the default octokit middleware:
          builder.use Faraday::Request::Retry, exceptions: [Octokit::ServerError]
          builder.use Octokit::Middleware::FollowRedirects
          builder.use Octokit::Response::RaiseError
          builder.use Octokit::Response::FeedParser
          builder.adapter Faraday.default_adapter
        end
        options[:middleware] = stack

๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด ๋ฏธ๋“ค์›จ์–ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ octokit์—์„œ ๋” ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ƒ์„ฑ ํ›„ Faraday ๊ฐœ์ฒด๋ฅผ ํŒจ์น˜ํ•˜๊ธฐ ์œ„ํ•ด octokit ๋ž˜ํผ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  3 ๋Œ“๊ธ€

@asf-stripe ๋‚˜๋Š” ์ด๊ฒƒ์„ ์‹œ๋„ํ•œ ์ ์ด ์—†์ง€๋งŒ (์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋‘ ๋˜๋Š” ์ „ํ˜€ ์—†์Œ) setter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐ์„ ์ดˆ๊ธฐํ™”ํ•œ ํ›„ ํ”„๋ก์‹œ๋ฅผ nil๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(https://github.com/lostisland/faraday/blob /master/lib/faraday/connection.rb#L397)

c = Faraday.new('https://www.google.com')
c.proxy = nil

์ด๊ฒƒ์€ @manual_proxy env๋ฅผ true๋กœ ์„ค์ •ํ•˜๊ณ  Faraday๊ฐ€ ํ•ด๋‹น ํŠน์ • ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ env๋ฅผ ๋ฌด์‹œํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์„ธ์š” ๐Ÿ˜„

OMG, ํ™•์‹คํžˆ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ํ•œ ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฏธ๋“ค์›จ์–ด์˜€์Šต๋‹ˆ๋‹ค(Octokit ์‚ฌ์šฉ์„ ์œ„ํ•ด):

    # A Faraday middleware that throws out any configured proxy away
    # from the request environment, to make connections to GHE work
    # (those must not be proxied).
    class ProxyDroppingMiddleware < Faraday::Middleware
      def call(request_env)
        request_env[:request][:proxy] = nil
        @app.call(request_env)
      end
    end

๊ทธ๋ฆฌ๊ณ  ์˜ฅํ† ํ‚ท์„ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ๊ฐ€ ๋˜๋ฉด:

        stack = Faraday::RackBuilder.new do |builder|
          builder.use ProxyDroppingMiddleware
          # What follows is the default octokit middleware:
          builder.use Faraday::Request::Retry, exceptions: [Octokit::ServerError]
          builder.use Octokit::Middleware::FollowRedirects
          builder.use Octokit::Response::RaiseError
          builder.use Octokit::Response::FeedParser
          builder.adapter Faraday.default_adapter
        end
        options[:middleware] = stack

๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด ๋ฏธ๋“ค์›จ์–ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ octokit์—์„œ ๋” ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ƒ์„ฑ ํ›„ Faraday ๊ฐœ์ฒด๋ฅผ ํŒจ์น˜ํ•˜๊ธฐ ์œ„ํ•ด octokit ๋ž˜ํผ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์•„ ์˜ˆ, ์ œ ์†”๋ฃจ์…˜์€ ์‹ค์ œ ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ๊ถŒํ•œ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค(๋ž˜ํผ ์‚ฌ์šฉ ๋˜๋Š” instance_variable_get ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉ). ๋‚˜๋Š” ๋‹น์‹ ์ด ์ฒซ ๋ฒˆ์งธ ๊ฒŒ์‹œ๋ฌผ์—์„œ ์–ธ๊ธ‰ํ•œ ์‹œ๋„๋ฅผ ๋ณด๊ณ  ๊ทธ ๊ฒฝ์šฐ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ์ œ์•ˆ์ด ํšจ๊ณผ๊ฐ€ ์žˆ๊ณ  ๋‹ค๋ฅธ ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ๋ฏธ๋“ค์›จ์–ด๊ฐ€ ์žˆ๋‹ค๋Š” ์†Œ์‹์„ ๋“ฃ๊ณ  ๊ธฐ์ฉ๋‹ˆ๋‹ค.
์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋„์›€์ด ํ•„์š”ํ•˜๋ฉด ์—ฐ๋ฝํ•ด ์ฃผ์„ธ์š” ๐Ÿ˜„

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰