Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for running the webpack dev server in ssl mode #2089

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/angular-cli/custom-typings.d.ts
Expand Up @@ -17,6 +17,9 @@ interface IWebpackDevServerConfigurationOptions {
headers?: { [key: string]: string };
stats?: { [key: string]: boolean };
inline: boolean;
https?: boolean;
key?: string;
cert?: string;
}

interface WebpackProgressPluginOutputOptions {
Expand Down
23 changes: 21 additions & 2 deletions packages/angular-cli/tasks/serve-webpack.ts
Expand Up @@ -50,6 +50,19 @@ export default Task.extend({
}
}

let sslKey: string = null;
let sslCert: string = null;
if (commandOptions.ssl) {
const keyPath = path.resolve(this.project.root, commandOptions.sslKey);
if (fs.existsSync(keyPath)) {
sslKey = fs.readFileSync(keyPath, 'utf-8');
}
const certPath = path.resolve(this.project.root, commandOptions.sslCert);
if (fs.existsSync(certPath)) {
sslCert = fs.readFileSync(certPath, 'utf-8');
}
}

const webpackDevServerConfiguration: IWebpackDevServerConfigurationOptions = {
contentBase: path.resolve(
this.project.root,
Expand All @@ -61,13 +74,19 @@ export default Task.extend({
proxy: proxyConfig,
watchOptions: {
poll: CliConfig.fromProject().config.defaults.poll
}
},
https: commandOptions.ssl
};

if (sslKey != null && sslCert != null) {
webpackDevServerConfiguration.key = sslKey;
webpackDevServerConfiguration.cert = sslCert;
}

ui.writeLine(chalk.green(oneLine`
**
NG Live Development Server is running on
http://${commandOptions.host}:${commandOptions.port}.
http${commandOptions.ssl ? 's' : ''}://${commandOptions.host}:${commandOptions.port}.
**
`));

Expand Down
23 changes: 23 additions & 0 deletions tests/e2e/assets/ssl/server.crt
@@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIID5jCCAs6gAwIBAgIJAJOebwfGCm61MA0GCSqGSIb3DQEBBQUAMFUxCzAJBgNV
BAYTAlVTMRAwDgYDVQQIEwdHZW9yZ2lhMRAwDgYDVQQHEwdBdGxhbnRhMRAwDgYD
VQQKEwdBbmd1bGFyMRAwDgYDVQQLEwdBbmd1bGFyMB4XDTE2MTAwNDAxMDAyMVoX
DTI2MTAwMjAxMDAyMVowVTELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0dlb3JnaWEx
EDAOBgNVBAcTB0F0bGFudGExEDAOBgNVBAoTB0FuZ3VsYXIxEDAOBgNVBAsTB0Fu
Z3VsYXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDT6Q4d1+mw81SC
4K1qLbsMn4O459XDiDDU/cGBiE0byqi6RpaB0MujCPn35xdeCf1mdDw929leEIRB
w/fCN3VwE+4ZDM7sF6SgoSDN8YT/OOush4tDu0djH110I+i1Bfg4m7gVkUnJLUCv
vMMOlD19LDqqaxdY3ojXx8gZJW9sNtUH2vCICwsZ7aNZp2NcCNKpU7LppP4IomCd
GfG501kY/UtELVgNGX+zuJwIiH/2AQZ+fsaDBBD0Azanck2M/aq5yVKMG8y/S5WP
7LMvZs8ZHPSG73QINogRTYW0EKx7nT87vmrHRtCc9u4coPdqOzQN9BigCYVkYrTv
xkOX9VDHAgMBAAGjgbgwgbUwHQYDVR0OBBYEFG4VV6/aNLx/qFIS9MhAWuyeV5OX
MIGFBgNVHSMEfjB8gBRuFVev2jS8f6hSEvTIQFrsnleTl6FZpFcwVTELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0dlb3JnaWExEDAOBgNVBAcTB0F0bGFudGExEDAOBgNV
BAoTB0FuZ3VsYXIxEDAOBgNVBAsTB0FuZ3VsYXKCCQCTnm8HxgputTAMBgNVHRME
BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQDO4jZT/oKVxaiWr+jV5TD+qwThl9zT
Uw/ZpFDkdbZdY/baCFaLCiJwkK9+puMOabLvm1VzcnHHWCoiUNbWpw8AOumLEnTv
ze/5OZXJ6XlA9kd9f3hDlN5zNB3S+Z2nKIrkPGfxQZ603QCbWaptip5dxgek6oDZ
YXVtnbOnPznRsG5jh07U49RO8CNebqZLzdRToLgObbqYlfRMcbUxCOHXjnB5wUlp
377Iivm4ldnCTvFOjEiDh+FByWL5xic7PjyJPZFMidiYTmsGilP9XTFC83CRZwz7
vW+RCSlU6x8Uejz98BPmASoqCuCTUeOo+2pFelFhX9NwR/Sb6b7ybdPv
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions tests/e2e/assets/ssl/server.key
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA0+kOHdfpsPNUguCtai27DJ+DuOfVw4gw1P3BgYhNG8qoukaW
gdDLowj59+cXXgn9ZnQ8PdvZXhCEQcP3wjd1cBPuGQzO7BekoKEgzfGE/zjrrIeL
Q7tHYx9ddCPotQX4OJu4FZFJyS1Ar7zDDpQ9fSw6qmsXWN6I18fIGSVvbDbVB9rw
iAsLGe2jWadjXAjSqVOy6aT+CKJgnRnxudNZGP1LRC1YDRl/s7icCIh/9gEGfn7G
gwQQ9AM2p3JNjP2quclSjBvMv0uVj+yzL2bPGRz0hu90CDaIEU2FtBCse50/O75q
x0bQnPbuHKD3ajs0DfQYoAmFZGK078ZDl/VQxwIDAQABAoIBAEl17kXcNo/4GqDw
QE2hoslCdwhfnhQVn1AG09ESriBnRcylccF4308aaoVM4CXicqzUuJl9IEJimWav
B7GVRinfTtfyP71KiPCCSvv5sPBFDDYYGugVAS9UjTIYzLAMbLs7CDq5zglmnZkO
Z9QjAZnl/kRbsZFGO8wJ3s0Q1Cp/ygZcvFU331K2jHXW7B4YXiFOH/lBQrjdz0Gy
WBjX4zIdNWnwarvxu46IS/0z1P1YOHM8+B1Uv54MG94A6szBdd/Vp0cQRs78t/Cu
BQ1Rnuk16Pi+ieC5K04yUgeuNusYW0PWLtPX1nKNp9z46bmD1NHKAxaoDFXr7qP3
pZCaDMkCgYEA8mmTYrhXJTRIrOxoUwM1e3OZ0uOxVXJJ8HF6X8t+UO6dFxXB/JC9
ZBc+94cZQapaKFOeMmd/j3L2CQIjChk5yKV/G3Io+raxIoAAKPCkMF4NQQVvvNkS
CAGl61Qa78DoF5Habumz0AC1R9P877kNTC0aPSt4lhPWgfotbZNNMlMCgYEA38nM
s4a0pZseXPkuOtPYX/3Ms3E+d70XKSFuIMCHCg79YGsQ8h/9apYcPyeYkpQ0a4gs
I3IUqMaXC2OyqWA5LU1BZv51mXb6zcb2pokZfpiSWk+7sy5XjkE9EmQxp3xHfV3c
EO/DxHfWNvtMjESMbhu0yVzM2O/Aa53Tl9lqAT0CgYEA1dXBuHyqCtyTG08zO78B
55Ny5rAJ1zkI9jvz2hr0o0nJcvqzcyruliNXXRxkcCNoglg4nXfk81JSrGGhLSBR
c6hhdoF+mqKboLZO7c5Q14WvpWK5TVoiaMOja/J2DHYbhecYS2yGPH7TargaUBDq
JP9IPRtitOhs+Z0Jg7ZDi5cCgYAMb7B6gY/kbBxh2k8hYchyfS41AqQQD2gMFxmB
pHFcs7yM8SY97l0s4S6sq8ykyKupFiYtyhcv0elu7pltJDXJOLPbv2RVpPEHInlu
g8vw5xWrAydRK9Adza5RKVRBFHz8kIy8PDbK4kX7RDfay6xqKgv/7LJNk/VDhb/O
fnyPmQKBgQDg/o8Ubf/gxA9Husnuld4DBu3wwFhkMlWqyO9QH3cKgojQ2JGSrfDz
xHhetmhionEyzg0JCaMSpzgIHY+8o/NAwc++OjNHEoYp3XWM9GTp81ROMz6b83jV
biVR9N0MhONdwF6vtzDCcJxNIUe2p4lTvLf/Xd9jaQDNXe35Gxsdyg==
-----END RSA PRIVATE KEY-----
16 changes: 16 additions & 0 deletions tests/e2e/tests/misc/ssl-default.ts
@@ -0,0 +1,16 @@
import { request } from '../../utils/http';
import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';


export default function() {
return Promise.resolve()
.then(() => ngServe('--ssl', 'true'))
.then(() => request('https://localhost:4200/'))
.then(body => {
if (!body.match(/<app-root>Loading...<\/app-root>/)) {
throw new Error('Response does not match expected value.');
}
})
.then(() => killAllProcesses(), (err) => { killAllProcesses(); throw err; });
}
22 changes: 22 additions & 0 deletions tests/e2e/tests/misc/ssl-with-cert.ts
@@ -0,0 +1,22 @@
import { request } from '../../utils/http';
import { assetDir } from '../../utils/assets';
import { killAllProcesses } from '../../utils/process';
import { ngServe } from '../../utils/project';


export default function() {
return Promise.resolve()
.then(() => ngServe(
'--ssl', 'true',
'--ssl-key', assetDir('ssl/server.key'),
'--ssl-cert', assetDir('ssl/server.crt')
))
.then(() => request('https://localhost:4200/'))
.then(body => {
if (!body.match(/<app-root>Loading...<\/app-root>/)) {
throw new Error('Response does not match expected value.');
}
})
.then(() => killAllProcesses(), (err) => { killAllProcesses(); throw err; });

}
5 changes: 3 additions & 2 deletions tests/e2e/utils/http.ts
Expand Up @@ -4,11 +4,12 @@ import * as _request from 'request';

export function request(url: string): Promise<string> {
return new Promise((resolve, reject) => {
_request(url, (error: any, response: IncomingMessage, body: string) => {
let options = { url: url, agentOptions: { rejectUnauthorized: false }};
_request(options, (error: any, response: IncomingMessage, body: string) => {
if (error) {
reject(error);
} else if (response.statusCode >= 400) {
reject(new Error(`Requesting "${url}" returned status code ${response.statusCode}.`);
reject(new Error(`Requesting "${url}" returned status code ${response.statusCode}.`));
} else {
resolve(body);
}
Expand Down