Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encoding error in DB connection string #77

Closed
greensombrero opened this issue Jul 23, 2018 · 4 comments
Closed

Encoding error in DB connection string #77

greensombrero opened this issue Jul 23, 2018 · 4 comments
Labels
bug Something isn't working

Comments

@greensombrero
Copy link

We are trying to use migrate with a MySQL database hosted in Azure with Azure Database for MySQL and have hit an issue. Azure MySQL usernames contain an @ sign. Unfortunately this messes up migrate because the database connection is being parsed as a URL. I was on an older version and the @ sign was being escaped. I just pulled the latest version and see that this commit changed the order of when the mysql:// is removed so passwords aren't escaped. Unfortunately now I get an error parsing the url "first path segment in URL cannot contain colon". A sample connection string looks like mysql://someuser@samplehost:password@tcp(samplehost.mysql.database.azure.com:3306)/SampleDB?tls=skip-verify&allowNativePasswords=true

Any ideas how to work around this?

@dhui
Copy link
Member

dhui commented Jul 24, 2018

Looks like there's an issue w/ our usage of url.Parse() e.g. we're relying on undefined behaviors to get net/url to not escape/encode users/passwords.

According to the docs, we shouldn't be trimming the scheme since the hostname and path (e.g. db) are usually specified:

Trying to parse a hostname and path without a scheme is invalid but may not necessarily return an error, due to parsing ambiguities.

Was Azure honoring the url-encoded @ character in the username?
If so, for now, try manually url-encoding the @ character. e.g. use %40

Longterm, we'll need to figure out our approach/stance regarding connection string formats and escaping/encoding. Both go-sql-driver/mysql and lib/pq parse the connection string themselves instead of relying on net/url which escapes reserved URL characters

@greensombrero
Copy link
Author

Unfortunately escaping the @ sign doesn't seem to help the error I'm getting.

Prior to the code change that trims the schema I had a potential fix. The url.Parse was escaping the @ sign and I could just unescape it in a line of code right before passing the connection string to the underlying go database layer. It did have to be unescaped to work but that was an option. However now with the error coming at the url.Parse point in the code that isn't an option.

I think the core issue as you point out is that url.Parse tends to encode special characters. It seems the main reason net/url is being used is so the query string parameters can easily be manipulated. I wonder if there is a better way to do that and avoid the url.Parse call entirely?

Another option I thought of is that I could create a custom Azure MySQL driver and give it different behavior than the normal MySQL driver. That doesn't seem like the most elegant approach but would unblock my use case.

My strong preference is not to end up using a custom fork of the project if at all possible. I'm open to any ideas on how to solve this in a way that could be incorporated back into the project.

@dhui dhui added the bug Something isn't working label Jul 24, 2018
@dhui
Copy link
Member

dhui commented Jul 24, 2018

For now, I'd suggest downgrading to v3.3.0 while I figure out what the best "fix" is.
Any future fix will allow all characters to be used as a username and password, so a fork or Azure specific MySQL driver shouldn't be necessary.

I'd like to avoid writing our own connection string parser (like the underlying DB drivers seem to do) to avoid addition encoding/escaping bugs.

For the fix, I'm inclined to revert #69, continue using url.Parse(), add tests for connection strings, and improve the connection string documentation by explicitly listing the reserved URL characters.

@dhui dhui changed the title Support for Azure MySQL Encoding error in DB connection string Jul 24, 2018
@dhui
Copy link
Member

dhui commented Jul 25, 2018

This has been fixed in v3.4.0

@dhui dhui closed this as completed Aug 7, 2018
FPiety0521 pushed a commit to FPiety0521/Golang-SQL that referenced this issue May 24, 2023
    - Improve docs around escaping/encoding reserved URL characters
    - Add tests for net/url Parse() and reserved characters to document understanding
    - Addresses: golang-migrate/migrate#77
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants