UNPKG

php-embed

Version:

Bidirectional interoperability between PHP and Node.js in a single process

175 lines (172 loc) 5.68 kB
var Promise = require('prfun'); var StringStream = require('../test-stream.js'); var http = require('http'); var querystring = require('querystring'); var should = require('should'); require('should-http'); describe('Feeding POST data from JS to PHP', function() { var php = require('../'); var extend = function(obj1, obj2) { Object.keys(obj2).forEach(function(k) { obj1[k] = obj2[k]; }); return obj1; }; // Create an HTTP server for these tests. var makeServer = function(httpOptions, phpOptions, requestFunc) { var phpValueResolver = Promise.defer(); var responseResolver = Promise.defer(); var outputResolver = Promise.defer(); var out = new StringStream(); var server = http.createServer(function(request, response) { php.request(extend({ request: request, stream: response, }, phpOptions)). tap(function() { response.end(); }). then(phpValueResolver.resolve, phpValueResolver.reject); }); server.listen(0/* Random port */, function() { var address = server.address(); var req = http.request(extend({ host: address.address, port: address.port, }, httpOptions), function(res) { res.on('end', function() { responseResolver.resolve(res); outputResolver.resolve(out.toString()); }); // Pipe the output to a string stream res.pipe(out); }); req.on('error', responseResolver.reject); if (requestFunc) { requestFunc(req); } req.end(); }); return Promise.all([ phpValueResolver.promise, outputResolver.promise, responseResolver.promise, ]); }; it('should handle a basic GET request', function() { var serverOk = false; return makeServer({ path: '/index.html?abc=def&foo=bar+bat', }, { // We have to dereference $_SERVER in order to trigger the // _testInitServer method. source: 'var_dump($_SERVER["CONTEXT"] ? $_GET : $_GET)', _testInitServer: function(server) { serverOk = (server.REQUEST_METHOD === 'GET' && server.REQUEST_URI === '/index.html?abc=def&foo=bar+bat' && server.QUERY_STRING === 'abc=def&foo=bar+bat'); }, }).spread(function(phpvalue, output, response) { should(phpvalue).be.null(); output.should.be.equal([ 'array(2) {', ' ["abc"]=>', ' string(3) "def"', ' ["foo"]=>', ' string(7) "bar bat"', '}', '', ].join('\n')); response.should.be.html(); response.should.have.status(200); response.should.have.header('x-powered-by'); serverOk.should.be.true(); }); }); it('should handle a basic POST request', function() { var serverOk = false; var postData = querystring.stringify({ msg: 'Hello World!', foo: 'bar bat', }); return makeServer({ path: '/post', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': postData.length, }, }, { // We have to dereference $_SERVER in order to trigger the // _testInitServer method. source: 'var_dump($_SERVER["CONTEXT"] ? $_POST : $_POST)', _testInitServer: function(server) { serverOk = (server.REQUEST_METHOD === 'POST' && server.REQUEST_URI === '/post' && server.QUERY_STRING === ''); }, }, function(request) { request.write(postData); }).spread(function(phpvalue, output, response) { should(phpvalue).be.null(); output.should.be.equal([ 'array(2) {', ' ["msg"]=>', ' string(12) "Hello World!"', ' ["foo"]=>', ' string(7) "bar bat"', '}', '', ].join('\n')); response.should.be.html(); response.should.have.status(200); response.should.have.header('x-powered-by'); serverOk.should.be.true(); }); }); it('should handle cookies', function() { var serverOk = false; return makeServer({ path: '/cookie/test', headers: { // RFC 6265 says, "When the user agent generates an HTTP request, // the user agent MUST NOT attach more than one Cookie header // field." (sec 5.4) So we don't need to worry about duplicate // headers sent *to* PHP (except for set-cookie, perhaps, but // that would be very unusual being sent *to* PHP). Cookie: 'foo=bar; bat=ball', }, }, { source: [ 'call_user_func(function() {', ' # ensure that _testInitServer is triggered', ' $_SERVER["CONTEXT"];', ' # ensure we handle duplicate headers sent from PHP', ' setcookie("a", "b");', ' setcookie("c", "d", 0, "/");', ' var_dump($_COOKIE);', ' return 1;', '})', ].join('\n'), _testInitServer: function(server) { serverOk = (server.REQUEST_METHOD === 'GET' && server.REQUEST_URI === '/cookie/test' && server.QUERY_STRING === ''); }, }).spread(function(phpvalue, output, response) { should(phpvalue).be.equal(1); output.should.be.equal([ 'array(2) {', ' ["foo"]=>', ' string(3) "bar"', ' ["bat"]=>', ' string(4) "ball"', '}', '', ].join('\n')); response.should.be.html(); response.should.have.status(200); response.should.have.header('x-powered-by'); response.should.have.header('set-cookie'); response.headers['set-cookie'].should.eql([ 'a=b', 'c=d; path=/', ]); serverOk.should.be.true(); }); }); });