question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Google API clients are improperly escaping URLs

See original GitHub issue

Google API clients are improperly escaping URLs

This issue has been causing problems for users of Google APIs for years. For example, Issue #454 , Issue #534, Issue #636, and I’ll bet there are others. This is the issue to track work for making this just work for API clients, regardless of .NET framework target and without needing to modify code or config.

Problem

There are two different behaviors of System.Uri depending on the version of the .NET Framework you are using. @mmdriley put together a great repro in Issue #636. See [Microsoft Connect 511010](https://connect.microsoft.com/VisualStudio/feedback/details/511010/erroneous-uri-parsing-for-encoded-reserved-characters-according-to-rfc-3986 Known deviation from the URI spec), Microsoft Connect 94109.

Whereas System.Uri in .NET 4.0 will convert “%2F” into “/” when encoded into a URL. .NET 4.5 will leave the “%2F” as-is. The problem is that certain APIs require a “%2F” and will fail if there is a “/” instead.

This behavior is especially problematic when using the Google Cloud Storage API. Storage objects usually have slashes in their name, so when URLs get generated for API calls the URL is invalid. For example, to get the GCS object with name “test/file1.txt” you need to generate a URL such as:

GET https://www.googleapis.com/storage/v1/b/gcs-bucket-name/o/test%2Ffile1.tmp?key={API_KEY}

So with the .NET 4.0 behavior, the request will be invalid:

GET https://www.googleapis.com/storage/v1/b/gcs-bucket-name/o/test/file1.tmp?key={API_KEY}

Note that while .NET 4.0 is nearly out of its lifespan, .NET 4.5 will emulate the 4.0 behaviour for assemblies that are targeting .NET 4.0. (e.g. from an assembly-level attribute.)

Work Around

There are a couple of easy work-arounds for this issue.

First, the easiest thing to do is to have your assembly explicitly target the .NET Framework version 4.5. This can be done within Visual Studio and/or by specifying an assembly-level attribute.

This option isn’t ideal because using a Google API shouldn’t force you to target a specific version of the framework.

Second, you can modify your app.config or web.config file to modify the behavior. Just add this stanza to the file:

<uri>
  <schemeSettings>
    <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
  </schemeSettings>
</uri>

This option isn’t ideal because some scenarios don’t have an appropriate config file. For example, when the assembly is hosted such as in PowerShell modules. Also, again, using a Google API shouldn’t force you to set application-wide level policy.

Possible Solutions

This SO post has a hack that used reflection to poke at the private fields in System.Uri to get consistent behavior.

In fact, this project used to use the reflection hack but it was removed later.

Alternatively, we can be hoist the Uri generation into a separate AppDomain, which is forced to run with the 4.5 behavior.

Alternatively, we can be use some heuristics and double-encode the data as needed and trick the 4.0 System.Uri.

There might even be a better solution.

I’d like to welcome suggestions for how to proceed.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
mmdrileycommented, Mar 19, 2016

Fixed by #698 and released in v1.11.

0reactions
jtattermuschcommented, Dec 17, 2015

Possibly related: I also spotted this problem when I was trying to make unit tests pass on mono (at that time I thought this is mono vs .NET incompatibility issue): https://github.com/google/google-api-dotnet-client/pull/616/files#diff-58a277240f102603523e70fe06e2a816R958

Read more comments on GitHub >

github_iconTop Results From Across the Web

Best Practices Using Places API Web Services
However, note that certain services have several parameters that may result in long URLs. Polite Use of Google APIs. Poorly designed API clients...
Read more >
How to prevent python requests from percent encoding my ...
A json api I am "forced" to use doesn't like the url passed to it to be encoded. Had to build a string....
Read more >
Package com.google.api.client.util.escape (1.43.2)
A UnicodeEscaper that escapes some set of Java characters using the URI percent encoding scheme. The set of safe characters (those which ...
Read more >
Apigee URL encoding issue
I've got an issue with encoding. The issue is that when an email with + is added as queryparam in AssignMessage, Apigee encodes...
Read more >
Escape hash in url python. Value. ...
Escape hash in url python. Value. This was a particular problem for me when trying to open local files with a "#" in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found