[prev in list] [next in list] [prev in thread] [next in thread]
List: apache-modperl
Subject: [BUG] PerlCleanUpHandler seems to execute before reply
From: Cone - Sergei Kirjanov <sk () cone ! ee>
Date: 2020-05-27 23:16:27
Message-ID: 614BDA577CD0134AA2D1652A4C19FF58015EF65C97 () EX3 ! edss ! local
[Download RAW message or body]
PerlCleanUpHandle, that is registered in config executes before reply to the client.
So any time-consuming action in the cleanup handler affects response time without any \
notion.
This problem can be workarounded by using $ap->pool->cleanup_register(...), that \
works as expected.
------------------------ details ----------------------
This problem seeems to appear with mod_perl/2.0.9:
ubuntu 14.04: Apache/2.4.7 (Ubuntu) mod_perl/2.0.8 Perl/v5.18.2 -- ok
ubuntu 16.04: Apache/2.4.18 (Ubuntu) mod_perl/2.0.9 Perl/v5.22.1 -- not ok
ubuntu 18.04: Apache/2.4.29 (Ubuntu) mod_perl/2.0.10 Perl/v5.26.1 -- not ok, target
ubuntu 20.04: Apache/2.4.41 (Ubuntu) mod_perl/2.0.11 Perl/v5.30.0 -- not ok
apache.conf:
LoadModule mpm_prefork_module /usr/lib/apache2/modules/mod_mpm_prefork.so
LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so
LoadModule authz_core_module /usr/lib/apache2/modules/mod_authz_core.so
Listen 1080
PidFile /web/.pid
ErrorLog /web/error.log
CustomLog /web/main.log main
ServerName cone2
PerlRequire /web/test.pl
SetHandler perl-script
PerlResponseHandler tnlib::sqcon::handler
PerlCleanUpHandler tnlib::sqcon::cleanuphandler
test.pl:
package tnlib::sqcon;
use strict;
use Apache2::Const qw(OK);
use Apache2::RequestRec ();
use APR::Pool ();
sub handler{
my($ap)=@_;
$ap->pool->cleanup_register(sub{ sleep 5; die 5 });
$ap->status(200);
return OK;
}
sub cleanuphandler{
sleep 5;
}
1;
init.pl:
mkdir "/web/root";
system "/usr/sbin/apache2", "-f", "/web/apache.conf";
system "tail -f /web/main.log /web/error.log";
Dockerfile:
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt update && apt install -y netcat-openbsd curl mc libapache2-mod-perl2 \
libcgi-pm-perl && rm -rf /var/lib/apt/lists/* RUN useradd --home-dir /web \
--create-home --user-group --uid 1979 --shell /bin/bash c2 COPY --chown=c2:c2 . /web/
USER c2
CMD ["perl","/web/init.pl"]
docker build -t apache_cleanup .
docker run --init --rm --name apache_cleanup -p '1080:1080' apache_cleanup
time curl localhost:1080/test -v
docker stop apache_cleanup
[Attachment #3 (text/html)]
<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">// Promises
var _eid_promises = {};
// Turn the incoming message from extension
// into pending Promise resolving
window.addEventListener("message", function(event) {
if(event.source !== window) return;
if(event.data.src && (event.data.src === "background.js")) {
console.log("Page received: ");
console.log(event.data);
// Get the promise
if(event.data.nonce) {
var p = _eid_promises[event.data.nonce];
// resolve
if(event.data.result === "ok") {
if(event.data.signature !== undefined) {
p.resolve({hex: event.data.signature});
} else if(event.data.version !== undefined) {
p.resolve(event.data.extension + "/" + event.data.version);
} else if(event.data.cert !== undefined) {
p.resolve({hex: event.data.cert});
} else {
console.log("No idea how to handle message");
console.log(event.data);
}
} else {
// reject
p.reject(new Error(event.data.result));
}
delete _eid_promises[event.data.nonce];
} else {
console.log("No nonce in event msg");
}
}
}, false);
function TokenSigning() {
function nonce() {
var val = "";
var hex = "abcdefghijklmnopqrstuvwxyz0123456789";
for(var i = 0; i < 16; i++) val += hex.charAt(Math.floor(Math.random() * \
hex.length)); return val;
}
function messagePromise(msg) {
return new Promise(function(resolve, reject) {
// amend with necessary metadata
msg["nonce"] = nonce();
msg["src"] = "page.js";
// send message
window.postMessage(msg, "*");
// and store promise callbacks
_eid_promises[msg.nonce] = {
resolve: resolve,
reject: reject
};
});
}
this.getCertificate = function(options) {
var msg = {type: "CERT", lang: options.lang, filter: options.filter};
console.log("getCertificate()");
return messagePromise(msg);
};
this.sign = function(cert, hash, options) {
var msg = {type: "SIGN", cert: cert.hex, hash: hash.hex, hashtype: hash.type, \
lang: options.lang, info: options.info}; console.log("sign()");
return messagePromise(msg);
};
this.getVersion = function() {
console.log("getVersion()");
return messagePromise({
type: "VERSION"
});
};
}</script><style type="text/css" id="owaParaStyle"></style>
</head>
<body fpstyle="1" ocsi="0">
<div style="direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;">
<div><br>
</div>
<div>PerlCleanUpHandle, that is registered in config executes before reply to the \
client.</div> <div>So any time-consuming action in the cleanup handler affects \
response time without any notion.</div> <div><br>
</div>
<div>This problem can be workarounded by using \
$ap->pool->cleanup_register(...), that works as expected.</div> <div><br>
</div>
<div>------------------------ details ----------------------<br>
</div>
<div><br>
</div>
<div>This problem seeems to appear with mod_perl/2.0.9:</div>
<div>ubuntu 14.04: Apache/2.4.7 (Ubuntu) mod_perl/2.0.8 Perl/v5.18.2 -- ok<br>
ubuntu 16.04: Apache/2.4.18 (Ubuntu) mod_perl/2.0.9 Perl/v5.22.1 -- not ok</div>
<div>ubuntu 18.04: Apache/2.4.29 (Ubuntu) mod_perl/2.0.10 Perl/v5.26.1 -- not ok, \
target<br> ubuntu 20.04: Apache/2.4.41 (Ubuntu) mod_perl/2.0.11 Perl/v5.30.0 -- not \
ok</div> <div><br>
</div>
<div>apache.conf:</div>
<div>LoadModule mpm_prefork_module /usr/lib/apache2/modules/mod_mpm_prefork.so<br>
LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so<br>
LoadModule authz_core_module /usr/lib/apache2/modules/mod_authz_core.so<br>
Listen 1080<br>
PidFile /web/.pid<br>
ErrorLog /web/error.log<br>
CustomLog /web/main.log main<br>
ServerName cone2<br>
PerlRequire /web/test.pl<br>
SetHandler perl-script<br>
PerlResponseHandler tnlib::sqcon::handler<br>
PerlCleanUpHandler tnlib::sqcon::cleanuphandler<br>
</div>
<div><br>
</div>
<div>test.pl:<br>
</div>
<div>package tnlib::sqcon;<br>
use strict;<br>
use Apache2::Const qw(OK);<br>
use Apache2::RequestRec ();<br>
use APR::Pool ();<br>
sub handler{<br>
my($ap)=@_;<br>
$ap->pool->cleanup_register(sub{ sleep 5; die 5 });<br>
$ap->status(200);<br>
return OK;<br>
}<br>
sub cleanuphandler{<br>
sleep 5;<br>
}<br>
1;</div>
<div><br>
</div>
<div>init.pl:</div>
<div>mkdir "/web/root";<br>
system "/usr/sbin/apache2", "-f", \
"/web/apache.conf";<br> system "tail -f /web/main.log \
/web/error.log";<br> <br>
</div>
<div>Dockerfile:</div>
<div>FROM ubuntu:18.04<br>
ENV DEBIAN_FRONTEND=noninteractive <br>
RUN apt update && apt install -y netcat-openbsd curl mc libapache2-mod-perl2 \
libcgi-pm-perl && rm -rf /var/lib/apt/lists/*<br> RUN useradd --home-dir /web \
--create-home --user-group --uid 1979 --shell /bin/bash c2<br> COPY --chown=c2:c2 . \
/web/<br> USER c2<br>
CMD ["perl","/web/init.pl"]<br>
<br>
</div>
<div>docker build -t apache_cleanup .</div>
<div>docker run --init --rm --name apache_cleanup -p '1080:1080' apache_cleanup<br>
</div>
<div>time curl localhost:1080/test -v</div>
<div>docker stop apache_cleanup</div>
<div><br>
</div>
</div>
</body>
</html>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic