Skip to content

Commit

Permalink
add proxy support to REST and Streaming clients
Browse files Browse the repository at this point in the history
  • Loading branch information
stve authored and sferik committed May 8, 2015
1 parent 60ca58f commit 8a1a39b
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 4 deletions.
27 changes: 27 additions & 0 deletions examples/Configuration.md
Expand Up @@ -124,3 +124,30 @@ For more information, see the documentation for the
[client]: http://rdoc.info/gems/twitter/Twitter/Client
[rest-client]: http://rdoc.info/gems/twitter/Twitter/REST/Client
[streaming-client]: http://rdoc.info/gems/twitter/Twitter/Streaming/Client

## Using a Proxy

If you'd like to connect via a proxy, a proxy can be configured by passing a
`Hash` to your configuration:

```ruby
proxy = {
host: '127.0.0.1',
port: 3328,
username: 'proxy_username',
password: 'proxy_password',
}

client = Twitter::REST::Client.new do |config|
config.consumer_key = "YOUR_CONSUMER_KEY"
config.consumer_secret = "YOUR_CONSUMER_SECRET"
config.access_token = "YOUR_ACCESS_TOKEN"
config.access_token_secret = "YOUR_ACCESS_SECRET"
config.proxy = proxy
end
```

Note that only a `host` and `port` are required, but a `username` and `password`
can be optionally configured for an authenticated proxy server. Proxies are
supported by both [`Twitter::REST::Client`][rest-client] and
[`Twitter::Streaming::Client`][streaming-client] classes.
16 changes: 14 additions & 2 deletions lib/twitter/rest/request.rb
Expand Up @@ -10,7 +10,7 @@

module Twitter
module REST
class Request
class Request # rubocop:disable Metrics/ClassLength
include Twitter::Utils
BASE_URL = 'https://api.twitter.com'
attr_accessor :client, :headers, :options, :path, :rate_limit,
Expand All @@ -33,7 +33,7 @@ def initialize(client, request_method, path, options = {})
# @return [Array, Hash]
def perform
options_key = @request_method == :get ? :params : :form
response = HTTP.with(@headers).public_send(@request_method, @uri.to_s, options_key => @options)
response = http_client.with(@headers).public_send(@request_method, @uri.to_s, options_key => @options)
response_body = symbolize_keys!(response.parse)
response_headers = response.headers
fail_or_return_response_body(response.code, response_body, response_headers)
Expand Down Expand Up @@ -105,6 +105,18 @@ def symbolize_keys!(object)
end
object
end

# @return [HTTP::Client, HTTP]
def http_client
@client.proxy ? HTTP.via(*proxy) : HTTP
end

# Return proxy values as a compacted array
#
# @return [Array]
def proxy
@client.proxy.values_at(:host, :port, :username, :password).compact
end
end
end
end
2 changes: 1 addition & 1 deletion lib/twitter/streaming/client.rb
Expand Up @@ -110,7 +110,7 @@ def before_request(&block)
def request(method, uri, params)
before_request.call
headers = Twitter::Headers.new(self, method, uri, params).request_headers
request = HTTP::Request.new(method, uri + '?' + to_url_params(params), headers)
request = HTTP::Request.new(method, uri + '?' + to_url_params(params), headers, proxy)
response = Streaming::Response.new do |data|
if item = Streaming::MessageParser.parse(data) # rubocop:disable AssignmentInCondition, IfUnlessModifier
yield(item)
Expand Down
18 changes: 17 additions & 1 deletion spec/twitter/rest/request_spec.rb
Expand Up @@ -3,7 +3,6 @@
describe Twitter::REST::Request do
before do
@client = Twitter::REST::Client.new(consumer_key: 'CK', consumer_secret: 'CS', access_token: 'AT', access_token_secret: 'AS')
@request = Twitter::REST::Request.new(@client, :get, '/path')
end

describe '#request' do
Expand All @@ -19,5 +18,22 @@
expect(a_request(:post, 'https://upload.twitter.com/1.1/media/upload.json')).to have_been_made
expect(a_post('/1.1/statuses/update.json').with(body: {status: 'Update', media_ids: '470030289822314497'})).to have_been_made
end

context 'when using a proxy' do
before do
@client = Twitter::REST::Client.new(consumer_key: 'CK', consumer_secret: 'CS', access_token: 'AT', access_token_secret: 'AS', proxy: {host: '127.0.0.1', port: 3328})
end
it 'requests via the proxy when no uploaded media is present' do
stub_post('/1.1/statuses/update.json').with(body: {status: 'Update'}).to_return(body: fixture('status.json'), headers: {content_type: 'application/json; charset=utf-8'})
expect(HTTP).to receive(:via).with('127.0.0.1', 3328).and_call_original
@client.update('Update')
end
it 'requests via the proxy when uploaded media is present' do
stub_request(:post, 'https://upload.twitter.com/1.1/media/upload.json').to_return(body: fixture('upload.json'), headers: {content_type: 'application/json; charset=utf-8'})
stub_post('/1.1/statuses/update.json').with(body: {status: 'Update', media_ids: '470030289822314497'}).to_return(body: fixture('status.json'), headers: {content_type: 'application/json; charset=utf-8'})
expect(HTTP).to receive(:via).with('127.0.0.1', 3328).twice.and_call_original
@client.update_with_media('Update', fixture('pbjt.gif'))
end
end
end
end
12 changes: 12 additions & 0 deletions spec/twitter/streaming/client_spec.rb
Expand Up @@ -119,4 +119,16 @@ def stream(_, response)
expect(objects[5].code).to eq('FALLING_BEHIND')
end
end

context 'when using a proxy' do
let(:proxy) { {host: '127.0.0.1', port: 3328} }
before do
@client = Twitter::Streaming::Client.new(consumer_key: 'CK', consumer_secret: 'CS', access_token: 'AT', access_token_secret: 'AS', proxy: proxy)
end
it 'requests via the proxy' do
@client.connection = FakeConnection.new(fixture('track_streaming.json'))
expect(HTTP::Request).to receive(:new).with(:get, 'https://stream.twitter.com:443/1.1/statuses/sample.json?', kind_of(Hash), proxy)
@client.sample {}
end
end
end

0 comments on commit 8a1a39b

Please sign in to comment.