Closed stream (IO::Error) with HTTP::Client.get("https...") - crystal-lang

I am a bit confused with two codes.
uri = URI.parse("https://api.exchangeratesapi.io")
client = HTTP::Client.new(uri)
client.get("/latest?base=EUR") do |response|
p response.body_io.gets
end
It works as expected, but
response = HTTP::Client.get("https://api.exchangeratesapi.io/latest?base=EUR")
p response
failed with
Closed stream (IO::Error)
from /usr/share/crystal/src/io.cr:128:5 in 'check_open'
from /usr/share/crystal/src/io/buffered.cr:99:5 in 'peek'
from /usr/share/crystal/src/io.cr:632:37 in 'gets'
from /usr/share/crystal/src/io.cr:591:5 in 'gets'
from /usr/share/crystal/src/io.cr:814:5 in 'read_line:chomp'
from /usr/share/crystal/src/http/content.cr:205:7 in 'read_chunk_size'
from /usr/share/crystal/src/http/content.cr:187:26 in 'next_chunk'
from /usr/share/crystal/src/http/content.cr:120:7 in 'read'
from /usr/share/crystal/src/io.cr:554:29 in 'gets_to_end'
from /usr/share/crystal/src/http/client/response.cr:81:15 in 'consume_body_io'
from lib/webmock/src/webmock/core_ext.cr:12:7 in 'exec_internal'
from /usr/share/crystal/src/http/client.cr:576:5 in 'exec'
from /usr/share/crystal/src/http/client.cr:698:5 in 'exec'
from /usr/share/crystal/src/http/client.cr:730:7 in 'exec'
from /usr/share/crystal/src/http/client.cr:402:3 in ‚get
I use Crystal 0.33. Any idea what could fix second code?

