Why is aws-sdk-ruby connecting to '169.254.169.254' on initialization? - ruby

I installed the gem webmock, which blocks external connections during the test suite. After I installed it, I got an unexpected result when running the test suite.
I'm somewhat confused why the aws-sdk needs to connect to 169.254.169.254 on initialization?
rspec spec/models/concerns/posconcern_spec.rb
[Coveralls] Set up the SimpleCov formatter.
[Coveralls] Using SimpleCov's 'rails' settings.
An error occurred while loading ./spec/models/concerns/posconcern_spec.rb.
Failure/Error: require File.expand_path('../../config/environment', __FILE__)
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET http://169.254.169.254/latest/meta-data/iam/security-credentials/ with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}
You can stub this request with the following snippet:
stub_request(:get, "http://169.254.169.254/latest/meta-data/iam/security-credentials/").
with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
to_return(status: 200, body: "", headers: {})
============================================================
# /home/andey/.rvm/gems/ruby-2.3.4/gems/webmock-3.1.0/lib/webmock/http_lib_adapters/net_http.rb:114:in `request'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:109:in `http_get'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:90:in `block (2 levels) in get_credentials'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:105:in `open_connection'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:88:in `block in get_credentials'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:121:in `retry_errors'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:87:in `get_credentials'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:73:in `block in refresh'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:121:in `retry_errors'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:72:in `refresh'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/refreshing_credentials.rb:20:in `initialize'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/instance_profile_credentials.rb:51:in `initialize'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/credential_provider_chain.rb:90:in `new'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/credential_provider_chain.rb:90:in `instance_profile_credentials'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/credential_provider_chain.rb:12:in `block in resolve'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/credential_provider_chain.rb:11:in `each'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/credential_provider_chain.rb:11:in `resolve'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/aws-sdk-core/plugins/request_signer.rb:37:in `block in <class:RequestSigner>'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:70:in `call'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:205:in `block in resolve_defaults'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:57:in `each'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:57:in `each'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:204:in `resolve_defaults'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:200:in `value_at'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:189:in `block in resolve'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:189:in `resolve'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:177:in `apply_defaults'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/configuration.rb:150:in `build!'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/base.rb:68:in `build_config'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/base.rb:19:in `initialize'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/aws-sdk-core-2.10.52/lib/seahorse/client/base.rb:105:in `new'
# ./config/initializers/aws.rb:1:in `<top (required)>'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:268:in `load'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:268:in `block in load'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:240:in `load_dependency'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/activesupport-4.2.9/lib/active_support/dependencies.rb:268:in `load'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/engine.rb:652:in `block in load_config_initializer'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/activesupport-4.2.9/lib/active_support/notifications.rb:166:in `instrument'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/engine.rb:651:in `load_config_initializer'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/engine.rb:616:in `block (2 levels) in <class:Engine>'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/engine.rb:615:in `each'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/engine.rb:615:in `block in <class:Engine>'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/initializable.rb:30:in `instance_exec'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/initializable.rb:30:in `run'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/initializable.rb:55:in `block in run_initializers'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/initializable.rb:44:in `each'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/initializable.rb:44:in `tsort_each_child'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/initializable.rb:54:in `run_initializers'
# /home/andey/.rvm/gems/ruby-2.3.4/gems/railties-4.2.9/lib/rails/application.rb:352:in `initialize!'
# ./config/environment.rb:5:in `<top (required)>'
# ./spec/rails_helper.rb:3:in `require'
# ./spec/rails_helper.rb:3:in `<top (required)>'
# ./spec/models/concerns/posconcern_spec.rb:1:in `require'
# ./spec/models/concerns/posconcern_spec.rb:1:in `<top (required)>'
Relevant link to repo:
https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb#L45

It is trying to connect to the AWS metadata server to get the AWS credentials. All AWS servers should be able to connect to the internal metadata server.
I installed the gem webmock, which blocks external connections during
the test suite
How are you blocking it? Firewall? Add a rule to allow traffic to 169.254.169.254 or stub it.
The script is trying to connect to AWS services. For that it needs credentials which can be provided in many ways. One way is to use AWS IAM role and fetch the credentials dynamically from the metadata server (169.254.169.254). Your script is connecting to 169.254.169.254 to fetch the credentials. It can be used to connect to AWS services later.

