Skip to content

Commit 08ca407

Browse files
committed
Replace depricated url.parse with the WHATWG URL API
close #1380
1 parent 74cbc4b commit 08ca407

File tree

4 files changed

+57
-14
lines changed

4 files changed

+57
-14
lines changed

src/http.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { NtlmClient } from 'axios-ntlm';
88
import { randomUUID } from 'crypto';
99
import debugBuilder from 'debug';
1010
import { ReadStream } from 'fs';
11-
import * as url from 'url';
1211
import MIMEType from 'whatwg-mimetype';
1312
import { gzipSync } from 'zlib';
1413
import { IExOptions, IHeaders, IHttpClient, IOptions } from './types';
@@ -24,6 +23,13 @@ export interface IAttachment {
2423
body: NodeJS.ReadableStream;
2524
}
2625

26+
function getPortFromUrl(url: URL): string {
27+
if (url.port) return url.port;
28+
if (url.protocol.toLowerCase() === 'https:') return '443';
29+
if (url.protocol.toLowerCase() === 'http:') return '80';
30+
return '';
31+
}
32+
2733
/**
2834
* A class representing the http client
2935
* @param {Object} [options] Options object. It allows the customization of
@@ -50,18 +56,19 @@ export class HttpClient implements IHttpClient {
5056
* @returns {Object} The http request object for the `request` module
5157
*/
5258
public buildRequest(rurl: string, data: any, exheaders?: IHeaders, exoptions: IExOptions = {}): any {
53-
const curl = url.parse(rurl);
59+
const curl = new URL(rurl);
5460
const method = data ? 'POST' : 'GET';
5561

5662
const host = curl.hostname;
57-
const port = parseInt(curl.port, 10);
63+
64+
const port = getPortFromUrl(curl);
5865
const headers: IHeaders = {
5966
'User-Agent': 'node-soap/' + version,
6067
'Accept': 'text/html,application/xhtml+xml,application/xml,text/xml;q=0.9,*/*;q=0.8',
6168
'Accept-Encoding': 'none',
6269
'Accept-Charset': 'utf-8',
6370
...(exoptions.forever && { Connection: 'keep-alive' }),
64-
'Host': host + (isNaN(port) ? '' : ':' + port),
71+
'Host': host + (port ? ':' + port : ''),
6572
};
6673
const mergeOptions = ['headers'];
6774

src/server.ts

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55

66
import { EventEmitter } from 'events';
77
import * as http from 'http';
8-
import * as url from 'url';
98
import { IOneWayOptions, IServerOptions, IServices, ISoapFault, ISoapServiceMethod } from './types';
109
import { WSDL } from './wsdl';
1110
import { BindingElement, IPort } from './wsdl/elements';
1211
import zlib from 'zlib';
1312

14-
interface IExpressApp {
13+
interface IExpressApp extends http.Server {
1514
route;
1615
use;
1716
}
1817

1918
export type ServerType = http.Server | IExpressApp;
19+
2020
type Request = http.IncomingMessage & { body?: any };
2121
type Response = http.ServerResponse;
2222

@@ -35,6 +35,28 @@ function getDateString(d) {
3535
return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + 'Z';
3636
}
3737

38+
function getServerBaseUrl(server: ServerType): string {
39+
if (!server) {
40+
return `http://localhost:8080`;
41+
}
42+
43+
if (typeof server.address !== 'function') {
44+
return `http://${server.address}`;
45+
}
46+
47+
const address = server.address();
48+
49+
if (typeof address === 'string') {
50+
return `http://${server.address}`;
51+
}
52+
53+
if (address.family.toLowerCase() === 'ipv6') {
54+
return `http://localhost:${address.port}`;
55+
}
56+
57+
return `http://${address.address}:${address.port}`;
58+
}
59+
3860
//eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
3961
export interface Server {
4062
emit(event: 'request', request: any, methodName: string): boolean;
@@ -74,6 +96,7 @@ export class Server extends EventEmitter {
7496
private enableChunkedEncoding: boolean;
7597
private soapHeaders: any[];
7698
private callback?: (err: any, res: any) => void;
99+
private baseUrl: string;
77100

78101
constructor(server: ServerType, path: string | RegExp, services: IServices, wsdl: WSDL, options?: IServerOptions) {
79102
super();
@@ -90,6 +113,7 @@ export class Server extends EventEmitter {
90113
this.onewayOptions = (options && options.oneWay) || {};
91114
this.enableChunkedEncoding = options.enableChunkedEncoding === undefined ? true : !!options.enableChunkedEncoding;
92115
this.callback = options.callback ? options.callback : () => {};
116+
this.baseUrl = getServerBaseUrl(server);
93117
if (typeof path === 'string' && path[path.length - 1] !== '/') {
94118
path += '/';
95119
} else if (path instanceof RegExp && path.source[path.source.length - 1] !== '/') {
@@ -118,7 +142,7 @@ export class Server extends EventEmitter {
118142
return;
119143
}
120144
}
121-
let reqPath = url.parse(req.url).pathname;
145+
let reqPath = new URL(req.url, this.baseUrl).pathname;
122146
if (reqPath[reqPath.length - 1] !== '/') {
123147
reqPath += '/';
124148
}
@@ -225,7 +249,7 @@ export class Server extends EventEmitter {
225249
}
226250

227251
private _requestListener(req: Request, res: Response) {
228-
const reqParse = url.parse(req.url);
252+
const reqParse = new URL(req.url, this.baseUrl);
229253
const reqQuery = reqParse.search;
230254

231255
if (typeof this.log === 'function') {
@@ -283,7 +307,7 @@ export class Server extends EventEmitter {
283307
}
284308

285309
private _process(input, req: Request, res: Response, cb: (result: any, statusCode?: number) => any) {
286-
const pathname = url.parse(req.url).pathname.replace(/\/$/, '');
310+
const pathname = new URL(req.url, this.baseUrl).pathname.replace(/\/$/, '');
287311
const obj = this.wsdl.xmlToObject(input);
288312
const body = obj.Body;
289313
const headers = obj.Header;
@@ -327,7 +351,7 @@ export class Server extends EventEmitter {
327351
for (name in ports) {
328352
portName = name;
329353
const port = ports[portName];
330-
const portPathname = url.parse(port.location).pathname.replace(/\/$/, '');
354+
const portPathname = new URL(port.location).pathname.replace(/\/$/, '');
331355

332356
if (typeof this.log === 'function') {
333357
this.log('info', 'Trying ' + portName + ' from path ' + portPathname, req);

src/wsdl/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import * as _ from 'lodash';
1212
import * as path from 'path';
1313
import * as sax from 'sax';
1414
import stripBom from 'strip-bom';
15-
import * as url from 'url';
1615
import { HttpClient } from '../http';
1716
import { NamespaceContext } from '../nscontext';
1817
import { IOptions } from '../types';
@@ -1225,7 +1224,15 @@ export class WSDL {
12251224
includePath = path.resolve(path.dirname(this.uri), include.location);
12261225
}
12271226
} else {
1228-
includePath = url.resolve(this.uri || '', include.location);
1227+
if (/^https?:/i.test(include.location)) {
1228+
includePath = include.location;
1229+
} else {
1230+
try {
1231+
includePath = new URL(this.uri || '', include.location).toString();
1232+
} catch {
1233+
includePath = include.location;
1234+
}
1235+
}
12291236
}
12301237

12311238
const options = Object.assign({}, this.options);

test/client-test.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,13 @@ var fs = require('fs'),
508508
client.MyOperation(
509509
{},
510510
function () {
511-
assert.ok(client.lastRequestHeaders.Host.indexOf(':443') > -1);
512-
done();
511+
try {
512+
assert.ok(client.lastRequestHeaders.Host.indexOf(':443') > -1);
513+
done();
514+
} catch (err) {
515+
done(err);
516+
throw err;
517+
}
513518
},
514519
null,
515520
{ 'test-header': 'test' },

0 commit comments

Comments
 (0)