mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Math
synced 2024-11-24 07:34:22 +00:00
Fix SVG glyphs and make the service more robust
Change-Id: I14d3ca2fdc89f8662b2e823b6c891c79db5bab5a
This commit is contained in:
parent
fd8da050fb
commit
6c7f4e3b38
|
@ -57,7 +57,7 @@ window.engine = (new (function() {
|
||||||
// displayed like an image on some different page.
|
// displayed like an image on some different page.
|
||||||
this.merge = function(svg) {
|
this.merge = function(svg) {
|
||||||
var uses,
|
var uses,
|
||||||
copied,
|
copied = {},
|
||||||
k,
|
k,
|
||||||
id,
|
id,
|
||||||
texts,
|
texts,
|
||||||
|
@ -69,19 +69,18 @@ window.engine = (new (function() {
|
||||||
// clone and copy all used paths into local defs.
|
// clone and copy all used paths into local defs.
|
||||||
// xlink:href in uses FIX
|
// xlink:href in uses FIX
|
||||||
uses = svg.getElementsByTagName('use');
|
uses = svg.getElementsByTagName('use');
|
||||||
copied = {};
|
|
||||||
for ( k = 0; k < uses.length; ++k) {
|
for ( k = 0; k < uses.length; ++k) {
|
||||||
id = uses[k].getAttribute('href');
|
id = uses[k].getAttribute('href');
|
||||||
if (id && copied[id]) {
|
if (id && copied[id]) {
|
||||||
uses[k].setAttribute('xlink:href', id);
|
uses[k].setAttribute('xlink:href', id);
|
||||||
// Already copied, skip
|
// Already copied, skip
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
defs.appendChild(
|
defs.appendChild(
|
||||||
document.getElementById(id.substr(1)).cloneNode(true)
|
document.getElementById(id.substr(1)).cloneNode(true)
|
||||||
);
|
);
|
||||||
uses[k].setAttribute('xlink:href', id);
|
uses[k].setAttribute('xlink:href', id);
|
||||||
copied[id] = true;
|
copied[id] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for errors in svg.
|
// check for errors in svg.
|
||||||
|
@ -94,6 +93,7 @@ window.engine = (new (function() {
|
||||||
|
|
||||||
svg.style.position = 'static';
|
svg.style.position = 'static';
|
||||||
tmpDiv = document.createElement('div');
|
tmpDiv = document.createElement('div');
|
||||||
|
tmpDiv.appendChild(defs);
|
||||||
tmpDiv.appendChild(svg);
|
tmpDiv.appendChild(svg);
|
||||||
return tmpDiv.innerHTML;
|
return tmpDiv.innerHTML;
|
||||||
};
|
};
|
||||||
|
@ -125,7 +125,7 @@ window.engine = (new (function() {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
cb([latex, err.message, '-']);
|
cb([latex, err, err]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,7 +39,8 @@ page.onCallback = function(data) {
|
||||||
data[0].length + 'B query, ERR ' + data[1][0] + t;
|
data[0].length + 'B query, ERR ' + data[1][0] + t;
|
||||||
out = JSON.stringify({err:data[1][0],svg:data[1],mml:data[2],'log':log,'sucess':false});
|
out = JSON.stringify({err:data[1][0],svg:data[1],mml:data[2],'log':log,'sucess':false});
|
||||||
resp.write(out);
|
resp.write(out);
|
||||||
//console.log(log);
|
console.log(log);
|
||||||
|
phantom.exit(1);
|
||||||
}
|
}
|
||||||
resp.close();
|
resp.close();
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@ var express = require('express'),
|
||||||
http = require('http'),
|
http = require('http'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
child_process = require('child_process'),
|
child_process = require('child_process'),
|
||||||
|
request = require('request'),
|
||||||
querystring = require('querystring');
|
querystring = require('querystring');
|
||||||
|
|
||||||
var config;
|
var config;
|
||||||
|
@ -40,28 +41,32 @@ console.log( ' - ' + instanceName + ' loading...' );
|
||||||
var restarts = 10;
|
var restarts = 10;
|
||||||
|
|
||||||
var backend,
|
var backend,
|
||||||
|
backendStarting = false,
|
||||||
backendPort,
|
backendPort,
|
||||||
requestQueue = [];
|
requestQueue = [];
|
||||||
|
|
||||||
var startBackend = function () {
|
// forward declaration
|
||||||
|
var handleRequests;
|
||||||
|
|
||||||
|
var backendCB = function () {
|
||||||
|
backendStarting = false;
|
||||||
|
handleRequests();
|
||||||
|
};
|
||||||
|
|
||||||
|
var startBackend = function (cb) {
|
||||||
if (backend) {
|
if (backend) {
|
||||||
backend.kill();
|
backend.removeAllListeners();
|
||||||
|
backend.kill('SIGKILL');
|
||||||
}
|
}
|
||||||
var backendCB = function (err, stdout, stderr) {
|
|
||||||
if (err) {
|
|
||||||
restarts--;
|
|
||||||
if (restarts > 0) {
|
|
||||||
startBackend();
|
|
||||||
}
|
|
||||||
console.error(err.toString());
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
backendPort = Math.floor(9000 + Math.random() * 50000);
|
backendPort = Math.floor(9000 + Math.random() * 50000);
|
||||||
console.error(instanceName + ': Starting backend on port ' + backendPort);
|
console.error(instanceName + ': Starting backend on port ' + backendPort);
|
||||||
backend = child_process.exec('phantomjs main.js ' + backendPort, backendCB);
|
backend = child_process.spawn('phantomjs', ['main.js', backendPort]);
|
||||||
backend.stdout.pipe(process.stdout);
|
backend.stdout.pipe(process.stderr);
|
||||||
backend.stderr.pipe(process.stderr);
|
backend.stderr.pipe(process.stderr);
|
||||||
|
backend.on('close', startBackend);
|
||||||
|
backendStarting = true;
|
||||||
|
// give backend 1 seconds to start up
|
||||||
|
setTimeout(backendCB, 1000);
|
||||||
};
|
};
|
||||||
startBackend();
|
startBackend();
|
||||||
|
|
||||||
|
@ -86,57 +91,67 @@ app.get(/^\/robots.txt$/, function ( req, res ) {
|
||||||
res.end( "User-agent: *\nDisallow: /\n" );
|
res.end( "User-agent: *\nDisallow: /\n" );
|
||||||
});
|
});
|
||||||
|
|
||||||
var handleRequests = function() {
|
|
||||||
// Call the next request on the queue
|
|
||||||
if (requestQueue.length) {
|
|
||||||
requestQueue[0]();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function handleRequest(req, res, tex) {
|
function handleRequest(req, res, tex) {
|
||||||
// do the backend request
|
// do the backend request
|
||||||
var query = new Buffer(querystring.stringify({tex:tex})),
|
var reqbody = new Buffer(querystring.stringify({tex: tex})),
|
||||||
options = {
|
options = {
|
||||||
hostname: 'localhost',
|
method: 'POST',
|
||||||
port: backendPort.toString(),
|
uri: 'http://localhost:' + backendPort.toString() + '/',
|
||||||
path: '/',
|
body: reqbody,
|
||||||
method: 'POST',
|
// Work around https://github.com/ariya/phantomjs/issues/11421 by
|
||||||
headers: {
|
// setting explicit upper-case headers (request sends them lowercase
|
||||||
'Content-Length': query.length,
|
// by default) and manually encoding the body.
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
headers: {
|
||||||
'Connection': 'close'
|
'Content-Length': reqbody.length,
|
||||||
},
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
agent: false
|
},
|
||||||
};
|
timeout: 2000
|
||||||
var chunks = [];
|
};
|
||||||
//console.log(options);
|
request(options, function (err, response, body) {
|
||||||
var httpreq = http.request(options, function(httpres) {
|
body = new Buffer(body);
|
||||||
httpres.on('data', function(chunk) {
|
if (err || response.statusCode !== 200) {
|
||||||
chunks.push(chunk);
|
var errBuf;
|
||||||
});
|
if (err) {
|
||||||
httpres.on('end', function() {
|
errBuf = new Buffer(JSON.stringify({
|
||||||
var buf = Buffer.concat(chunks);
|
tex: tex,
|
||||||
res.writeHead(200,
|
log: err.toString(),
|
||||||
{
|
success: false
|
||||||
'Content-type': 'application/json',
|
}));
|
||||||
'Content-length': buf.length
|
} else {
|
||||||
});
|
errBuf = body;
|
||||||
res.write(buf);
|
}
|
||||||
res.end();
|
res.writeHead(500,
|
||||||
|
{
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Content-Length': errBuf.length
|
||||||
|
});
|
||||||
|
res.end(errBuf);
|
||||||
|
// don't retry the request
|
||||||
requestQueue.shift();
|
requestQueue.shift();
|
||||||
handleRequests();
|
startBackend();
|
||||||
});
|
return handleRequests();
|
||||||
|
}
|
||||||
|
res.writeHead(200,
|
||||||
|
{
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Content-length': body.length
|
||||||
|
});
|
||||||
|
res.end(body);
|
||||||
|
requestQueue.shift();
|
||||||
|
handleRequests();
|
||||||
});
|
});
|
||||||
httpreq.on('error', function(err) {
|
|
||||||
console.log('error', err.toString());
|
|
||||||
res.writeHead(500);
|
|
||||||
return res.end(JSON.stringify({error: "Backend error: " + err.toString()}));
|
|
||||||
});
|
|
||||||
|
|
||||||
httpreq.end(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleRequests = function() {
|
||||||
|
// Call the next request on the queue
|
||||||
|
if (!backendStarting && requestQueue.length) {
|
||||||
|
requestQueue[0]();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
app.post(/^\/$/, function ( req, res ) {
|
app.post(/^\/$/, function ( req, res ) {
|
||||||
// First some rudimentary input validation
|
// First some rudimentary input validation
|
||||||
if (!req.body.tex) {
|
if (!req.body.tex) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"querystring": "0.x.x",
|
"querystring": "0.x.x",
|
||||||
"express": "2.5.x"
|
"express": "2.5.x",
|
||||||
|
"request": "2.x.x"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue