Sample server & client for Rack hijack proxy questions - ruby

I've got sample app for hijack proxy server
io_lambda = lambda{ |io|
3.times do |i|
puts i
io.write "David\r\n"
end
io.close
}
run lambda{ |req|
[
200,
[ [ "rack.hijack", io_lambda ] ],
[""]
]
}
and starting it
rackup config.ru -p 3000
Now I trying to code client for it. First, just curl it:
curl http://localhost:3000 -vv
and get following client output:
* Rebuilt URL to: http://localhost:3000/
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
<
David
David
* transfer closed with outstanding read data remaining
* stopped the pause stream!
* Closing connection 0
curl: (18) transfer closed with outstanding read data remaining
now, with httparty:
require 'rubygems'
require 'bundler/setup'
Bundler.require(:default)
response = HTTParty.get('http://localhost:3000')
puts response.body, response.code, response.message, response.headers.inspect
I get:
→ ruby httparty-client.rb
Traceback (most recent call last):
19: from httparty-client.rb:5:in `<main>'
18: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:627:in `get'
17: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:508:in `get'
16: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty.rb:594:in `perform_request'
15: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/httparty-0.17.1/lib/httparty/request.rb:145:in `perform'
14: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1470:in `request'
13: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:920:in `start'
12: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1472:in `block in request'
11: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1479:in `request'
10: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1517:in `transport_request'
9: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:166:in `reading_body'
8: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:229:in `body'
7: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:204:in `read_body'
6: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:283:in `read_body_0'
5: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:278:in `inflater'
4: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:285:in `block in read_body_0'
3: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `read_chunked'
2: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `ensure in read_chunked'
1: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:159:in `read'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)
last try with net/http:
require 'net/http'
streamURL = 'http://localhost:3000'
uri = URI.parse(streamURL)
Net::HTTP.start(uri.host, uri.port) do |http|
request = Net::HTTP::Get.new uri.request_uri
http.request request do |response|
response.read_body do |chunk|
#We get the data here chunk-by-chunk
puts chunk
end
end
end
I get:
→ ruby net-http-client.rb
David
David
David
David
Traceback (most recent call last):
16: from net-http-client.rb:7:in `<main>'
15: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:605:in `start'
14: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:920:in `start'
13: from net-http-client.rb:10:in `block in <main>'
12: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1479:in `request'
11: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1517:in `transport_request'
10: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:165:in `reading_body'
9: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:1518:in `block in transport_request'
8: from net-http-client.rb:11:in `block (2 levels) in <main>'
7: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:204:in `read_body'
6: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:283:in `read_body_0'
5: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:278:in `inflater'
4: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:285:in `block in read_body_0'
3: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `read_chunked'
2: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http/response.rb:324:in `ensure in read_chunked'
1: from /Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:159:in `read'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)
Could someone explain me:
1) Why curl return David x2, httparty - nothing and net/http - David x4, while server sent 5? Also I'm curious why httparty and net/http results differ, because one uses another under the hood.
2) Why in all cases we have an error (transfer closed with outstanding read data remaining and end of file reached (EOFError))?

Have figured it out. Headers do matter. This version makes it work for all clients
io_lambda = lambda{ |io|
5.times do |i|
puts i
io.write "David\r\n"
sleep 1
end
io.close
}
app = lambda do |env|
response_headers = {}
response_headers['Transfer-Encoding'] = 'binary'
response_headers["Content-Type"] = "text/plain"
response_headers["rack.hijack"] = io_lambda
[200, response_headers, nil]
end
run app

Related

how to fix it?(it happened when my friend run /stop in chat with the telegram bot)(since then the bot is always gives this error...)

ruby .\bot.rb
#: /stop
Traceback (most recent call last):
8: from ./bot.rb:7:in `<main>'
7: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/telegram_bot-0.0.8/lib/telegram_bot/bot.rb:32:in `get_updates'
6: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/telegram_bot-0.0.8/lib/telegram_bot/bot.rb:32:in `loop'
5: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/telegram_bot-0.0.8/lib/telegram_bot/bot.rb:34:in `block in get_updates'
4: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/telegram_bot-0.0.8/lib/telegram_bot/bot.rb:34:in `each'
3: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/telegram_bot-0.0.8/lib/telegram_bot/bot.rb:37:in `block (2 levels) in get_updates'
2: from ./bot.rb:11:in `block in <main>'
1: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/telegram_bot-0.0.8/lib/telegram_bot/message.rb:16:in `reply'
./bot.rb:19:in `block (2 levels) in <main>': undefined local variable or method `commands' for main:Object (NameError)
Did you mean? command``
the whole code:
require 'telegram_bot'
token ="my bot token"
bot = TelegramBot.new(token: token)
bot.get_updates(fail_silently: true) do |message|
puts "##{message.from.username}: #{message.text}"
command = message.get_command_for(bot)
message.reply do |reply|
case command
when /start/i
reply.text = "All I can do is say hello. Try the /greet command."
when /greet/i
greetings = ['bonjour', 'hola', 'hallo', 'sveiki', 'namaste', 'salaam', 'szia', 'halo', 'ciao']
reply.text = "#{greetings.sample.capitalize}, #{message.from.first_name}!"
else
reply.text = "I have no idea what #{commands.inspect} means."
end
puts "sending #{reply.text.inspect} to ##{message.from.username}"
reply.send_with(bot)
end
end

