Re: write handlers with C or modperl?
I think it really depends on what the handler is doing. If it is mainly executing some db queries rewriting it in C won't make much of a difference. If the handler is doing some expensive computation it might be worth it. Before you rewrite the whole handler though you should look at the option of just implementing the expensive parts and using XS-bindings to load them into the perl handler. That is actually what we did: implementing expensive parser logic that rarely changes in C and calling it from perl while leaving the often-changing business logic in perl. We also catch the most frequently used calls in the nginx reverse proxy and use lua there to fast-track them. In the end it is always a trade-off between performance and maintainability so optimizations like that should only be done on a very limited scope. Hendrik Am 22.07.2016 um 11:53 schrieb André Warnier (tomcat): On 22.07.2016 11:00, yhp...@orange.fr wrote: Hello, We have some handlers which were written by modperl for API endpoints. yes developing a apache handler with modperl is so easy and quick. but for better performance we also consider the C handler. (one of the APIs has got 1,500,000 accesses by unique clients) Do you think if it's valuable to change the handler from modperl to pure C? for C coding we have to take more time to develop, debug and maintain. You have asked the question, and partially answered it yourself. (Just ad the fact that to use mod_perl, means having a perl interpreter in each of your Apache httpd children processes, which is a significant memory overhead). Ask yourself also if you need perl in Apache for anything else than these "some" handlers. If you do, then you have to keep perl anyway, and you would not gain anything (in terms of memory) by moving your handlers to C. As to the overall question, nobody can answer this but yourself. My company runs a bunch (dozens, not hundreds) of websites for customers, under Apache/mod_perl, since many years. The applications are customised and quite sophisticated, but the individual traffic on each website is moderate (not millions per day like you). Over these many years, we have found mod_perl *invaluable* in terms of the flexibility and rapid development that it provides to us, to accomodate a wide range of ever-changing customer requirements in terms of data-entry, user authentication, input and output filtering, etc. etc. (and not least, the availability of CPAN modules, to achieve almost anything you can dream of). So we would not even dream of doing without mod_perl or something at least equivalent; and there /is/ nothing else really equivalent under Apache httpd, when it comes to interacting more deeply with the HTTP request/response cycle than just running some CGI scripts. But if your applications are different (more standard and stable over time e.g.), then maybe you can squeeze some additional performance by converting all or some of your handlers to C. But again, you have to decide that for yourself. I believe that it is maybe the "drama" of mod_perl : it is so powerful, and so flexible, that you kind of get used to it and blasé. Using it, nothing to do with HTTP seems impossible anymore, and nothing requires very large resources or a lot of time to do. Consequently, a development team using mod_perl does not need to get very large, to achieve quite complex things and keep them running. And consequently, such teams tend to remain small and have small budgets, which does not give them (or mod_perl) a very high profile. To get back to your question, maybe there is an intellectual experiment that you can do : Imagine that tomorrow, you get a new management directive, saying that within 6 months all usage of perl and mod_perl on your websites needs to be stopped. And try to figure out what this would cost, in terms of finding alternatives, implementing them and maintaining them over time.
Re: No $r = no mod_perl?
Maybe you are using the wrong sethandler value for your application, check http://perl.apache.org/docs/2.0/user/config/config.html#C_GlobalRequest_ If you are using a global $r variable you should specify SetHandler perl-script and not SetHandler modperl Using the latter you get the $r variable as an argument to your handler-sub. Hendrik Am So, 10.07.2011, 12:08 schrieb Tosh Cooey: So I'm following your advice and going the easy route of apt-get everything. My original server had this config: Apache/2.2.11 (Ubuntu) mod_perl/2.0.4 Perl/v5.10.0 Server And two years later we're at: Apache/2.2.14 (Ubuntu) mod_perl/2.0.4 Perl/v5.10.1 Server Is that really the state of two years of progress in apt-get packages, or did I choose the wrong repository? And so after copying over configs and startups I'm getting this error: Can't call method auth_name on an undefined value at /usr/local/share/perl/5.10.1/Apache2/AuthCookieDBI.pm line 284. Which is: my $auth_name = $r-auth_name; So the fact that $r is undefined tells me that whatever is running is NOT running under mod_perl, is this a valid assessment? Because right now I will have to get into a fight with my sys-admin who will say it's not working because I didn't configure something correctly, but my position is if he apt-gets everything and then copies over the config/startup from the old (working) install then everything *should* work so he's probably left out something. Do you see now why I would prefer to work with a PaaS instead of admins, I don't want to have to deal with this, I just want to write apps. Thanks! Tosh -- McIntosh Cooey - Twelve Hundred Group LLC - http://www.1200group.com/
Re: mod_perl EC2 AMI's or other platform providers?
Am Mo, 4.07.2011, 12:03 schrieb Tosh Cooey: The only public AMI for EC2 setup with mod_perl I can easily find is an OpenSuse one from 2009. Services like Bitnami are a really nice platform for launching LAMP stacks, unfortunately the P is anything but Perl :( Is there a reason for the lack of plug'n'play mod_perl LAMP cloud service providers? Or are there a ton that I just don't know about? Tosh -- McIntosh Cooey - Twelve Hundred Group LLC - http://www.1200group.com/ We run a few EC2 instances with mod_perl setup and afaik there is no public image that gives you an out-of-the-box system. We use Debian images by Alestic (sadly these are not updated any more but I guess one could use their Ubuntu images instead) that give you a basic Debian setup. From there to a working apache/mod_perl it's just a few apt-get install calls (that can be executed automatically when running a new instance) and deploying your application so this should be as far as you can get towards mod_perl. Apart from that I don't think anyone could package a mod_perl image for you that can be used out-of-the-box at all. A usual mod_perl setup needs certain perl-modules in place, a setup.pl, special apache-configurations etc. Hendrik
Re: Apache2::Filter Intermittently Missing Injected String
Am Do, 31.03.2011, 06:30 schrieb Chris Datfung: On Wed, Mar 30, 2011 at 12:36 PM, Hendrik Schumacher h...@activeframe.dewrote: Am Mi, 30.03.2011, 12:17 schrieb Chris Datfung: I had a similar problem with a http proxy that injected a string into the HTML body. If the response is passed to the filter in multiple parts there is a certain probability that the response is split on the string position you are looking for (for example part 2 ends with /bo and part 3 starts with dy). I had to buffer the last bytes of each response part and take them into account Hi Hendrik, That is exactly the problem. How did you buffer the last bytes of each response. Don't you just set the BUFF_LEN and thats the number of characters you get? Chris You have to handle the last bytes buffer yourself. If you use the f-read approach of Apache2::Filter, you could use the following (untested and probably not very efficient): my $lastbytes = undef; my $done = undef; while ($filter-read(my $buffer, $wanted)) { { if ($lastbytes) { $buffer = $lastbytes.$buffer; $lastbytes = undef; } if (not $done) { if ($buffer =~ s/\/body/$injection\/body/) { $done = 1; } else { $lastbytes = substr ($buffer, -6); # length of string to search - 1 $buffer = substr ($buffer, 0, -6); } } $filter-print($buffer); } if ($filter-seen_eos $lastbytes) { $filter-print($lastbytes); } If you are using the callback approach, you would have to store $lastbytes somewhere (eg in $filter-ctx) and make sure to flush $lastbytes on eos. Hendrik
Re: Apache2::Filter Intermittently Missing Injected String
Hi Chris, my example implementation doesnt assume a string cut-off at a certain place. If your search string has a length of 7 bytes, the worst case is that one buffer contains the first 6 bytes and the next buffer the last one. If the string is cut at another place you just carry over a little bit too much (but it doesnt hurt as long as you make sure that the replacement takes place only once). I dont think that you can force the bucket to be a certain length. I dont know how it is handled exactly but I would assume that you get passed any content that is flushed by the previous handler/filter. The only thing you could possibly control is the threshold at which Apache does an automatic flushing of the output buffer. Hendrik Am Do, 31.03.2011, 12:08 schrieb Chris Datfung: Hi Hendrik, That seems like a good work around assuming the string gets cut off at the same place each time. Thanks for that, in my case, I'm not certain that it does. I thought the BUFF_LEN constant defines how many bytes should be read. My string is always within the first 5000 bytes, but setting BUFF_LEN to 8000 did not help as the buffer still sometimes gets cut after ~2500 bytes or so. Do you know of any way to force the bucket to be a certain length? Thanks Chris On Thu, Mar 31, 2011 at 10:07 AM, Hendrik Schumacher h...@activeframe.dewrote: Am Do, 31.03.2011, 06:30 schrieb Chris Datfung: On Wed, Mar 30, 2011 at 12:36 PM, Hendrik Schumacher h...@activeframe.dewrote: Am Mi, 30.03.2011, 12:17 schrieb Chris Datfung: I had a similar problem with a http proxy that injected a string into the HTML body. If the response is passed to the filter in multiple parts there is a certain probability that the response is split on the string position you are looking for (for example part 2 ends with /bo and part 3 starts with dy). I had to buffer the last bytes of each response part and take them into account Hi Hendrik, That is exactly the problem. How did you buffer the last bytes of each response. Don't you just set the BUFF_LEN and thats the number of characters you get? Chris You have to handle the last bytes buffer yourself. If you use the f-read approach of Apache2::Filter, you could use the following (untested and probably not very efficient): my $lastbytes = undef; my $done = undef; while ($filter-read(my $buffer, $wanted)) { { if ($lastbytes) { $buffer = $lastbytes.$buffer; $lastbytes = undef; } if (not $done) { if ($buffer =~ s/\/body/$injection\/body/) { $done = 1; } else { $lastbytes = substr ($buffer, -6); # length of string to search - 1 $buffer = substr ($buffer, 0, -6); } } $filter-print($buffer); } if ($filter-seen_eos $lastbytes) { $filter-print($lastbytes); } If you are using the callback approach, you would have to store $lastbytes somewhere (eg in $filter-ctx) and make sure to flush $lastbytes on eos. Hendrik
Re: Apache2::Filter Intermittently Missing Injected String
Am Mi, 30.03.2011, 12:17 schrieb Chris Datfung: I have a script that uses Apache2::Filter to filter the server response output and inject a string into the HTML body. The script normally works fine expect intermittently the output is missing the injected string. This happens around 10% of the time. I verified that there is enough memory and CPU available and tried playing with the buffer size, but to no avail. The server is running: Apache 2.2.17-2 Modperl 2.0.4-7 Any explanation for why the script fails 10% of the time? Thanks Chris I had a similar problem with a http proxy that injected a string into the HTML body. If the response is passed to the filter in multiple parts there is a certain probability that the response is split on the string position you are looking for (for example part 2 ends with /bo and part 3 starts with dy). I had to buffer the last bytes of each response part and take them into account when looking for the search-string in the next part. I dont know though if this is possible in Apache2::Filter or if this is your problem at all. Hendrik
Re: On memory consumption - request for comments
Am Fr, 11.02.2011, 16:46, schrieb Michael Peters: On 02/11/2011 09:26 AM, Torsten Förtsch wrote: What does that mean? The total size of a process comprises its complete address space. Normally, by far not everything of this space is present in RAM. I'm not sure I'm understanding you correctly here, but are you saying that most of the time not all of a process's memory space is in hardware RAM? If you are saying that, then I would disagree, at least in the context of httpd/mod_perl. Most of the time (if not all the time) the goal should be to have enough RAM that your httpd processes completely fit into memory. Or am I missing something? -- Michael Peters Plus Three, LP I didnt have time yet to read Torsten's post (will do later) but I will take a stab at this question. You are missing the difference between address space and used memory. Sample extract from /proc/*/smaps: Size:884 kB Rss: 536 kB Pss: 17 kB Shared_Clean:536 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 0 kB Referenced: 536 kB Swap: 0 kB In this case the address space has a size of 884 kb. Only 536 kb are used though (Rss/Referenced). All of this space is shared. As you can see the difference between 884 kb and 536 kb is not swapped out but just not allocated. Relying on smaps is a little complicated because the format differs with the kernel version. I usually use (just) Private_Dirty to determine if an apache process should be restarted. Its hard to find good thresholds though. Hendrik
Re: On memory consumption - request for comments
Am Fr, 11.02.2011, 17:10, schrieb Michael Peters: On 02/11/2011 11:01 AM, Hendrik Schumacher wrote: I didnt have time yet to read Torsten's post (will do later) but I will take a stab at this question. You are missing the difference between address space and used memory. Sample extract from /proc/*/smaps: Size:884 kB Rss: 536 kB Pss: 17 kB Shared_Clean:536 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 0 kB Referenced: 536 kB Swap: 0 kB In this case the address space has a size of 884 kb. Only 536 kb are used though (Rss/Referenced). All of this space is shared. As you can see the difference between 884 kb and 536 kb is not swapped out but just not allocated. Interesting. I didn't know that. But I think the questions that Torsten was posing about what would happen if an admin turned off swap while things were running doesn't apply then, right? This memory isn't in swap, it's just not in RAM. So turning off swap won't cause the shared/unshared sizes to blow up, right? -- Michael Peters Plus Three, LP Yes and no. If I modify the example from above: Size:884 kB Rss: 536 kB Pss: 17 kB Shared_Clean:536 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 0 kB Referenced: 536 kB Swap: 64 kB then switching off the swap would cause the Shared or the Private to blow up by 64 kb. Only the address space that is neither present nor swapped does not cause any effect when switching off the swap.
Re: On memory consumption - request for comments
Hi, I would go with rss - shared_size. Especially on 64bit-platforms the total_size gives much too high values (even without swap space). Using the other values like Pss or Swap is not possible on older kernels (I don't have these values on EC2-instances for example). An option would be to substract Swap from unshared_size if it is present. Personally I don't bother if swapped space is shared or not. Hendrik Am Fr, 11.02.2011, 15:26, schrieb Torsten Förtsch: Hi, there is an ongoing discussion initiated by Max whether Apache::SizeLimit does the right thing in reporting the current amount of RAM a process does not share with any other process as unshared_size = total_size - shared_size Max suggests to change that definition to unshared_size = rss - shared_size Beside the fact that that change should be announced very loudly, perhaps by a new major version, because it requires current installations to adjust their parameters I am not sure whether it is the right way. (I am talking about Linux here) What does that mean? The total size of a process comprises its complete address space. Normally, by far not everything of this space is present in RAM. When the process accesses a part of its address space that is not present the CPU generates an interrupt and the operating system reads in that piece from disk or allocates an empty page and thus makes the accessed page present. Then the operation is repeated and this time it succeeds. The process normally is not aware of all this. The part of the process that is really present in RAM is the RSS. Now, Linux comes with the /proc/$PID/smaps device that reports sizes for shared and private portions of the process' address space. How does that work? === Linux organizes the RAM and address spaces in fixed size chunks, so called pages (normally 4kb). Now, a single page of RAM can belongs to only one process or it can be used by multiple processes (for example because they use the same algorithmic part of the C library that is read-only). So, each page has a reference count. If that refcount is 1 the page is used by only one process and hence private to it. If the refcount is 1 the page is shared among multiple processes. When /proc/$PID/smaps is read for a process Linux walks all pages of the process and classifies them in 3 groups: - the page is present in RAM and has a refcount==1 == add it to the process total size and to the private portion - the page is present in RAM and has a refcount1 == add it to the process total size and to the shared portion - the page is not present in RAM == add it to the process total size The point here is, for a page that is not present Linux cannot read the refcount because that count is also not present in RAM. So, to decide if a page is shared or not it would have to read in the page. This is too expensive an operation only to read the refcount. So, while in theory a page is either used by only one process and hence private or by multiple and hence shared in practice we have total_size = private + shared + notpresent where notpresent is either shared or private, we cannot know. How processes are created? == Under Linux a process is create by the fork() or clone() system calls. In theory the operating system duplicates the complete address space of the process calling fork. One copy belongs to the original process (the parent) the other is for the new process (the child). But if we really had to copy the whole address space fork() would be a really expensive operation. In fact, only a table holding pointers to the pages that comprise the parent's address space is duplicated. And all pages are marked read-only and their reference count is incremented. Now, if one of the processes wants to write to a page the CPU again generates an interrupt because the page is marked as read-only. The operating system catches that interrupt. And only now the actual page is duplicated. One page for the writing process and one for the others. The refcount of the new page becomes 1 that of the old is decremented. This working pattern is called copy- on-write. With the apache web server we have one parent process that spawns many children. At first, almost all of the child's address space is shared with the parent due to copy-on-write. Over its lifetime the child's private address space grows by 2 means: * it allocates more memory == total_size grows, unshared grows but shared stays the same. * it writes to portions that were initially shared with the parent == unshared grows, shared shrinks but total_size does not change. Now, what is the goal of Apache::SizeLimit? === If the overall working set of all apache children becomes larger than the available RAM the system then the operating system has to fetch from
Re: Running a proxy in front of mod_perl on Win32
Am Fr, 28.01.2011, 09:31, schrieb Michiel Beijen: On Fri, January 28, 2011 01:14, Michael Peters wrote: Another thing that maybe the OP should look at (if he hasn't already) is to run a proxy in front of the main mod_perl application. Even if the proxy is on the same machine it will help because you can reduce the number of memory-heavy mod_perl processes/threads and handle the same number of connections. I have read that advice before; then it was because of this bug concerning running mod_ssl + mod_perl at the same time on Win32: https://issues.apache.org/bugzilla/show_bug.cgi?id=36751 Unfortunately the bug still exists but the bug report was set to invalid because it did not get proper attention. What would be the best (windows-style) way of running a proxy in front of apache? Insights are welcome! -- Mike (Linux-style) I use nginx and it works great (by coping with ssl and keep-alives) whether you allow it to cache requests or not. It can serve thousands of simultaneous connections and still has just a memory footprint of a few mb. I dont know if the event-model works as great under windows but there are windows builds available on the website (http://nginx.org) so it should be worth a try. Hendrik
Re: How to pre-open files in apache's processes
Am Do, 2.12.2010, 02:24, schrieb Xiao Lan: On Thu, Dec 2, 2010 at 3:38 AM, Mithun Bhattacharya inz...@yahoo.com wrote: Can you confirm the error you are encountering using your current method ? I would like to understand what you are trying to achieve by having a global file handle - do you want to have modular code or does the content of the file somehow determine which handler to be used ? Hi, Thanks for the replying. I was giving the example by openning a file. In acutal I was using this module: http://search.cpan.org/~sunnavy/IP-QQWry-0.0.16/lib/IP/QQWry.pm For each client request if I open the data file: my $qqwry = IP::QQWry-new('QQWry.Dat'); That will be slow IMO. So I was thinking to pre-open the data file in each process of apache and use it directly in each handler. How about this case? Thanks. Regards. Hi. You could do the following (and avoid any possible conflicts when using the file descriptor globally - one thing that comes into my mind would be seek): In the perl file that holds your handler declare a variable on module level: my $qqwry = undef; In the handler instantiate the object if $qqwry is undefined: if (not $qqwry) { $qqwry = IP::QQWry-new('QQWry.Dat'); } This way the file should be opened only once in each apache process (which should be good enough for performance reasons). The my $qqwry on module level should be persistent in each process. Hendrik
Re: How to pre-open files in apache's processes
Am Do, 2.12.2010, 14:24, schrieb Xiao Lan: On Thu, Dec 2, 2010 at 5:58 PM, Hendrik Schumacher h...@activeframe.de wrote: In the perl file that holds your handler declare a variable on module level: my $qqwry = undef; In the handler instantiate the object if $qqwry is undefined: if (not $qqwry) { Â$qqwry = IP::QQWry-new('QQWry.Dat'); } This way the file should be opened only once in each apache process (which should be good enough for performance reasons). The my $qqwry on module level should be persistent in each process. Hi, I'm not sure, what's the perl file that holds your handler? My hanlder is a perl package, which file will hold this package? Thanks. In the perl file that holds your handler means your perl package file. Sounds more difficult as it was meant. The important thing is that the variable has to be declared on package level, not inside a sub routine.
Re: Help: unwanted extra characters in output
Hi, your problem has nothing to do with the mod_perl output. The 20d and 0 are length descriptors for chunked encoding, check out the response header: Transfer-Encoding: chunked This SHOULD be supported by a HTTP 1.1 client. In fact, I would be surprised if cadaver/neon couldnt handle this. Whats the exact error message / unexpected behaviour you get? Hendrik Am Mi, 22.09.2010, 06:44, schrieb Nico Coetzee: Hi - I have a problem which I can't seem to solve. I am busy implementing a webdav solution in mod_perl and as you may know, the output is XML based. The problem is that the output generated by mod_perl contains additional characters before and after the XML which the webdav clients don't seem to like. If I convert this script to a CGI, it works 100% and the extra characters is not present. Any ideas? Here is the example trace (check the 20d and 0 before and after the XML): PROPFIND /webdav/ HTTP/1.1 Host: test:81 User-Agent: cadaver/0.22.3 neon/0.25.5 Connection: TE TE: trailers Depth: 0 Content-Length: 297 Content-Type: application/xml Authorization: Basic dGVzdHVzZXIxOnBhc3N3b3Jk ?xml version=1.0 encoding=utf-8? propfind xmlns=DAV:prop getcontentlength xmlns=DAV:/ getlastmodified xmlns=DAV:/ executable xmlns=http://apache.org/dav/props// resourcetype xmlns=DAV:/ checked-in xmlns=DAV:/ checked-out xmlns=DAV:/ /prop/propfind HTTP/1.1 200 OK Date: Wed, 22 Sep 2010 04:25:57 GMT Server: Apache/2.2.3 (CentOS) Cache-Control: max-age=0 Expires: Wed, 22 Sep 2010 04:25:57 GMT Connection: close Transfer-Encoding: chunked Content-Type: text/xtml; charset=utf-8 20d ?xml version=1.0 encoding=utf-8? D:multistatus xmlns:D=DAV:D:response xmlns:lp1=DAV: xmlns:lp2=http://apache.org/dav/props/; D:href/D:hrefD:propstatD:prop lp1:resourcetypeD:collection//lp1:resourcetype lp1:getlastmodified2010-09-14T05:09:29Z/lp1:getlastmodified lp1:executableF/lp1:executable lp1:getcontentlength4096/lp1:getcontentlength D:checked-in / D:checked-out / D:lockdiscovery/ /D:prop D:statusHTTP/1.1 200 OK/D:status /D:propstat /D:response /D:multistatus 0
Re: Help: unwanted extra characters in output
Btw, if you simply want to disable chunked encoding, buffer your output in your mod_perl handler, set the Content-Length response header once your output is complete and only after that print your output. Apache only activates chunked encoding if no Content-Length header is present when output is sent. Hendrik Am Mi, 22.09.2010, 06:44, schrieb Nico Coetzee: Hi - I have a problem which I can't seem to solve. I am busy implementing a webdav solution in mod_perl and as you may know, the output is XML based. The problem is that the output generated by mod_perl contains additional characters before and after the XML which the webdav clients don't seem to like. If I convert this script to a CGI, it works 100% and the extra characters is not present. Any ideas? Here is the example trace (check the 20d and 0 before and after the XML): PROPFIND /webdav/ HTTP/1.1 Host: test:81 User-Agent: cadaver/0.22.3 neon/0.25.5 Connection: TE TE: trailers Depth: 0 Content-Length: 297 Content-Type: application/xml Authorization: Basic dGVzdHVzZXIxOnBhc3N3b3Jk ?xml version=1.0 encoding=utf-8? propfind xmlns=DAV:prop getcontentlength xmlns=DAV:/ getlastmodified xmlns=DAV:/ executable xmlns=http://apache.org/dav/props// resourcetype xmlns=DAV:/ checked-in xmlns=DAV:/ checked-out xmlns=DAV:/ /prop/propfind HTTP/1.1 200 OK Date: Wed, 22 Sep 2010 04:25:57 GMT Server: Apache/2.2.3 (CentOS) Cache-Control: max-age=0 Expires: Wed, 22 Sep 2010 04:25:57 GMT Connection: close Transfer-Encoding: chunked Content-Type: text/xtml; charset=utf-8 20d ?xml version=1.0 encoding=utf-8? D:multistatus xmlns:D=DAV:D:response xmlns:lp1=DAV: xmlns:lp2=http://apache.org/dav/props/; D:href/D:hrefD:propstatD:prop lp1:resourcetypeD:collection//lp1:resourcetype lp1:getlastmodified2010-09-14T05:09:29Z/lp1:getlastmodified lp1:executableF/lp1:executable lp1:getcontentlength4096/lp1:getcontentlength D:checked-in / D:checked-out / D:lockdiscovery/ /D:prop D:statusHTTP/1.1 200 OK/D:status /D:propstat /D:response /D:multistatus 0
How to handle (103) Software caused connection abort
Hi, I am running mod_perl handlers under mod_perl 2.0.4 and apache 2.2.16. Recently (probably after rebuilding with a more recent apache version - I was using 2.2.9 before) I started frequently getting the following errors in my error log: Apache2::RequestIO::rflush: (103) Software caused connection abort Apache2::RequestIO::print: (103) Software caused connection abort After investigating it seems these errors are caused by a connection aborted by the client (either due to a timeout or user action). What bothers me is that this didnt happen to me before so I am not sure if this is indeed working as intended (and I should catch the fatal error with an eval) or if something is broken on my side. If this is indeed how it works now, the description at http://perl.apache.org/docs/1.0/guide/debug.html on how to handle user aborts (by probing the connection with \0-bytes) is no longer working. The print/rflush has to be wrapped with an eval. The $r-connection-aborted may also be pretty useless then. Could anyone clarify about this? Thanks in advance, Hendrik