In the log I see lib/webmock/src/webmock/core_ext.cr (which normally shouldn't be there), seems like its influence is causing the problem, and the code in isolation would just work.

Related

Message content checker does not work correctly discord.py

I am trying to make a bad words system for my server's custom bot, but it seems to only
listen for the first condition, ignoring the second one:
#bot.event
async def on_message(message):
###BAD WORDS CHECK
if message.author == bot.user:
pass
else:
if (any(x in message.content.lower() for x in words2)):
if "hack" or "crack" in message.content.lower():
await message.reply("I think you may be asking for illegal services or illegal advice. Please refer to rule #5 in the welcome channel!")
await message.channel.send("If you think this was a mistake please reply with $report!")
global CAN_REPORT
CAN_REPORT = "yes"
return
else:
pass
await bot.process_commands(message)
The bot will for some reason respond to any message containing any word from words2:
words2 = [
"instagram",
"snapchat",
"roblox",
"paypal",
"facebook",
"gmail",
"fortnite",
"minecraft",
"apex",
"youtube",
]
ignoring whether the message contains "hack", which leads to it replying to every message talking about social media or games. The goal is to check if BOTH conditions are true.
Any help is appreciated!
With this line if "hack" or "crack" in message.content.lower(): you are basically checking if either the string "hack" is true or if "crack" in message.content.lower() is true.
Thus the check always returns true, because "hack" will always be true.
The way to fix this would be something like this:
if "hack" in message.content.lower() or "crack" in message.content.lower():
Or, better yet, do it like you do in the first check:
word_list = ["hack", "crack"]
if any(x in message.content.lower() for x in word_list):
Its simple just add :
if words2 in message.content.lower():
await message.delete()
await ctx.send('that word is banned')

Granite ORM + fiber + mysql = Unexpected EOF (Exception)?

Is working with Fibers in Granite possible? I didn't have a reason to believe otherwise, until I attempted to write some code for it. I am attempting to learn to work with Fibers, so perhaps incorrect fiber implementation could also be a cause. The following code results in an exception. Any hints to resolve this?
lines = File.read_lines INVENTORY_FILE
channel = Channel(Int32).new(199)
lines[0..200].each do |line|
row_number += 1
proc = ->(line : NamedTuple(item_number: String) do
spawn do
sku = Sku.find_by :item_number, item_number
channel.send(1)
end
end
proc.call({ line: line })
end
199.times do |i|
channel.receive
end
The above results in the following repeated exception starting from the very first fiber's attempt to access the DB. I've ensured that MySQL is in a working state and that the code works when fibers are not in use:
Unexpected EOF (Exception)
from lib/mysql/src/mysql/read_packet.cr:38:18 in 'read_byte!'
from lib/mysql/src/mysql/read_packet.cr:63:5 in 'read_int'
from lib/mysql/src/mysql/packets.cr:13:7 in 'read'
from lib/mysql/src/mysql/connection.cr:63:14 in 'read_packet'
from lib/mysql/src/mysql/connection.cr:22:19 in 'initialize'
from lib/mysql/src/mysql/connection.cr:4:3 in 'new'
from lib/mysql/src/mysql/driver.cr:3:5 in 'build_connection'
from lib/db/src/db/pool.cr:255:3 in 'build_resource'
from lib/db/src/db/pool.cr:34:22 in 'checkout'
from lib/db/src/db/pool.cr:65:7 in 'checkout_some'
from lib/db/src/db/database.cr:99:7 in 'checkout_some'
from lib/db/src/db/pool_prepared_statement.cr:35:24 in 'build_statement'
from lib/db/src/db/pool_prepared_statement.cr:53:22 in 'initialize'
from lib/db/src/db/pool_prepared_statement.cr:11:5 in 'new'
from lib/db/src/db/database.cr:89:7 in 'build_prepared_statement'
from lib/db/src/db/database.cr:7:15 in 'fetch_or_build_prepared_statement'
from lib/db/src/db/session_methods.cr:23:9 in 'build'
from lib/db/src/db/query_methods.cr:38:7 in 'query'
from lib/granite/src/granite/querying.cr:53:12 in 'find_by'
from /usr/share/crystal/src/kernel.cr:0:3 in '~procProc(Nil)'
from /usr/share/crystal/src/fiber.cr:255:3 in 'run'
from /usr/share/crystal/src/concurrent.cr:0:3 in '~proc2Proc(Fiber, (IO::FileDescriptor | Nil))'
from ???

Unparsable MOF Query When Trying to Register Event

Update 2
I accepted an answer and asked a different question elsewhere, where I am still trying to get to the bottom of this.
I don't think that one-lining this query is the answer, as I am still not getting the required results (and multi-lining queries is allowed in .mof, as shown in the URLs in comments to the answer ...
Update
I rewrote the query as a one-liner as suggested, but still got the same error! As it was still talking about lines 11-19 I knew there must be another issue. After saving a new file with the change, I reran mofcomp and it appears to have loaded, but the event which I have subscribed to simply does not work.
I really feel that there is not enough documentation on this topic and it is hard to work out how I am meant to debug this - any help on this would be much appreciated, even if this means using a different more appropriate method.
I have the following .mof file, which I would like to use to register an event on my system :
#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
Name = "Event Filter Instance Name";
Query = "Select * from __InstanceCreationEvent within 1 "
"where targetInstance isa \"Cim_DirectoryContainsFile\" "
"and targetInstance.GroupComponent = \"Win32_Directory.Name=\"c:\\\\test\"\"";
QueryLanguage = "WQL";
EventNamespace = "Root\\Cimv2";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "TestConsumer";
ScriptingEngine = "VBScript";
ScriptText =
"Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n"
"Set objFile = objFSO.OpenTextFile(\"c:\\test\\Log.txt\", 8, True)\n"
"objFile.WriteLine Time & \" \" & \" File Created\"\n"
"objFile.Close\n";
// Specify any other relevant properties.
};
instance of __FilterToConsumerBinding
{
Filter = $EventFilter;
Consumer = $Consumer;
};
But whenever I run the command mfcomp myfile.mof I am getting this error:
Parsing MOF file: myfile.mof
MOF file has been successfully parsed
Storing data in the repository...
An error occurred while processing item 1 defined on lines 11 - 19 in file myfile.mof:
Error Number: 0x80041058, Facility: WMI
Description: Unparsable query.
Compiler returned error 0x80041058
This error appears to be caused by incorrect syntax in the query, but I don't understand where I have gone wrong with this - is anyone able to advise?
There are no string concatenation or line continuation characters being used in building "Query". To keep it simple, you could put the entire query on one line.

VCR is not recording cassettes on successful requests, only on failed ones

I have a simple test to fetch one Facebook object. I'm using Curl for the request.
it "gets an object from Facebook" do
VCR.use_cassette('facebook') do
url = "https://graph.facebook.com/<ID>?access_token=#{#access_token}&#{query_string}"
curl = Curl::Easy.perform(url)
expect(curl.body_str).to eql('<my object>')
end
end
My VCR configs are:
VCR.configure do |c|
c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
c.hook_into :webmock
end
When I run the tests, it passes, and the following is logged:
[Cassette: 'facebook'] Initialized with options: {:record=>:once, :match_requests_on=>[:method, :uri], :allow_unused_http_interactions=>true, :serialize_with=>:yaml, :persist_with=>:file_system}
[webmock] Handling request: [get https://graph.facebook.com/<ID>?access_token=<TOKEN>&fields=%5B%22id%22,%22account_id%22,%22name%22,%22campaign_group_status%22,%22objective%22%5D] (disabled: false)
[Cassette: 'facebook'] Initialized HTTPInteractionList with request matchers [:method, :uri] and 0 interaction(s): { }
[webmock] Identified request type (recordable) for [get https://graph.facebook.com/<ID>?access_token=<TOKEN>&fields=%5B%22id%22,%22account_id%22,%22name%22,%22campaign_group_status%22,%22objective%22%5D]
But the cassette is not recorded and the dir is empty. I've tried :record => :all to same results.
Usually, people encountered this error when using incompatible hooks for the library they're using, but that's not the case. I'm using webmock and curb.
Curiously, the cassette is recorded when there's a failure in the request, e.g., the token is expired. When it's fixed, and I delete the file, it's not recorded again.
Have anyone had the same problem?
It turns out that my code was a little more complicated than above and was executing a callback after perfoming the request. Something like:
success_handler = Proc.new { return c.body_str }
curl.on_success do |easy|
success_handler.call(easy)
end
That bypasses VCR and the file is not written. Refactoring the code to not use callbacks works.

Abort user request with Node.js/formidable

I'm using formidable to receive a file upload with node.js. I send some fields together with a file in a multipart request.
As soon as certain fields arrived, I'm able to validate the authenticity of the request for instance, and I would like to abort the whole request if this is not correct to avoid waisting resources.
I have not found a right way to abort the incoming request. I tried to use req.connection.destroy(); as follow:
form
.on('field', function(field, value) {
fields[field] = value;
if (!fields['token'] || !fields['id'] || !fields['timestamp']) {
return;
}
if (!validateToken(fields['token'], fields['id'], fields['timestamp'])) {
res.writeHead(401, {'Content-Type' : 'text/plain' });
res.end('Unauthorized');
req.connection.destroy();
}
})
However, this triggers the following error:
events.js:45
throw arguments[1]; // Unhandled 'error' event
^
Error: Cannot resume() closed Socket.
at Socket.resume (net.js:764:11)
at IncomingMessage.resume (http.js:254:15)
at IncomingForm.resume (node_modules/formidable/lib/incoming_form.js:52:11)
at node_modules/formidable/lib/incoming_form.js:181:12
at node_modules/formidable/lib/file.js:51:5
at fs.js:1048:7
at wrapper (fs.js:295:17)
I also tried req.connection.end() but the file keeps uploading.
Any thoughts? Thanks in advance!
The problem is that formidable didn't understand that you want it to stop. Try this:
req.connection.destroy();
req.connection.resume = function(){};
Of course, this is a somewhat ugly workaround, I'd open an issue on github.