ruby net/http: How to fix EOFError on HTTPS POST request

I'm writing a script to get data from GitHub v4 API. But my Ruby script fails on EOFError. How to avoid EOFError?
The following code fails on end of file reached (EOFError). I run the script 10 times, but no one suceeded.
require 'net/http'
require 'uri'
uri = URI.parse 'https://api.github.com/graphql'
header = {
'Authorization' => 'bearer MY_GITHUB_TOKEN',
}
Net::HTTP.new uri.host, uri.port do |http|
http.use_ssl = true
end.start do |http|
req = Net::HTTP::Post.new uri.path, header
req.body = " \
{ \
\"query\": \"query { viewer { login }}\" \
} \
"
http.request req do |res|
p res.code
p res.message
p res.body
p res.read_body
res.read_body do |body|
p body
end
end
end
I'm using Ruby ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
compiled by rbenv-build. I got following stack trace.
Traceback (most recent call last):
11: from tmp.rb:20:in `<main>'
10: from /home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/http.rb:920:in `start'
9: from tmp.rb:31:in `block in <main>'
8: from /home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/http.rb:1479:in `request'
7: from /home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/http.rb:1506:in `transport_request'
6: from /home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/http.rb:1506:in `catch'
5: from /home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/http.rb:1509:in `block in transport_request'
4: from /home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/http/response.rb:29:in `read_new'
3: from /home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/http/response.rb:40:in `read_status_line'
2: from /home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/protocol.rb:201:in `readline'
1: from /home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/protocol.rb:191:in `readuntil'
/home/yuntan/.rbenv/versions/2.6.3/lib/ruby/2.6.0/net/protocol.rb:225:in `rbuf_fill': end of file reached (EOFError)
Due to my wrong guess.
Net::HTTP.new does not take any block, so the code below
Net::HTTP.new uri.host, uri.port do |http|
http.use_ssl = true
end.start ...
should be
(Net::HTTP.new uri.host, uri.port).tap do |http|
http.use_ssl = true
end.start ...

Ruby - Capybara recording test execution videos

I am trying to record and save in a video format my execution tests using Capybara. My tests are passing however I'm getting several errors in my Mac terminal. Also the videos are not being recorded/saved.
SPEC_HELPER.RB
require 'capybara'
require 'capybara/rspec'
require 'capybara/dsl'
require 'selenium-webdriver'
require 'headless'
headless = Headless.new
headless.start
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
config.include Capybara::DSL
config.before(:example) do
headless.video.start_capture
page.current_window.resize_to(1200, 800)
end
config.after(:example) do |e, scenario|
name = e.description.gsub(/[^A-Za-z0-9 ]/, '').tr(' ', '_')
d = Time.now.strftime("%F-%T")
page.save_screenshot('log/' + name + '-' + d.to_s + '.png')
headless.video.stop_and_save('log/' + name + '-' + d.to_s + '.mov')
end
end
Capybara.configure do |config|
config.default_driver = :selenium_chrome_headless
config.run_server = false
end
Capybara.default_max_wait_time = 10
MAC TERMINAL ERROR
Finished in 19.68 seconds (files took 0.82221 seconds to load)
4 examples, 0 failures
Traceback (most recent call last):
8: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/capybara-3.14.0/lib/capybara/selenium/driver.rb:374:in `block in setup_exit_handler'
7: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/capybara-3.14.0/lib/capybara/selenium/driver.rb:208:in `quit'
6: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/chrome/driver.rb:62:in `quit'
5: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:81:in `stop'
4: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:122:in `stop_process'
3: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:12:in `stop'
2: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:61:in `send_term'
1: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `send_signal'
/Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `kill': Operation not permitted (Errno::EPERM)
Traceback (most recent call last):
8: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/capybara-3.14.0/lib/capybara/selenium/driver.rb:374:in `block in setup_exit_handler'
7: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/capybara-3.14.0/lib/capybara/selenium/driver.rb:208:in `quit'
6: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/chrome/driver.rb:62:in `quit'
5: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:81:in `stop'
4: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:122:in `stop_process'
3: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:12:in `stop'
2: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:61:in `send_term'
1: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `send_signal'
/Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `kill': Operation not permitted (Errno::EPERM)
12: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/platform.rb:141:in `block in exit_hook'
11: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:67:in `block in start'
10: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:77:in `stop'
9: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:128:in `stop_server'
8: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:104:in `connect_to_server'
7: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:605:in `start'
6: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:919:in `start'
5: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:930:in `do_start'
4: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:945:in `connect'
3: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/timeout.rb:103:in `timeout'
2: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/timeout.rb:93:in `block in timeout'
1: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:946:in `block in connect'
/Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/2.6.0/net/http.rb:949:in `rescue in block in connect': Failed to open TCP connection to 127.0.0.1:9515 (Connection refused - connect(2) for "127.0.0.1" port 9515) (Errno::ECONNREFUSED)
8: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/platform.rb:141:in `block in exit_hook'
7: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:67:in `block in start'
6: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:81:in `stop'
5: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:81:in `ensure in stop'
4: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.141.0/lib/selenium/webdriver/common/service.rb:122:in `stop_process'
3: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:12:in `stop'
2: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:61:in `send_term'
1: from /Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `send_signal'
/Users/dsanders/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/childprocess-0.9.0/lib/childprocess/unix/process.rb:72:in `kill': Operation not permitted (Errno::EPERM)
Try replacing these lines
page.save_screenshot('log/' + name + '-' + d.to_s + '.png')
headless.video.stop_and_save('log/' + name + '-' + d.to_s + '.mov')
With
#please note for this ../ from this file to root just reach to root of the project. in my case root
root_path = File.join(File.dirname(__FILE__), "../")
page.save_screenshot(File.join(root_path,'log/' + name + '-' + d.to_s + '.png'))
headless.video.stop_and_save(File.join(root_path,'log/' + name + '-' + d.to_s + '.mov'))
my searching show that Mac is not compatible with Xvfb which is something that Headless uses. Even if you get pass the rails error, you might not pass this one.

