diff --git a/src/handler.ts b/src/handler.ts index c24d8c4..cb29282 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -75,7 +75,8 @@ export async function handleProxyToGoogleTakeoutRequest( ) } - const originalResponse = await fetch(extracted_url.toString(), { + // Don't pass the original URL. The URL object will malform the `%2B` to `+`. + const originalResponse = await fetch(original_url_segment_stripped_processed, { method: request.method, headers: request.headers, }) diff --git a/test/handler.test.ts b/test/handler.test.ts index 0e5e26a..a386d6c 100644 --- a/test/handler.test.ts +++ b/test/handler.test.ts @@ -14,7 +14,7 @@ import { real_azb_url, file_test_small_url, file_test_large_url, - small_test_string_encoded_url + small_test_string_encoded_url, small_test_string_plus_encoded_url } from './real_url' describe('handler utilities', () => { @@ -168,6 +168,48 @@ describe('azure proxy handler', () => { expect(single_block_ok).toEqual('') }) + test('handles proxying a transload request with plus in the encoded URL to azure with azure transloading from cloudflare via the proxy', async () => { + // Not exactly a clean unit test since it depends on a properly deployed proxy already, but it'll do. + const AZ_STORAGE_TEST_URL_SEGMENT = process.env.AZ_STORAGE_TEST_URL_SEGMENT + if (!AZ_STORAGE_TEST_URL_SEGMENT) { + throw new Error( + 'AZ_STORAGE_TEST_URL_SEGMENT environment variable is not set', + ) + } + + // Construct the file_source_url that is proxied to the proxy + // "https://gtr-proxy.677472.xyz/p/" is prepended to the file_test_small_url with file_test_small_url's scheme removed. + const file_source_url = new URL( + `https://gtr-proxy.677472.xyz/p/${small_test_string_plus_encoded_url.toString().replace( + 'https://', + '' + )}`, + ) + + + const base_request_url = new URL( + `https://example.com/p-azb/${AZ_STORAGE_TEST_URL_SEGMENT}`, + ) + // Change filename of request URL + base_request_url.pathname = base_request_url.pathname.replace( + 'test.dat', + 'p-azb-transload-plus-encoded-url-via-proxy.dat', + ) + + // Do a single block upload + const single_block_request = new Request(base_request_url, { + method: 'PUT', + headers: { + 'x-ms-blob-type': 'BlockBlob', + 'x-ms-copy-source': file_source_url.toString(), + } + }) + + const single_block_result = await handleRequest(single_block_request) + const single_block_ok = await single_block_result.text() + expect(single_block_ok).toEqual('') + }) + }) describe('takeout proxy handler', () => { diff --git a/test/real_url.ts b/test/real_url.ts index 9ca924a..02d9b54 100644 --- a/test/real_url.ts +++ b/test/real_url.ts @@ -7,3 +7,6 @@ export const file_test_small_url = new URL("https://gtr-test.677472.xyz/10MB.bin export const file_test_large_url = new URL("https://gtr-test.677472.xyz/200MB.zip") export const small_test_string_encoded_url = new URL("https://put-block-from-url-esc-issue-demo-server-3vngqvvpoq-uc.a.run.app/red%252Fblue.txt/dummy.bin") + +export const small_test_string_plus_encoded_url = new URL("https://put-block-from-url-esc-issue-demo-server-3vngqvvpoq-uc.a.run.app/me%2Byou.txt/dummy.bin") +