├── .checkbuild
├── .editorconfig
├── .gitignore
├── .jshintrc
├── .nvmrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── index.js
├── package.json
├── scripts
├── changelog
└── ci
│ └── start
└── test
└── main.js
/.checkbuild:
--------------------------------------------------------------------------------
1 | {
2 | "checkbuild": {
3 | // "buddyjs"
4 | "enable": ["david", "jshint", "jsinspect", "nsp"],
5 | // don't exit immediately if one of the tools reports an error (default true)
6 | "continueOnError": true,
7 | // don't exit(1) even if we had some failures (default false)
8 | "allowFailures": false
9 | },
10 | "jshint": {
11 | "args": ["*.js"]
12 | },
13 | "jsinspect": {
14 | "args": ["*.js"]
15 | },
16 | "jscs": {
17 | "args": ["lib/**.js"],
18 | "url":"https://raw.githubusercontent.com/FGRibreau/javascript/master/.jscsrc"
19 | },
20 | "david": {
21 | "error": {
22 | "ESCM": false
23 | }
24 | },
25 | "nsp": {}
26 | }
27 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
11 | # 4 space indentation
12 | [*.js]
13 | indent_style = space
14 | indent_size = 2
15 |
16 |
17 | # Indentation override for all JS under lib directory
18 | #[lib/**.js]
19 | #indent_style = space
20 | #indent_size = 2
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # Compiled binary addons (http://nodejs.org/api/addons.html)
20 | build/Release
21 |
22 | # Dependency directory
23 | # Deployed apps should consider commenting this line out:
24 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
25 | node_modules
26 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "maxerr" : 50, // {int} Maximum error before stopping
3 |
4 | // Enforcing
5 | "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
6 | "camelcase" : false, // true: Identifiers must be in camelCase
7 | "curly" : true, // true: Require {} for every new block or scope
8 | "eqeqeq" : true, // true: Require triple equals (===) for comparison
9 | "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
10 | "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
11 | "indent" : 2, // {int} Number of spaces to use for indentation
12 | "latedef" : false, // true: Require variables/functions to be defined before being used
13 | "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()`
14 | "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
15 | "noempty" : true, // true: Prohibit use of empty blocks
16 | "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
17 | "plusplus" : false, // true: Prohibit use of `++` & `--`
18 | "quotmark" : false, // Quotation mark consistency:
19 | // false : do nothing (default)
20 | // true : ensure whatever is used is consistent
21 | // "single" : require single quotes
22 | // "double" : require double quotes
23 | "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
24 | "unused" : true, // true: Require all defined variables be used
25 | "strict" : true, // true: Requires all functions run in ES5 Strict Mode
26 | "trailing" : false, // true: Prohibit trailing whitespaces
27 | "maxparams" : 5, // {int} Max number of formal params allowed per function
28 | "maxdepth" : 4, // {int} Max depth of nested blocks (within functions)
29 | "maxstatements" : 25, // {int} Max number statements per function
30 | "maxcomplexity" : 6, // {int} Max cyclomatic complexity per function
31 | "maxlen" : false, // {int} Max number of characters per line
32 |
33 | // Relaxing
34 | "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
35 | "boss" : false, // true: Tolerate assignments where comparisons would be expected
36 | "debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
37 | "eqnull" : false, // true: Tolerate use of `== null`
38 | "es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
39 | "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
40 | "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
41 | // (ex: `for each`, multiple try/catch, function expression…)
42 | "evil" : false, // true: Tolerate use of `eval` and `new Function()`
43 | "expr" : false, // true: Tolerate `ExpressionStatement` as Programs
44 | "funcscope" : false, // true: Tolerate defining variables inside control statements"
45 | "globalstrict" : true, // true: Allow global "use strict" (also enables 'strict')
46 | "iterator" : false, // true: Tolerate using the `__iterator__` property
47 | "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
48 | "laxbreak" : false, // true: Tolerate possibly unsafe line breakings
49 | "laxcomma" : true, // true: Tolerate comma-first style coding
50 | "loopfunc" : false, // true: Tolerate functions being defined in loops
51 | "multistr" : true, // true: Tolerate multi-line strings
52 | "proto" : false, // true: Tolerate using the `__proto__` property
53 | "scripturl" : false, // true: Tolerate script-targeted URLs
54 | "smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
55 | "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
56 | "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
57 | "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
58 | "validthis" : false, // true: Tolerate using this in a non-constructor function
59 |
60 | // Environments
61 | "browser" : true, // Web Browser (window, document, etc)
62 | "couch" : false, // CouchDB
63 | "devel" : true, // Development/debugging (alert, confirm, etc)
64 | "dojo" : false, // Dojo Toolkit
65 | "jquery" : false, // jQuery
66 | "mootools" : false, // MooTools
67 | "node" : true, // Node.js
68 | "nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
69 | "prototypejs" : false, // Prototype and Scriptaculous
70 | "rhino" : false, // Rhino
71 | "worker" : false, // Web Workers
72 | "wsh" : false, // Windows Scripting Host
73 | "yui" : false, // Yahoo User Interface
74 |
75 | // Legacy
76 | "nomen" : false, // true: Prohibit dangling `_` in variables
77 | "onevar" : false, // true: Allow only one `var` statement per function
78 | "passfail" : false, // true: Stop on first error
79 | "white" : false, // true: Check against strict whitespace and indentation rules
80 |
81 | // Custom Globals
82 | "predef" : [
83 | "Buffer",
84 | "view",
85 | "test",
86 | "factoryKey",
87 | "RedisStub",
88 | "equal",
89 | "strictEqual",
90 | "ok",
91 | "deepEqual",
92 | "expect",
93 | "checkGrid",
94 |
95 | "describe",
96 | "beforeEach",
97 | "afterEach",
98 | "it",
99 |
100 | "module",
101 | "prompt",
102 | "require",
103 | "exports",
104 | "console",
105 | "__dirname",
106 | "process",
107 | "setInterval",
108 | "setTimeout",
109 | "clearTimeout",
110 | "Redsmin",
111 | "window",
112 | "Backbone",
113 | "bootbox",
114 | "Highcharts",
115 | "ReadLine",
116 | "CodeMirror",
117 | "$",
118 | "jQuery",
119 | "document",
120 | "angular",
121 | "alert",
122 | "grunt",
123 | "escape",
124 | "walk",
125 | "deepStrictEqual",
126 | "returnfalse",
127 | "forEachAsync",
128 | "humanize",
129 | "Mousetrap",
130 | "store",
131 | "Slick",
132 | "Slickback"] // additional predefined global variables
133 | }
134 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v0.10
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | ## [v1.2.0](https://github.com/fgribreau/node-tolerant-url-parser/tree/v1.2.0) (2015-04-05)
4 |
5 | [Full Changelog](https://github.com/fgribreau/node-tolerant-url-parser/compare/v1.1.0...v1.2.0)
6 |
7 | ## [v1.1.0](https://github.com/fgribreau/node-tolerant-url-parser/tree/v1.1.0) (2015-04-05)
8 |
9 |
10 |
11 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Francois-Guillaume Ribreau
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | tolerant url-parser [](https://drone.io/github.com/FGRibreau/node-tolerant-url-parser/latest) [](https://david-dm.org/FGRibreau/node-tolerant-url-parser)
2 | ========================
3 |
4 | Overly tolerant url parser specialized in parsing protocol, auth (even invalid ones), host and port url parts.
5 |
6 | [](https://npmjs.org/package/tolerant)
7 |
8 | ### Sponsored by
9 |
10 |
11 | tolerant-url-parser development was sponsored by Redsmin, a fully loaded administration service for Redis.
12 |
13 |
14 |
15 | ### Usage
16 |
17 | ```javascript
18 | var TolerantUrl = require('tolerant');
19 |
20 | console.log(TolerantUrl.parse('protocol://user:auth@domain.com:port/path/a'));
21 |
22 | // should print
23 | {
24 | 'protocol': 'protocol:',
25 | 'auth': 'user:auth',
26 | 'hostname': 'domain.com',
27 | 'host': 'domain.com:port',
28 | 'port': 'port',
29 | 'href': 'protocol://user:auth@domain.com:port/path/a',
30 | 'path': '/path/a'
31 | }
32 |
33 | // and that's all.
34 | ```
35 |
36 | ### How `tolerant` differs from nodejs url.parse
37 |
38 | NodeJS [url standard library](nodejs.org/docs/latest/api/url.html):
39 |
40 | ```javascript
41 | require('url')
42 | .parse('redis://plop:z4fsoV:_git://53c2nd@koo3@1hFldzFG/2ojyPwcTCPZgRo=@redsmin.com:6379')
43 | {
44 | protocol: 'redis:',
45 | slashes: true,
46 | auth: null,
47 | host: 'plop',
48 | port: null,
49 | hostname: 'plop',
50 | hash: null,
51 | search: null,
52 | query: null,
53 | pathname: '/:z4fsoV:_git//53c2nd@koo3@1hFldzFG/2ojyPwcTCPZgRo=@redsmin.com:6379',
54 | path: '/:z4fsoV:_git//53c2nd@koo3@1hFldzFG/2ojyPwcTCPZgRo=@redsmin.com:6379',
55 | href: 'redis://plop/:z4fsoV:_git//53c2nd@koo3@1hFldzFG/2ojyPwcTCPZgRo=@redsmin.com:6379'
56 | }
57 | ```
58 |
59 | `url.parse` was not able to extract the auth while the tolerant url-parser can:
60 |
61 | ```javascript
62 | require('tolerant')
63 | .parse('redis://plop:z4fsoV:_git://53c2nd@koo3@1hFldzFG/2ojyPwcTCPZgRo=@redsmin.com:6379')
64 | {
65 | protocol: 'redis:',
66 | auth: 'plop:z4fsoV:_git://53c2nd@koo3@1hFldzFG/2ojyPwcTCPZgRo=',
67 | hostname: 'redsmin.com',
68 | host: 'redsmin.com:6379',
69 | port: '6379',
70 | href: 'redis://plop:z4fsoV:_git://53c2nd@koo3@1hFldzFG/2ojyPwcTCPZgRo=@redsmin.com:6379',
71 | path: null
72 | }
73 | ```
74 |
75 | Check `test/main.js` for examples of weird urls parsed by `tolerant`.
76 |
77 | ### [Changelog](/CHANGELOG.md)
78 |
79 | ### License
80 |
81 | Copyright (c) 2014, Francois-Guillaume Ribreau node@fgribreau.com.
82 |
83 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
84 |
85 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
86 |
87 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
88 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | Overly tolerant url parser
4 | */
5 |
6 | var Url = module.exports = {
7 | PROTOCOL: '://',
8 | COLON: ':',
9 | AT: '@',
10 | SLASH: '/',
11 | parse: function (url) {
12 | // first parse auth/host/port
13 | var parsed = this._parse(url);
14 |
15 | // then handle path (quick & dirty way)
16 | ['host', 'hostname', 'port'].forEach(function (part) {
17 | if (strCount(parsed[part], this.SLASH) > 0) {
18 | var pair = parsed[part].split(this.SLASH);
19 | parsed[part] = pair.shift();
20 | parsed.path = this.SLASH + pair.join(this.SLASH);
21 | }
22 | }, this);
23 |
24 | return parsed;
25 | },
26 | _parse: function (url) {
27 | var parsed = {
28 | protocol: null, // string
29 | auth: null, // string
30 | hostname: null, // string
31 | host: null, // string
32 | port: null, // string
33 | href: url, // string
34 | path: null
35 | };
36 |
37 | // check protocol
38 | var protocolIdx = url.indexOf(this.PROTOCOL);
39 | if (protocolIdx !== -1) {
40 | parsed.protocol = url.substring(0, protocolIdx + 1);
41 | protocolIdx += this.PROTOCOL.length;
42 | // remove the protocol part from the url
43 | url = url.substring(protocolIdx);
44 | }
45 |
46 | var atCount = strCount(url, this.AT);
47 | var colonCount = strCount(url, this.COLON);
48 | var atIsPresent = atCount > 0;
49 | var colonIsPresent = colonCount > 0;
50 |
51 | if (!atIsPresent && !colonIsPresent) {
52 | parsed.host = url;
53 | parsed.hostname = url;
54 | // parse is done, there are no port and auth
55 | return parsed;
56 | }
57 |
58 | if (colonCount === 1 && !atIsPresent) { // it can only be the port number
59 | extractPortAndHostnameFromHost(parsed, url);
60 | return parsed;
61 | }
62 |
63 | var parts = url.split(this.AT);
64 | var host = parts.pop();
65 | extractPortAndHostnameFromHost(parsed, host);
66 | parsed.auth = parts.join(this.AT);
67 | return parsed;
68 | }
69 | };
70 |
71 |
72 | function strCount(str, substr) {
73 | if (str === null || substr === null) {
74 | return 0;
75 | }
76 | str = String(str);
77 | substr = String(substr);
78 |
79 | var count = 0,
80 | pos = 0,
81 | length = substr.length;
82 |
83 | while (true) {
84 | pos = str.indexOf(substr, pos);
85 | if (pos === -1) {
86 | break;
87 | }
88 | count++;
89 | pos += length;
90 | }
91 |
92 | return count;
93 | }
94 |
95 | function extractPortAndHostnameFromHost(parsed, host) {
96 | var portIdx = host.indexOf(Url.COLON);
97 | parsed.host = host;
98 |
99 | if (portIdx === -1) {
100 | parsed.hostname = host;
101 | // no colon is present inside host
102 | return;
103 | }
104 | parsed.port = host.substring(portIdx + Url.COLON.length);
105 | parsed.hostname = host.substring(0, portIdx);
106 | }
107 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tolerant",
3 | "version": "1.2.0",
4 | "description": "Overly tolerant url parser specialized in parsing protocol, auth (even invalid ones), host and port url parts.",
5 | "main": "index.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "scripts": {
10 | "test": "mocha"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git@github.com:FGRibreau/node-tolerant-url-parser.git"
15 | },
16 | "keywords": [
17 | "url",
18 | "parsing"
19 | ],
20 | "author": "Francois-Guillaume Ribreau (http://fgribreau.com/)",
21 | "license": "MIT",
22 | "bugs": {
23 | "url": "https://github.com/FGRibreau/node-tolerant-url-parser/issues"
24 | },
25 | "devDependencies": {
26 | "chai": "^2.2.0",
27 | "mocha": "~1.20.1"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/scripts/changelog:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # gem install github_changelog_generator
3 | github_changelog_generator -u fgribreau -p node-tolerant-url-parser
4 |
--------------------------------------------------------------------------------
/scripts/ci/start:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env zsh
2 |
3 | wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.21.0/install.sh | bash
4 | source ~/.nvm/nvm.sh
5 |
6 | nvm install
7 | nvm use
8 |
9 | npm install
10 |
11 | node -v
12 | npm -v
13 |
14 | npm install
15 |
16 | set -e
17 |
18 | # Any subsequent commands which fail will cause the shell script to exit immediately
19 | setopt extended_glob;
20 |
21 | npm test
22 |
23 | npm install check-build -g
24 | check-build
25 |
--------------------------------------------------------------------------------
/test/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var tolerantUrl = require('../');
3 | var t = require('chai').assert;
4 |
5 | describe('.parse', function () {
6 |
7 | it('should produce documentation #lazy', function () {
8 | var parsed = tolerantUrl.parse('protocol://user:auth@domain.com:port/path');
9 | // JSON.stringify(parsed, null, 2);
10 | t.deepEqual(parsed, {
11 | 'protocol': 'protocol:',
12 | 'auth': 'user:auth',
13 | 'hostname': 'domain.com',
14 | 'host': 'domain.com:port',
15 | 'port': 'port',
16 | 'href': 'protocol://user:auth@domain.com:port/path',
17 | 'path': '/path'
18 | });
19 | });
20 |
21 | it('should be able to parse sometime weird urls', function (f) {
22 | [{ // just domain without protocol
23 | input: 'my.own.domain.name.com',
24 | output: {
25 | protocol: null,
26 | auth: null,
27 | hostname: 'my.own.domain.name.com',
28 | port: null,
29 | host: 'my.own.domain.name.com',
30 | path: null
31 | }
32 | },
33 |
34 | { // just domain
35 | input: 'redis://pub-redis-12000.us-east-0-0.0.ec1.garantiadata.com',
36 | output: {
37 | protocol: 'redis:',
38 | auth: null,
39 | hostname: 'pub-redis-12000.us-east-0-0.0.ec1.garantiadata.com',
40 | port: null,
41 | host: 'pub-redis-12000.us-east-0-0.0.ec1.garantiadata.com',
42 | path: null
43 | }
44 | }, { // just domain with port
45 | input: 'redis://redsmin.ok.com:12000/aa/aaa',
46 | output: {
47 | protocol: 'redis:',
48 | auth: null,
49 | hostname: 'redsmin.ok.com',
50 | port: '12000',
51 | host: 'redsmin.ok.com:12000',
52 | path: '/aa/aaa'
53 | }
54 | }, { // full (easy)
55 | input: 'redis://user:password@plop.redsmin.com:12000',
56 | output: {
57 | protocol: 'redis:',
58 | auth: 'user:password',
59 | hostname: 'plop.redsmin.com',
60 | port: '12000',
61 | host: 'plop.redsmin.com:12000',
62 | path: null
63 | }
64 | }, { // weird auth + domain
65 | input: 'redis://z4fsoVXGIt:53c1NDkoi41fFmzdHJ/2ojyZtcTCPZgRo=@redsmin.com/aaa',
66 | output: {
67 | protocol: 'redis:',
68 | auth: 'z4fsoVXGIt:53c1NDkoi41fFmzdHJ/2ojyZtcTCPZgRo=',
69 | hostname: 'redsmin.com',
70 | port: null,
71 | host: 'redsmin.com',
72 | path: '/aaa'
73 | }
74 | }, { // weird auth + domain + port
75 | input: 'redis://z4fsoVXGIt53c1NDkoi41fFmzdHJ/2ojyZtcTCPZgRo=@redsmin.com:6379',
76 | output: {
77 | protocol: 'redis:',
78 | auth: 'z4fsoVXGIt53c1NDkoi41fFmzdHJ/2ojyZtcTCPZgRo=',
79 | hostname: 'redsmin.com',
80 | port: '6379',
81 | host: 'redsmin.com:6379',
82 | path: null
83 | }
84 | }, { // weird auth (multi @) + domain + port
85 | input: 'redis://user:z4fsoVXGIt5@3c1NDkoi41fFmzdHJ/2ojyZtcTCPZgRo=@redsmin.com:6379',
86 | output: {
87 | protocol: 'redis:',
88 | auth: 'user:z4fsoVXGIt5@3c1NDkoi41fFmzdHJ/2ojyZtcTCPZgRo=',
89 | hostname: 'redsmin.com',
90 | port: '6379',
91 | host: 'redsmin.com:6379',
92 | path: null
93 | }
94 | }, { // weird auth (multi ://) + domain + port
95 | input: 'redis://user:z4fsoVXGI://t5@3c1NDkoi41fFmzdHJ/2ojyZtcTCPZgRo=@redsmin.com:6379',
96 | output: {
97 | protocol: 'redis:',
98 | auth: 'user:z4fsoVXGI://t5@3c1NDkoi41fFmzdHJ/2ojyZtcTCPZgRo=',
99 | hostname: 'redsmin.com',
100 | port: '6379',
101 | host: 'redsmin.com:6379',
102 | path: null
103 | }
104 | }, { // really really weird auth + domain + port
105 | input: 'redis://user:F,-9fsR;K{E4cM{o-&xS%ma6NbPoPTT*M_YJ.Kdp,p8qT,NDg*Q9%wy6h-OGgEU]?sYg?Ef,|2shOkwgYkz.NPNDu]T4%:,>_76U}7U;\'TSv7K*+k!HZR?0TQ2+]X.9DMs,s[rSZi?c.\'&>M7h89SpElr[vtL.Gdfe;!L|>&!wZ\'CuPT\'6,F62_ox,?L+gae5aUO<<%A\'28\'4hS77TrGDPK#1lrBo}*F:*pcd0w_NY##>0K:2#soE[,nJn,9\'&>-({84AHRvApS49iWTDmCJ?h(+-B6VYrZz:Ij\'9J_}w9uP:24YHV@QgKKt/7vm](3t#5:v:7dP]6MQrC@SHw|@r{{7(!*Y_YJ.Kdp,p8qT,NDg*Q9%wy6h-OGgEU]?sYg?Ef,|2shOkwgYkz.NPNDu]T4%:,>_76U}7U;\'TSv7K*+k!HZR?0TQ2+]X.9DMs,s[rSZi?c.\'&>M7h89SpElr[vtL.Gdfe;!L|>&!wZ\'CuPT\'6,F62_ox,?L+gae5aUO<<%A\'28\'4hS77TrGDPK#1lrBo}*F:*pcd0w_NY##>0K:2#soE[,nJn,9\'&>-({84AHRvApS49iWTDmCJ?h(+-B6VYrZz:Ij\'9J_}w9uP:24YHV@QgKKt/7vm](3t#5:v:7dP]6MQrC@SHw|@r{{7(!*Y