|
1 | 1 | import * as dns from 'dns';
|
2 | 2 | import * as fs from 'fs';
|
3 |
| -import { URL, URLSearchParams } from 'url'; |
| 3 | +import ConnectionString from 'mongodb-connection-string-url'; |
| 4 | +import { URLSearchParams } from 'url'; |
4 | 5 | import { AuthMechanism } from './cmap/auth/defaultAuthProviders';
|
5 | 6 | import { ReadPreference, ReadPreferenceMode } from './read_preference';
|
6 | 7 | import { ReadConcern, ReadConcernLevel } from './read_concern';
|
@@ -146,68 +147,6 @@ export function checkTLSOptions(options: AnyOptions): void {
|
146 | 147 | check('tlsDisableCertificateRevocationCheck', 'tlsDisableOCSPEndpointCheck');
|
147 | 148 | }
|
148 | 149 |
|
149 |
| -const HOSTS_REGEX = new RegExp( |
150 |
| - String.raw`(?<protocol>mongodb(?:\+srv|)):\/\/(?:(?<username>[^:]*)(?::(?<password>[^@]*))?@)?(?<hosts>(?!:)[^\/?@]+)(?<rest>.*)` |
151 |
| -); |
152 |
| - |
153 |
| -/** @internal */ |
154 |
| -export function parseURI(uri: string): { isSRV: boolean; url: URL; hosts: string[] } { |
155 |
| - const match = uri.match(HOSTS_REGEX); |
156 |
| - if (!match) { |
157 |
| - throw new MongoParseError(`Invalid connection string ${uri}`); |
158 |
| - } |
159 |
| - |
160 |
| - const protocol = match.groups?.protocol; |
161 |
| - const username = match.groups?.username; |
162 |
| - const password = match.groups?.password; |
163 |
| - const hosts = match.groups?.hosts; |
164 |
| - const rest = match.groups?.rest; |
165 |
| - |
166 |
| - if (!protocol || !hosts) { |
167 |
| - throw new MongoParseError('Invalid connection string, protocol and host(s) required'); |
168 |
| - } |
169 |
| - |
170 |
| - decodeURIComponent(username ?? ''); |
171 |
| - decodeURIComponent(password ?? ''); |
172 |
| - |
173 |
| - // characters not permitted in username nor password Set([':', '/', '?', '#', '[', ']', '@']) |
174 |
| - const illegalCharacters = new RegExp(String.raw`[:/?#\[\]@]`, 'gi'); |
175 |
| - if (username?.match(illegalCharacters)) { |
176 |
| - throw new MongoParseError(`Username contains unescaped characters ${username}`); |
177 |
| - } |
178 |
| - if (!username || !password) { |
179 |
| - const uriWithoutProtocol = uri.replace(`${protocol}://`, ''); |
180 |
| - if (uriWithoutProtocol.startsWith('@') || uriWithoutProtocol.startsWith(':')) { |
181 |
| - throw new MongoParseError('URI contained empty userinfo section'); |
182 |
| - } |
183 |
| - } |
184 |
| - |
185 |
| - if (password?.match(illegalCharacters)) { |
186 |
| - throw new MongoParseError('Password contains unescaped characters'); |
187 |
| - } |
188 |
| - |
189 |
| - let authString = ''; |
190 |
| - if (typeof username === 'string') authString += username; |
191 |
| - if (typeof password === 'string') authString += `:${password}`; |
192 |
| - |
193 |
| - const isSRV = protocol.includes('srv'); |
194 |
| - const hostList = hosts.split(','); |
195 |
| - const url = new URL(`${protocol.toLowerCase()}://${authString}@dummyHostname${rest}`); |
196 |
| - |
197 |
| - if (isSRV && hostList.length !== 1) { |
198 |
| - throw new MongoParseError('mongodb+srv URI cannot have multiple service names'); |
199 |
| - } |
200 |
| - if (isSRV && hostList[0].includes(':')) { |
201 |
| - throw new MongoParseError('mongodb+srv URI cannot have port number'); |
202 |
| - } |
203 |
| - |
204 |
| - return { |
205 |
| - isSRV, |
206 |
| - url, |
207 |
| - hosts: hosts.split(',') |
208 |
| - }; |
209 |
| -} |
210 |
| - |
211 | 150 | const TRUTHS = new Set(['true', 't', '1', 'y', 'yes']);
|
212 | 151 | const FALSEHOODS = new Set(['false', 'f', '0', 'n', 'no', '-1']);
|
213 | 152 | function getBoolean(name: string, value: unknown): boolean {
|
@@ -285,7 +224,8 @@ export function parseOptions(
|
285 | 224 | mongoClient = undefined;
|
286 | 225 | }
|
287 | 226 |
|
288 |
| - const { url, hosts, isSRV } = parseURI(uri); |
| 227 | + const url = new ConnectionString(uri); |
| 228 | + const { hosts, isSRV } = url; |
289 | 229 |
|
290 | 230 | const mongoOptions = Object.create(null);
|
291 | 231 | mongoOptions.hosts = isSRV ? [] : hosts.map(HostAddress.fromString);
|
|
0 commit comments