forked from micahblu/gulp-connect-php
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
141 lines (128 loc) · 3.44 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
'use strict';
var spawn = require('child_process').spawn;
var exec = require('child_process').exec;
var http = require('http');
var open = require('opn');
var binVersionCheck = require('bin-version-check');
var fs = require('fs');
module.exports = (function () {
var checkServerTries = 0;
var workingPort = 8000;
function checkServer(hostname, port, cb) {
setTimeout(function () {
http.request({
method: 'HEAD',
hostname: hostname,
port: port
}, function (res) {
var statusCodeType = Number(res.statusCode.toString()[0]);
if ([2, 3, 4].indexOf(statusCodeType) !== -1) {
return cb();
} else if (statusCodeType === 5) {
console.log(
'Server docroot returned 500-level response. Please check ' +
'your configuration for possible errors.'
);
return cb();
}
checkServer(hostname, port, cb);
}).on('error', function (err) {
// back off after 1s
if (++checkServerTries > 20) {
console.log('PHP server not started. Retrying...');
return cb();
}
checkServer(hostname, port, cb);
}).end();
}, 50);
}
function extend(obj /* , ...source */) {
for (var i = 1; i < arguments.length; i++) {
for (var key in arguments[i]) {
if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
obj[key] = arguments[i][key];
obj[key] = (typeof arguments[i][key] === 'object' && arguments[i][key] ? extend(obj[key], arguments[i][key]) : arguments[i][key]);
}
}
}
return obj;
}
var closeServer = function (cb) {
var child = exec('lsof -i :' + workingPort,
function (error, stdout, stderr) {
//console.log('stdout: ' + stdout);
//console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
// get pid then kill it
var pid = stdout.match(/php\s+?([0-9]+)/)[1];
if (pid) {
exec('kill ' + pid, function (error, stdout, stderr) {
//console.log('stdout: ' + stdout);
//console.log('stderr: ' + stderr);
cb();
});
} else {
cb({error: "couldn't find process id and kill it"});
}
});
};
var server = function (options, cb){
if (!cb) {
cb = function(){};
}
options = extend({
port: 8000,
hostname: '127.0.0.1',
base: '.',
keepalive: false,
open: false,
bin: 'php',
root: '/',
stdio: 'inherit',
env: {}
}, options);
workingPort = options.port;
var host = options.hostname + ':' + options.port;
var args = ['-S', host];
if (options.ini) {
args.push('-c', options.ini);
}
if (options.router) {
args.push(options.router);
}
binVersionCheck(options.bin, '>=5.4', function (err) {
if (err) {
cb();
return;
}
var checkPath = function(){
var exists = fs.existsSync(options.base);
if (exists === true) {
spawn(options.bin, args, {
cwd: options.base,
stdio: options.stdio,
env: extend(process.env, options.env)
});
}
else{
setTimeout(checkPath, 100);
}
}
checkPath();
// check when the server is ready. tried doing it by listening
// to the child process `data` event, but it's not triggered...
checkServer(options.hostname, options.port, function () {
if (options.open) {
open('http://' + host + options.root);
}
cb();
}.bind(this));
}.bind(this));
};
return {
server: server,
closeServer: closeServer
}
})();