This is a follow up to #helloV 's answer.
Full documentation on
http://169.254.169.254/latest/meta-data/iam/security-credentials/
An application on the instance retrieves the security credentials
provided by the role from the instance metadata item
iam/security-credentials/role-name. The application is granted the
permissions for the actions and resources that you've defined for the
role through the security credentials associated with the role. These
security credentials are temporary and we rotate them automatically.
We make new credentials available at least five minutes prior to the
expiration of the old credentials.
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#instance-metadata-security-credentials

Had a tough time researching on how to stub it. Will share my findings here hope it'll help other people.
Since AWS uses service name to fetch credentials for multiple services such as S3, any IAM Role, SQS etc.
But when dealing with IAM roles AWS hits http://169.254.169.254/latest/meta-data/iam/security-credentials/ which return the role name attached onto the machine and using the response of the same it hits the curl http://169.254.169.254/latest/meta-data/iam/security-credentials/#{role}.
So we need to stub both of the curls in order to successfully mock the IAM role. Below is the code for the same.
def self.auth(params = {})
status = params[:status].presence || 200
url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/'
WebMock.stub_request(:get, url)
.with({headers: request_headers}.compact)
.to_return(status: status, body: 'SampleRole', headers: {})
end
def self.role_auth(role = 'SampleRole')
url = "http://169.254.169.254/latest/meta-data/iam/security-credentials/#{role}"
WebMock.stub_request(:get, url)
.with({headers: request_headers}.compact)
.to_return(status: 200, body: sample_response, headers: {})
end
private
def self.request_headers
{
'Accept': '*/*',
'Accept-Encoding': 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
'User-Agent': 'aws-sdk-ruby3/3.21.2'
}.with_indifferent_access
end
def self.sample_response
{
Code: 'Success',
LastUpdated: '2020-05-08T05:55:23Z',
Type: 'AWS-HMAC',
AccessKeyId: Faker::Lorem.characters(10),
SecretAccessKey: Faker::Lorem.characters(20),
Token: Faker::Lorem.characters(60),
Expiration: '2020-05-08T12:00:45Z'
}.to_json
end
So whenver any rspec uses InstanceCredentials provider you need to stub both of the above defined requests in before block of each of the rspec.
Example:
before do
ApiStub::IamCred.auth
ApiStub::IamCred.role_auth
end
Hope it helps.
Happy Coding

There are some good answers in this thread on how to stub this. Another alternative (a better one?) is to eliminate the need for thE SDK to check for credentials from the instance meta data service. You can do this by providing credentials. These can be fake. A simple way to do this would be to provide credential via the ENV (e.g. ENV['AWS_ACCESS_TOKEN'] and ENV['SECRET_ACCESS_TOKEN']).

Related

undefined method `query_options' for nil:NilClass, resque, unicorn, Rails 4, mysql

I get this error when i try to send an update mail.
undefined method `query_options' for nil:NilClass
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/connection_adapters/mysql2_adapter.rb:218:in `execute'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:300:in `execute_and_free'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:461:in `columns'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/connection_adapters/schema_cache.rb:114:in `block in prepare_default_proc'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/connection_adapters/schema_cache.rb:56:in `yield'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/connection_adapters/schema_cache.rb:56:in `default'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/connection_adapters/schema_cache.rb:56:in `columns'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/model_schema.rb:208:in `columns'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/model_schema.rb:217:in `columns_hash'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/dynamic_matchers.rb:60:in `block in valid?'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/dynamic_matchers.rb:60:in `each'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/dynamic_matchers.rb:60:in `all?'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/dynamic_matchers.rb:60:in `valid?'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activerecord-4.0.0/lib/active_record/dynamic_matchers.rb:18:in `method_missing'
/home/user_name/work/app_name/app/mailers/user_mailer.rb:12:in `update_message'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/actionpack-4.0.0/lib/abstract_controller/base.rb:189:in `process_action'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/actionpack-4.0.0/lib/abstract_controller/callbacks.rb:18:in `block in process_action'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:373:in `_run__1485230712795781007__process_action__callbacks'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/activesupport-4.0.0/lib/active_support/callbacks.rb:80:in `run_callbacks'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/actionpack-4.0.0/lib/abstract_controller/callbacks.rb:17:in `process_action'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/actionpack-4.0.0/lib/abstract_controller/base.rb:136:in `process'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/actionpack-4.0.0/lib/abstract_controller/rendering.rb:44:in `process'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/actionmailer-4.0.0/lib/action_mailer/base.rb:503:in `process'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/actionmailer-4.0.0/lib/action_mailer/base.rb:497:in `initialize'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/resque_mailer-2.2.6/lib/resque_mailer.rb:48:in `new'
/home/user_name/.rvm/gems/ruby-1.9.3-p551#app_name/gems/resque_mailer-2.2.6/lib/resque_mailer.rb:48:in `perform'
We are using Rails 4, unicorn 4.7 and resque 1.25.
For sending emails on the application we use different mailer.
The recovery email that uses the object to send the emails, works fine, but the email that sends the profile update, which queries the user by id, does not work and throws the above error.
This is the unicorn config:
worker_processes 1
working_directory "correct/path" # available in 0.94.0+
listen "correct/path", :backlog => 64
timeout 30
pid "correct/path"
stderr_path "correct/path"
stdout_path "correct/path"
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true
before_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
after_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
I have tried various answer from stack overflow, or Github issues with no result.
I finally fixed the problem, I had to restart the worker(s) after removing the octopus gem.
That error message is because octopus does not work very well out of the box with unicorn so I did configured it, but I forgot to close the worker, and it kept the octopus setting thus throwing this error.
Unfortunately I could not find a good way to use octopus with our applications because we got this error, that as far as I could see is related to Resque, more precisely when any of the workers forks a process, it fails to connect to an outside database, ex: x model connecting to y database., which works well for the application using octopus_connect, but not for the workers.
Our solution was to use instead taskrabbit/makara as the connection proxy.

