Skip to content

Commit

Permalink
fix: properly encode url with unicode characters (#1291)
Browse files Browse the repository at this point in the history
* fix: properly encode url with unicode characters
* release: 2.6.3
  • Loading branch information
LinusU committed Sep 20, 2021
1 parent 152214c commit ace7536
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,10 @@ Changelog

# 2.x release

## v2.6.3

- Fix: properly encode url with unicode characters

## v2.6.2

- Fix: used full filename for main in package.json
Expand Down
8 changes: 5 additions & 3 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "node-fetch",
"version": "2.6.2",
"version": "2.6.3",
"description": "A light-weight module that brings window.fetch to node.js",
"main": "lib/index.js",
"browser": "./browser.js",
Expand Down Expand Up @@ -36,6 +36,9 @@
"url": "https://github.com/bitinn/node-fetch/issues"
},
"homepage": "https://github.com/bitinn/node-fetch",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"devDependencies": {
"@ungap/url-search-params": "^0.1.2",
"abort-controller": "^1.1.0",
Expand All @@ -60,7 +63,6 @@
"rollup": "^0.63.4",
"rollup-plugin-babel": "^3.0.7",
"string-to-arraybuffer": "^1.0.2",
"teeny-request": "3.7.0",
"whatwg-url": "^5.0.0"
"teeny-request": "3.7.0"
}
}
5 changes: 4 additions & 1 deletion rollup.config.js
@@ -1,9 +1,12 @@
import isBuiltin from 'is-builtin-module';
import babel from 'rollup-plugin-babel';
import packageJson from './package.json';
import tweakDefault from './build/rollup-plugin';

process.env.BABEL_ENV = 'rollup';

const dependencies = Object.keys(packageJson.dependencies);

export default {
input: 'src/index.js',
output: [
Expand All @@ -18,6 +21,6 @@ export default {
tweakDefault()
],
external: function (id) {
return isBuiltin(id);
return dependencies.includes(id) || isBuiltin(id);
}
};
40 changes: 37 additions & 3 deletions src/request.js
Expand Up @@ -9,6 +9,7 @@

import Url from 'url';
import Stream from 'stream';
import {URL} from 'whatwg-url';

This comment has been minimized.

Copy link
@robrecord

robrecord Sep 21, 2021

This import on line 12 is causing errors in other projects.

    ERROR in ./node_modules/node-fetch/lib/index.mjs 1157:15-18
    Can't import the named export 'URL' from non EcmaScript module (only default export is available)

This comment has been minimized.

Copy link
@LinusU

LinusU Sep 21, 2021

Author Member

@robrecord which version of Node.js are you using? Strangely enough I cannot reproduce this, but I think that the error is correct in that you cannot use the import syntax in that way with non-ESM libraries...

For the record, this is what works for me with Node.js 16.8.0:

$ node -e 'import("./lib/index.mjs").then(console.log)'
[Module: null prototype] {
  FetchError: [Function: FetchError],
  Headers: [class Headers],
  Request: [class Request],
  Response: [class Response],
  default: [Function: fetch] {
    isRedirect: [Function (anonymous)],
    Promise: [Function: Promise]
  }
}
import Headers, { exportNodeCompatibleHeaders } from './headers.js';
import Body, { clone, extractContentType, getTotalBytes } from './body';

Expand All @@ -18,6 +19,39 @@ const INTERNALS = Symbol('Request internals');
const parse_url = Url.parse;
const format_url = Url.format;

/**
* Wrapper around `new URL` to handle arbitrary URLs
*
* @param {string} urlStr
* @return {void}
*/
function parseURL(urlStr) {
/*
Check whether the URL is absolute or not
Scheme: https://tools.ietf.org/html/rfc3986#section-3.1
Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3
*/
if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) {
const url = new URL(urlStr);

return {
path: url.pathname,
pathname: url.pathname,
hostname: url.hostname,
protocol: url.protocol,
port: url.port,
hash: url.hash,
search: url.search,
query: url.query,

This comment has been minimized.

Copy link
@jimmywarting

jimmywarting Sep 21, 2021

Collaborator

url.query is undefined

it's not part of of URL spec.

new URL(...).query

href: url.href,
}
}

// Fallback to old implementation for arbitrary URLs
return parse_url(urlStr);
}

const streamDestructionSupported = 'destroy' in Stream.Readable.prototype;

/**
Expand Down Expand Up @@ -59,14 +93,14 @@ export default class Request {
// in order to support Node.js' Url objects; though WHATWG's URL objects
// will fall into this branch also (since their `toString()` will return
// `href` property anyway)
parsedURL = parse_url(input.href);
parsedURL = parseURL(input.href);
} else {
// coerce input to a string before attempting to parse
parsedURL = parse_url(`${input}`);
parsedURL = parseURL(`${input}`);
}
input = {};
} else {
parsedURL = parse_url(input.url);
parsedURL = parseURL(input.url);
}

let method = init.method || input.method || 'GET';
Expand Down
8 changes: 7 additions & 1 deletion test/server.js
Expand Up @@ -32,7 +32,7 @@ export default class TestServer {
}

router(req, res) {
let p = parse(req.url).pathname;
let p = decodeURIComponent(parse(req.url).pathname);

if (p === '/hello') {
res.statusCode = 200;
Expand Down Expand Up @@ -384,6 +384,12 @@ export default class TestServer {
});
req.pipe(parser);
}

if (p === '/issues/1290/ひらがな') {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Success');
}
}
}

Expand Down
22 changes: 22 additions & 0 deletions test/test.js
Expand Up @@ -2845,3 +2845,25 @@ describe('external encoding', () => {
});
});
});

describe('issue #1290', function() {
it('should handle escaped unicode in URLs', () => {
const url = `${base}issues/1290/%E3%81%B2%E3%82%89%E3%81%8C%E3%81%AA`;
return fetch(url).then((res) => {
expect(res.status).to.equal(200);
return res.text().then(result => {
expect(result).to.equal('Success');
});
});
});

it('should handle unicode in URLs', () => {
const url = `${base}issues/1290/ひらがな`;
return fetch(url).then((res) => {
expect(res.status).to.equal(200);
return res.text().then(result => {
expect(result).to.equal('Success');
});
});
});
});

0 comments on commit ace7536

Please sign in to comment.