|
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