# crates.io – Issue 4891
<https://github.com/rust-lang/crates.io/issues/4891>
## Issue
> Some clients, proxies, and/or repository managers may encode URLs to the upstream (for instance JFrog Artifactory). Due to blocks on crates.io some of these requests fail if there is a `+` sign in the URL
>
> e.g. If we go to this URL it works fine:
>
> <https://static.crates.io/crates/libgit2-sys/libgit2-sys-0.12.25+1.3.0.crate>
>
> But if we go to the encoded URL it gives us a 403 Access Denied
> <https://static.crates.io/crates/libgit2-sys/libgit2-sys-0.12.25%2B1.3.0.crate>
>
> This has also exposed some more strange behavior.
If we encode the + sign as a space (%20 instead of %2B), it works.
> <https://static.crates.io/crates/libgit2-sys/libgit2-sys-0.12.25%201.3.0.crate>
>
> Or even if I put a space instead in the URL (though that may be my browser encoding for me)
> "<https://static.crates.io/crates/libgit2-sys/libgit2-sys-0.12.25> 1.3.0.crate"
>
> Since URL encoding is fairly standard and other encoding works, I believe this is a bug
## Investigation
### Current State
The following tests were performed using `curl -I <url>` against the staging
environment, whose configuration is identical to the production environment.
| Target | Encoding | Result |
|------------|----------|------------|
| CloudFront | `+` | ✅ HTTP 200 |
| CloudFront | `%2B` | ❌ HTTP 403 |
| CloudFront | `%20` | ✅ HTTP 200 |
| Fastly | `+` | ✅ HTTP 200 |
| Fastly | `%2B` | ❌ HTTP 403 |
| Fastly | `%20` | ✅ HTTP 200 |
| S3 | `+` | ✅ HTTP 200 |
| S3 | `%B` | ❌ HTTP 403 |
| S3 | `%20` | ✅ HTTP 200 |
### After Renaming the File
The filename was manually changed to `rust-cratesio-4891-0.1.0+1.crate`, and the
same tests as above were performed.
| Target | Encoding | Result |
|------------|----------|------------|
| CloudFront | `+` | ❌ HTTP 403 |
| CloudFront | `%2B` | ✅ HTTP 200 |
| CloudFront | `%20` | ❌ HTTP 403 |
| Fastly | `+` | ❌ HTTP 403 |
| Fastly | `%2B` | ✅ HTTP 200 |
| Fastly | `%20` | ❌ HTTP 403 |
| S3 | `+` | ❌ HTTP 403 |
| S3 | `%2B` | ✅ HTTP 200 |
| S3 | `%20` | ❌ HTTP 403 |
## Cause
The issue seems to be that the `+` is a special character on S3. It is converted to a space when files are uploaded to S3, e.g. `libgit2-sys-0.12.25+1.3.0.crate` is saved on S3 as `libgit2-sys-0.12.25 1.3.0.crate`.
When accessing a file in S3, a `+` in the URL is encoded to a space in the file name. When encoding the `+` as `%2B` before sending the request, S3 decodes it to the character `+` and looks for the file `libgit2-sys-0.12.25+1.3.0.crate`. This file does not exist, though, since the `+` in the original file name got decoded to a space.
The issue arises when third-party clients try to download a crate and `urlencode()` the name before sending the request.
## Solution
Since filenames with spaces in them can cause all sorts of issues, we want to store the crates with a name like `libgit2-sys-0.12.25+1.3.0.crate` in S3. This requires that names are URL-encoded prior to uploading crates.