Ruby Vacuum Gem Amazon Product API "400 Bad Request Error"

I trying to make example from Vacuum documentation work, but all I got is: Expected(200)<=>Actual(400 Bad Request)
require 'vacuum'
request = Vacuum.new ('GB')
request.configure(
aws_access_key_id: 'XXXXXXX',
aws_secret_access_key: 'XXXXXXXX',
associate_tag: 'XXXXXXXX'
)
response = request.item_lookup(
query: {
'ItemId' => '0679753354'
}
)
puts response
and I got:
C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/excon-0.45.4/lib/excon/middlewares/expects.rb:6:in `response_call': Expected(200) <=> Actual(400 Bad Request) (Excon::Errors::BadRequest)
from C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/excon-0.45.4/lib/excon/middl ewares/response_parser.rb:8:in `response_call'
from C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/excon-0.45.4/lib/excon/connection.rb:372:in `response'
from C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/excon-0.45.4/lib/excon/connection.rb:236:in `request'
from (eval):6:in `get'
from C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/vacuum-1.4.0/lib/vacuum/request.rb:111:in `block (2 levels) in <class:Request>'
from vacuum.rb:11:in `<main>'
I just installed this gem, created Access Keys Pair and can't move any further. Forgive me being completely new with Ruby.

TypeError: wrong argument type class (expected module) in rspec

i'm developing a simple net application (packed as a gem) to learn Ruby and TDD.
I have this class (receiver.rb):
require 'eventmachine'
class Receiver < EM::Connection
def initialize(port)
EM.run do
EM.open_datagram_socket('0.0.0.0', port, self)
end
end
end
And this test (receiver_spec.rb):
require "spec_helper"
require "net/receiver"
describe "Receiver" do
it "can istantiate" do
#rec = Receiver.new(500)
end
end
Anyway, when i run rspec it prints out this:
1) Receiver can istantiate
Failure/Error: #rec = Receiver.new(500)
TypeError:
wrong argument type Receiver (expected Module)
# /var/lib/gems/1.9.1/gems/eventmachine- 1.0.7/lib/eventmachine.rb:1535:in `include'
# /var/lib/gems/1.9.1/gems/eventmachine-1.0.7/lib/eventmachine.rb:1535:in `block in klass_from_handler'
# /var/lib/gems/1.9.1/gems/eventmachine-1.0.7/lib/eventmachine.rb:1535:in `initialize'
# /var/lib/gems/1.9.1/gems/eventmachine-1.0.7/lib/eventmachine.rb:1535:in `new'
# /var/lib/gems/1.9.1/gems/eventmachine-1.0.7/lib/eventmachine.rb:1535:in `klass_from_handler'
# /var/lib/gems/1.9.1/gems/eventmachine- 1.0.7/lib/eventmachine.rb:867:in `open_datagram_socket'
# ./lib/rppc/net/receiver.rb:9:in `block in initialize'
# /var/lib/gems/1.9.1/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `call'
# /var/lib/gems/1.9.1/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `run_machine'
# /var/lib/gems/1.9.1/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `run'
# ./lib/rppc/net/receiver.rb:8:in `initialize'
# ./spec/net/receiver_spec.rb:6:in `new'
# ./spec/net/receiver_spec.rb:6:in `block (2 levels) in <top (required)>'
I'm quite new to the ruby environment, so if i missed something let me know.
I'm not sure what documentation you're working from, but it appears the open_datagram_socket requires a Module and cannot accept a Class as the third (handler) argument.
Per the comment in http://www.rubydoc.info/github/eventmachine/eventmachine/EventMachine.open_datagram_socket, it appears this restriction may have been loosened in a later version of EventMachine

