Consider the following code snippet:
require "sqlite3"
db = SQLite3::Database.new "my.db"
p db.execute("select * from user where name = ?", ["my_user_name"])
This will outut the entry in the database where the user's name is "my_user_name". This works as intended.
Now consider this code snippet (config.ru):
require "rack/auth/basic"
require "sqlite3"
use Rack::Auth::Basic, "my authentication" do |username, password|
p username
p db.execute("select * from user where name = ?", [username])
end
run do |env|
[200, {}, []]
end
When I send a request to this server:
curl -X POST -v -ujomy:abc123 localhost:9292 -d ''
I see the following output in the terminal where I started the server (using rackup):
"my_user_name"
[]
So I now do not get a result back from my sql query.
When I insert this line before the db.execute statement:
username = "my_user_name"
Now I actually get a result back.
Replacing username
with username.to_s
also does not work.
So it seems that using the username variable provided by Rack does not work with sqlite? How is this even possible as username.class
is String
? The username.size
is equal to "my_user_name".size
too.
This is an encoding issue. In this block username
and password
are encoded as "ASCII-8BIT".
use Rack::Auth::Basic, "my authentication" do |username, password|
p username
p db.execute("select * from user where name = ?", [username])
end
To resolve this you can change the encoding using String#force_encoding
like so:
use Rack::Auth::Basic, "my authentication" do |username, password|
p username
p db.execute("select * from user where name = ?", [username.force_encoding('UTF-8')])
end