Ruby: run irb from trap context?

The following example is given in the book Programming Ruby 1.9 & 2.0:
require 'irb'
trap "INT" do
IRB.start
end
count = 0
loop do
count += 1
puts count
puts "Value = #{#value}" if defined? #value
sleep 1
end
Unfortunately, if I run this code with my Ruby 2.5.1 setup I get the following ThreadError (run_irb.rb is the name of the file with the code above):
24: from run_irb.rb:8:in `<main>'
23: from run_irb.rb:8:in `loop'
22: from run_irb.rb:12:in `block in <main>'
21: from run_irb.rb:12:in `sleep'
20: from run_irb.rb:4:in `block in <main>'
19: from /usr/lib/ruby/2.5.0/irb.rb:376:in `start'
18: from /usr/lib/ruby/2.5.0/irb/init.rb:17:in `setup'
17: from /usr/lib/ruby/2.5.0/irb/init.rb:112:in `init_config'
16: from /usr/lib/ruby/2.5.0/irb/init.rb:112:in `new'
15: from /usr/lib/ruby/2.5.0/irb/locale.rb:32:in `initialize'
14: from /usr/lib/ruby/2.5.0/irb/locale.rb:108:in `load'
13: from /usr/lib/ruby/2.5.0/irb/locale.rb:124:in `find'
12: from /usr/lib/ruby/2.5.0/irb/locale.rb:145:in `search_file'
11: from /usr/lib/ruby/2.5.0/irb/locale.rb:157:in `each_localized_path'
10: from /usr/lib/ruby/2.5.0/irb/locale.rb:167:in `each_sublocale'
9: from /usr/lib/ruby/2.5.0/irb/locale.rb:158:in `block in each_localized_path'
8: from /usr/lib/ruby/2.5.0/irb/locale.rb:150:in `block in search_file'
7: from /usr/lib/ruby/2.5.0/rubygems.rb:213:in `try_activate'
6: from /usr/lib/ruby/2.5.0/rubygems/specification.rb:1063:in `find_by_path'
5: from /usr/lib/ruby/2.5.0/rubygems/specification.rb:1063:in `find'
4: from /usr/lib/ruby/2.5.0/rubygems/specification.rb:1063:in `each'
3: from /usr/lib/ruby/2.5.0/rubygems/specification.rb:1064:in `block in find_by_path'
2: from /usr/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:40:in `require'
1: from /usr/lib/ruby/2.5.0/monitor.rb:185:in `mon_enter'
/usr/lib/ruby/2.5.0/monitor.rb:185:in `lock': can't be called from trap context (ThreadError)
Is there a way to get the irb run from the trap context with Ruby 2.5.1?
Ruby 2.0 does not allow Mutex#lock within a signal handler
According to this bug 7917 in ruby lang this is the "expected" behaviour. So you've basically found a language bug and a book bug because the author didn't test this example in ruby 2.0 (confirmed that it works in 1.9.)
An alternative method is to use an exception/rescue and execute an IRB session from an interrupt like this:
require 'irb'
count = 0
loop do
count += 1
puts count
puts "Value = #{#value}" if defined? #value
sleep 1
rescue Interrupt => e
IRB.start
break
end
The above will correctly trap an interrupt and allow an IRB session to start. I did notice that IRB.start won't give you a local execution context, so you may want to look at binding.irb that let's you start a more useful debugging session like this:
$ ruby thread-test.rb
1
2
^C
[1] irb(main)>
From: /work/_scratch/thread-test/thread-test.rb # line 11 :
6: puts count
7: puts "Value = #{#value}" if defined? #value
8: sleep 1
9: rescue Interrupt => e
10: binding.irb
=> 11: break
12: end
[2] irb(main)> e
=> Interrupt
[3] irb(main)> count
=> 2
I found a few blog posts on handling Signals, Traps, and Rescues and Graceful Shutdown that may help you further with your problem.

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.

Resources