Ruby and Https: A socket operation was attempted to an unreachable network

I'm trying to download all of my class notes from coursera. I figured that since I'm learning ruby this would be a good practice exercise, downloading all the PDFs they have for future use. Unfortunately though, I'm getting an exception saying ruby can't connect for some reason. Here is my code:
require 'net/http'
module Coursera
class Downloader
attr_accessor :page_url
attr_accessor :destination_directory
attr_accessor :cookie
def initialize(page_url,dest,cookie)
#page_url=page_url
#destination_directory = dest
#cookie=cookie
end
def download
puts #page_url
request = Net::HTTP::Get.new(#page_url)
puts #cookie.encoding
request['Cookie']=#cookie
# the line below is where the exception is thrown
res = Net::HTTP.start(#page_url.hostname, use_ssl=true,#page_url.port) {|http|
http.request(request)
}
html_page = res.body
pattern = /http[^\"]+\.pdf/
i=0
while (match = pattern.match(html_page,i)) != nil do
# 0 is the entire string.
url_string = match[0]
# make sure that 'i' is updated
i = match.begin(0)+1
# we want just the name of the file.
j = url_string.rindex("/")
filename = url_string[j+1..url_string.length]
destination = #destination_directory+"\\"+filename
# I want to download that resource to that file.
uri = URI(url_string)
res = Net::HTTP.get_response(uri)
# write that body to the file
f=File.new(destination,mode="w")
f.print(res.body)
end
end
end
end
page_url_string = 'https://class.coursera.org/datasci-002/lecture'
puts page_url_string.encoding
dest='C:\\Users\\michael\\training material\\data_science'
page_url=URI(page_url_string)
# I copied this from my browsers developer tools, I'm omitting it since
# it's long and has my session key in it
cookie="..."
downloader = Coursera::Downloader.new(page_url,dest,cookie)
downloader.download
At runtime the following is written to console:
Fast Debugger (ruby-debug-ide 0.4.22, debase 0.0.9) listens on 127.0.0.1:65485
UTF-8
https://class.coursera.org/datasci-002/lecture
UTF-8
Uncaught exception: A socket operation was attempted to an unreachable network. - connect(2)
C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:878:in `initialize'
C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:878:in `open'
C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:878:in `block in connect'
C:/Ruby200-x64/lib/ruby/2.0.0/timeout.rb:52:in `timeout'
C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:877:in `connect'
C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:862:in `do_start'
C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:851:in `start'
C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:582:in `start'
C:/Users/michael/Documents/Aptana Studio 3 Workspace/practice/CourseraDownloader.rb:20:in `download'
C:/Users/michael/Documents/Aptana Studio 3 Workspace/practice/CourseraDownloader.rb:52:in `<top (required)>'
C:/Ruby200-x64/bin/rdebug-ide:23:in `load'
C:/Ruby200-x64/bin/rdebug-ide:23:in `<main>'
C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:878:in `initialize': A socket operation was attempted to an unreachable network. - connect(2) (Errno::ENETUNREACH)
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:878:in `open'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:878:in `block in connect'
from C:/Ruby200-x64/lib/ruby/2.0.0/timeout.rb:52:in `timeout'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:877:in `connect'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:862:in `do_start'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:851:in `start'
from C:/Ruby200-x64/lib/ruby/2.0.0/net/http.rb:582:in `start'
from C:/Users/michael/Documents/Aptana Studio 3 Workspace/practice/CourseraDownloader.rb:20:in `download'
from C:/Users/michael/Documents/Aptana Studio 3 Workspace/practice/CourseraDownloader.rb:52:in `<top (required)>'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide.rb:86:in `debug_load'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/ruby-debug-ide-0.4.22/lib/ruby-debug-ide.rb:86:in `debug_program'
from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/ruby-debug-ide-0.4.22/bin/rdebug-ide:110:in `<top (required)>'
from C:/Ruby200-x64/bin/rdebug-ide:23:in `load'
from C:/Ruby200-x64/bin/rdebug-ide:23:in `<main>'
I was following instructions here to write all the HTTP code. As far as I can see I'm following them ver-batim.
I'm using Windows 7, ruby 2.0.0p481, and Aptana Studio 3. When I copy the url into my browser it goes straight to the page without a problem. When I look at the request headers in my browser for that url, I don't see anything else I think I'm missing. I also tried setting the Host and Referer request headers, it made no difference.
I am out of ideas, and have already searched Stack Overflow for similar questions but that didn't help. Please let me know what I'm missing.
So, I had this same error message with a different project and the problem was that my machine literally couldn't connect to the IP / Port. Have you tried connecting with curl? If it works in your browser, it could be using a proxy or something to actually get there. Testing the URL with curl solved the problem for me.

Rspec any_instance stub causing error undefined method __rspec_original_dup

I'm trying to stub out a Class method for any instance of the class (via any_instance). My tests run through successfully, but at the end of the test when rspec is trying to reset the any_instance stub, it throws an error (Unable to find matching line from backtrace). Here's the apparent culprit line of code (removing it removes the error):
Confetti::Config.any_instance.stub(:write_info)
The full error is below. Seems like stub should've (but fails to) created the __rspec_original_dup method, and when the reset happens, it can't find the expected method.
Failure/Error: Unable to find matching line from backtrace
NameError:
undefined method `__rspec_original_dup' for class `Confetti::Config'
# /Library/Ruby/Gems/1.8/gems/rspec-mocks-2.11.1/lib/rspec/mocks/any_instance.rb:73:in `alias_method'
# /Library/Ruby/Gems/1.8/gems/rspec-mocks-2.11.1/lib/rspec/mocks/any_instance.rb:73:in `restore_dup'
# /Library/Ruby/Gems/1.8/gems/rspec-mocks-2.11.1/lib/rspec/mocks/any_instance.rb:72:in `class_eval'
# /Library/Ruby/Gems/1.8/gems/rspec-mocks-2.11.1/lib/rspec/mocks/any_instance.rb:72:in `restore_dup'
# /Library/Ruby/Gems/1.8/gems/rspec-mocks-2.11.1/lib/rspec/mocks/any_instance.rb:46:in `rspec_reset'
# /Library/Ruby/Gems/1.8/gems/rspec-mocks-2.11.1/lib/rspec/mocks/space.rb:17:in `reset_all'
# /Library/Ruby/Gems/1.8/gems/rspec-mocks-2.11.1/lib/rspec/mocks/space.rb:16:in `each'
# /Library/Ruby/Gems/1.8/gems/rspec-mocks-2.11.1/lib/rspec/mocks/space.rb:16:in `reset_all'
# /Library/Ruby/Gems/1.8/gems/rspec-mocks-2.11.1/lib/rspec/mocks.rb:23:in `teardown'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/mocking/with_rspec.rb:18:in `teardown_mocks_for_rspec'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:308:in `run_after_each'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:119:in `run'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:253:in `with_around_each_hooks'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:110:in `run'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:378:in `run_examples'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:374:in `map'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:374:in `run_examples'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:360:in `run'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:361:in `run'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:361:in `map'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:361:in `run'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:28:in `run'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:28:in `map'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:28:in `run'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/reporter.rb:34:in `report'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:25:in `run'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:69:in `run'
# /Library/Ruby/Gems/1.8/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:8:in `autorun'
# /usr/bin/rspec:19
I solved this by simply using Rspec v2.10.0 instead of v2.11.0:
gem 'rspec', '~> 2.10.0'
From the links that Henrik provided, it sounds like they may release a bugfix for Rspec. Watch this issue for more information. In the meantime, downgrading solved the issue for me.
(Thanks for your work in helping me figure this out, Henrik.)

Resources