Category Archives: apr

Avoid header processing in my Virtual FS module

I want to write a module that serves a huge virtual .wav file (also plan to add a virtual .ogg file in the future).

I know the size of the file (2Gb) and its fake modification time (2000-01-01 0:00:00) and I have a function to read portion of the file:

void virtwav_read(void *buf, ssize_t bufsz, uint32_t virtofs);

I want to hook the low-level file operations like stat, read, seek, etc. The standard apache code should take care of parsing the headers (including range requests, cache-related stuff) and generate Content-Type, Content-Length, ETag, Last-Modified, etc.

Parsing the request_rec.range is not a big deal. What worries me more is sending the right cache-related headers and HTTP 206 and 304 when approprate. I'm sure apache would do that better than my code.

I thought that setting request_rec.mtime and request_rec.clength would do the trick, but they don't seem to be output fields.

Lastly, VFS is surprisingly unpopular topic. I found only one ancient project http://apvfs.sourceforge.net/ dated 2003.

Here's my minimal module and its config. The right Content-Type is added by apache, but no ETag

LoadModule virtwav_module     modules/mod_virtwav.so
AddHandler virtwav-handler .wav

_

#include "apr_hash.h"
#include "ap_config.h"
#include "ap_provider.h"
#include "httpd.h"
#include "http_core.h"
#include "http_config.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"

#include <unistd.h> /* for sleep() */

static int example_handler(request_rec *r)
{
    if (!r->handler || strcmp(r->handler, "virtwav-handler")) return (DECLINED);

    //r->clength = 42;
    //r->mtime = apr_time_now();
    ap_rprintf(r, "clength: %" APR_INT64_T_FMT "\n", (apr_int64_t)r->clength);
    ap_rprintf(r, "mtime: %" APR_INT64_T_FMT "\n", (apr_int64_t)r->mtime);
    ap_rwrite("dummy", 5, r);
    ap_rflush(r);
    sleep(50);

    return OK;
}

static void register_hooks(apr_pool_t *pool)
{
    /* Create a hook in the request handler, so we get called when a request arrives */
    ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);

    // ap_hook_dirwalk_stat ?
    // This hook allows modules to handle/emulate the apr_stat()

    // ap_hook_map_to_storage ?
    // This hook allow modules to set the per_dir_config based on their own
}

module AP_MODULE_DECLARE_DATA   virtwav_module =
{
    STANDARD20_MODULE_STUFF,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    register_hooks   /* Our hook registering function */
};

apache Compile Error : /apps/opt/httpd/include/ap_hooks.h:36:28: error: ap_hook_probes.h: No such file or directory

I am trying to compile the latest apache for Development purpose .

I out the apr 1.5.2 and apr util under

[[email protected] httpd]$ find . -name apr
./srclib/apr
[[email protected] httpd]$ find . -name apr-util
./srclib/apr-util

I compiled my apache on a centos 6 os ( x86_64 x86_64 x86_64 GNU/Linux)

When i am successfully able to run a configure with the below options

sudo ./configure --enable-hook-probes --enable-exception-ok --enable-load-all-modules --enable-maintainer-mode --enable-debugger-mode --enable-pie --enable-authn-anon --enable-authn-socache --enable-mpms-shared='prefork worker' --enable-authz-owner --enable-authz-dbd --enable-authnz-ldap --enable-authnz-fcgi --enable-auth-form --enable-auth-digest --enable-allowmethods --enable-file-cache --enable-cache --enable-cache-disk --enable-cache-socache --enable-socache-memcache --enable-socache-dc --enable-so --enable-mods-shared=reallyall --enable-load-all-modules --enable-watchdog --enable-macro --enable-dumpio --enable-echo --enable-example-hooks --enable-case-filter --enable-case-filter-in --enable-example-ipc --enable-buffer --enable-data --enable-ratelimit --enable-ext-filter --enable-request --enable-include --enable-reflector --enable-substitute --enable-sed --enable-charset-lite --enable-deflate --enable-xml2enc --enable-proxy-html --enable-http --enable-http2 --enable-ldap --enable-log-debug --enable-log-forensic --enable-logio  --enable-mime-magic --enable-cern-meta --enable-expires --enable-ident --enable-usertrack --enable-unique-id --enable-remoteip --enable-proxy --enable-proxy-connect --enable-proxy-ftp --enable-proxy. --enable-proxy-http --enable-proxy. --enable-proxy-fcgi --enable-proxy-scgi --enable-proxy. --enable-proxy-fdpass --enable-proxy. --enable-proxy-wstunnel --enable-proxy-ajp --enable-proxy. --enable-proxy-balancer --enable-proxy-express --enable-session --enable-session-cookie --enable-session-crypto --enable-slotmem-shm --enable-slotmem-plain --enable-ssl --enable-optional-hook-export --enable-optional-hook-import --enable-optional-fn-import --enable-optional-fn-export --enable-dialup --enable-static-support --enable-static-htpasswd --enable-static-htdigest --enable-static-rotatelogs --enable-static-logresolve --enable-static-ab --enable-static-checkgid --enable-static-htcacheclean --enable-static-httxt2dbm --enable-static-fcgistarter --enable-lbmethod-byrequests --enable-lbmethod-bytraffic --enable-lbmethod-bybusyness --enable-lbmethod-heartbeat --enable-unixd --enable-heartbeat --enable-heartmonitor --enable-dav --enable-asis --enable-info --enable-cgid --enable-cgi --enable-dav-fs --enable-dav-lock --enable-vhost-alias --enable-negotiation --enable-imagemap --enable-actions --enable-speling --enable-userdir --enable-rewrite --enable-v4-mapped --with-ldap --with-crypto --with-openssl --with-included-apr --enable-mpms-shared=all --enable-mods-shared=reallyall

But i am not able to do a make . I am running into the below error

sudo make
Making all in srclib
make[1]: Entering directory `/apps/opt/httpd/srclib'
Making all in apr
make[2]: Entering directory `/apps/opt/httpd/srclib/apr'
make[3]: Entering directory `/apps/opt/httpd/srclib/apr'
sed 's,^\(location=\).*$,\1installed,' < apr-1-config > apr-config.out
sed -e 's,^\(apr_build.*=\).*$,\1/usr/local/apache2/build,' -e 's,^\(top_build.*=\).*$,\1/usr/local/apache2/build,' < build/apr_rules.mk > build/apr_rules.out
make[3]: Leaving directory `/apps/opt/httpd/srclib/apr'
make[2]: Leaving directory `/apps/opt/httpd/srclib/apr'
Making all in apr-util
make[2]: Entering directory `/apps/opt/httpd/srclib/apr-util'
Making all in xml/expat
make[3]: Entering directory `/apps/opt/httpd/srclib/apr-util/xml/expat'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/apps/opt/httpd/srclib/apr-util/xml/expat'
make[3]: Entering directory `/apps/opt/httpd/srclib/apr-util'
sed 's,^\(location=\).*$,\1installed,' < apu-1-config > apu-config.out
make[3]: Leaving directory `/apps/opt/httpd/srclib/apr-util'
make[2]: Leaving directory `/apps/opt/httpd/srclib/apr-util'
make[1]: Leaving directory `/apps/opt/httpd/srclib'
Making all in os
make[1]: Entering directory `/apps/opt/httpd/os'
Making all in unix
make[2]: Entering directory `/apps/opt/httpd/os/unix'
make[3]: Entering directory `/apps/opt/httpd/os/unix'
/apps/opt/httpd/srclib/apr/libtool --silent --mode=compile gcc -std=gnu99  -g -O2 -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -pthread -Wpointer-arith -Wdeclaration-after-statement -Werror=declaration-after-statement -Wformat -Wformat-security -Werror=format-security -O0    -DAP_HOOK_PROBES_ENABLED  -DLINUX -D_REENTRANT -D_GNU_SOURCE -DAP_DEBUG     -I. -I/apps/opt/httpd/os/unix -I/apps/opt/httpd/include -I/apps/opt/httpd/srclib/apr/include -I/apps/opt/httpd/srclib/apr-util/include -I/apps/opt/httpd/srclib/apr-util/xml/expat/lib -I/apps/opt/httpd/modules/aaa -I/apps/opt/httpd/modules/cache -I/apps/opt/httpd/modules/core -I/apps/opt/httpd/modules/database -I/apps/opt/httpd/modules/filters -I/apps/opt/httpd/modules/ldap -I/apps/opt/httpd/server -I/apps/opt/httpd/modules/loggers -I/apps/opt/httpd/modules/lua -I/apps/opt/httpd/modules/proxy -I/apps/opt/httpd/modules/session -I/apps/opt/httpd/modules/ssl -I/apps/opt/httpd/modules/test -I/apps/opt/httpd/server -I/apps/opt/httpd/modules/arch/unix -I/apps/opt/httpd/modules/dav/main -I/apps/opt/httpd/modules/generators -I/apps/opt/httpd/modules/mappers -fPIE -prefer-non-pic -static -c unixd.c && touch unixd.lo
In file included from /apps/opt/httpd/include/ap_config.h:25,
                 from unixd.c:17:
/apps/opt/httpd/include/ap_hooks.h:36:28: error: ap_hook_probes.h: No such file or directory
unixd.c: In function 'ap_run_get_suexec_identity':
unixd.c:125: warning: implicit declaration of function 'APR_HOOK_PROBE_ENTRY'
unixd.c:126: error: 'ap' undeclared (first use in this function)
unixd.c:126: error: (Each undeclared identifier is reported only once
unixd.c:126: error: for each function it appears in.)
unixd.c:126: error: 'get_suexec_identity' undeclared (first use in this function)
unixd.c:125: warning: implicit declaration of function 'APR_HOOK_PROBE_INVOKE'
unixd.c:125: warning: implicit declaration of function 'APR_HOOK_PROBE_COMPLETE'
unixd.c:125: warning: implicit declaration of function 'APR_HOOK_PROBE_RETURN'
make[3]: *** [unixd.lo] Error 1
make[3]: Leaving directory `/apps/opt/httpd/os/unix'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/apps/opt/httpd/os/unix'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/apps/opt/httpd/os'
make: *** [all-recursive] Error 1

Error relinking libaprutil while installing apache 2.4.18 on SLES

I am trying to install apache 2.4.18 on SLES 11.2 but I am experiencing an issue which I suppose is related to libaprutil.

After searching about the same issue I tried many solutions like before I was just using ./configure but now I am doing ./configure --with-included-apr --with-included-apr-util --with-ldap

While running ./configure --with-included-apr --with-included-apr-util --with-ldap, I get these:

rm: cannot remove `conftest*': No such file or directory                                                                    
rm: cannot remove `conftest*': No such file or directory                                                                    
rm: cannot remove `libtoolT': No such file or directory

'make' command executes just fine.

But still I am having an issue while make install, as follows:

libtool: warning: relinking 'libaprutil-1.la'  
mv: cannot move `libaprutil-1.so.0.5.4' to `libaprutil-1.so.0.5.4U': Permission denied  
libtool:   error: error: relink 'libaprutil-1.la' with the above command before installing it  
make[2]: *** [install] Error 1  
make[1]:*** [install-recursive] Error 1  
make: *** [install-recursive] Error 1

I also installed expat which I found as a solution on some other forum.
nghttp2 was very old, so I upgraded and that warning is also fixed now.

So, I have almost solved most of the errors except this one which I am unable to figure out as I am running it as root only. Though my root command is a little different due to company restrictions. So I use /proj/sudo/bin/sudo make install

Linker errors in a basic Apache module

I am attempting to write a "hello world" module for Apache HTTPD 2.4. I'm receiving some linker errors when building the module, and many Google searches have not revealed a solution.

My questions are:

  1. How can I resolve the ap_hook_handler linker error? I've searched through the Apache Portable Runtime source and headers and have not found it.
  2. Why is there an undefined reference to main? I thought shared objects don't have a main() entry point.

The source code:

// Dependancies: apr-devel apr-util-devel

#include <httpd.h>
#include <http_config.h>
#include <apr_hooks.h>

static int test_handler(request_rec* request)
{
        return OK;
}

static void register_hooks(apr_pool_t *pool)
{
        ap_hook_handler(test_handler, NULL, NULL, APR_HOOK_LAST);
}

module AP_MODULE_DECLARE_DATA test_module =
{
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL,
        register_hooks
};

The build command:

apxs -lapr-1 -laprutil-1 -c test.c -o mod_test.so

The errors:

apxs -lapr-1 -laprutil-1 -c test.c -o mod_test.so
/usr/lib64/apr-1/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wformat-security -fno-strict-aliasing  -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -pthread -I/usr/include/httpd  -I/usr/include/apr-1   -I/usr/include/apr-1   -c -o test.lo test.c && touch test.slo
/usr/lib64/apr-1/build/libtool --silent --mode=link gcc -o test.la  -lapr-1 -laprutil-1 -rpath /usr/lib64/httpd/modules -module -avoid-version    test.lo -o mod_test.so
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
.libs/test.o: In function `register_hooks':
/root/test/test.c:14: undefined reference to `ap_hook_handler'
collect2: ld returned 1 exit status
apxs:Error: Command failed with rc=65536

unixODBC works but Apache will not connect

I am trying to setup apache to connect to a Microsoft SQL server for authentication. This is not ideal but this legacy system has the credentials in MSSQL and that can not change. I have unixODBC setup and working

**odbcinst.ini**
[SQL Server Native Client 11.0]
Description = Microsoft SQL Server ODBC Driver V1.0 for Linux
Driver = /opt/microsoft/sqlncli/lib64/libsqlncli-11.0.so.1790.0
Threading = 1
UsageCount = 1

**odbc.ini**
[mssql]
Driver = SQL Server Native Client 11.0
Server = 192.168.250.200
Database = DBName

When I connect using isql I am able to query the database without issue

isql mssql username password

+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+

In apache I have configured the following

DBDriver odbc
DBDParams "datasource=mssql,user=username;pass=password"        
DBDMin 1
DBDKeep 2
DBDMax 10
DBDExptime 300

When I start httpd I get this in the error log

[Thu Dec 10 09:10:35 2015] [dbd_odbc] SQLDriverConnect returned SQL_ERROR (-1) at dbd/apr_dbd_odbc.c:1146 [unixODBC][Microsoft][SQL Server Native Client 11.0]Login timeout expired HYT00 [unixODBC][Microsoft][SQL Server Native Client 11.0]TCP Provider: Error code 0xD 08001 [unixODBC][Microsoft][SQL Server Native Client 11.0]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is confi 08001 
[Thu Dec 10 09:10:35.633986 2015] [dbd:error] [pid 15481] (20014)Internal error: AH00629: Can't connect to odbc: [dbd_odbc] SQLDriverConnect returned SQL_ERROR (-1) at dbd/apr_dbd_odbc.c:1146 [unixODBC][Microsoft][SQL Server Native Client 11.0]Login timeout expired HYT00 [unixODBC][Microsoft][SQL Server Native Client 11.0]TCP Provider: Error code 0xD 08001 [unixODBC][Microsoft][SQL Server Native Client 11.0]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is confi 08001 
[Thu Dec 10 09:10:35.634054 2015] [dbd:error] [pid 15481] (20014)Internal error: AH00633: failed to initialise
[Thu Dec 10 09:10:35.634200 2015] [dbd:crit] [pid 15481] (20014)Internal error: AH00636: child init failed!

apache-tomcat – APR does not understand this error code

We are on production with Apache/2.2.27 and Tomcat Version 7.0.55 on linux(2.6.32-431.37.1.el6.x86_64) with 6 core. what we're seeing is below error on webserver which has no pattern as to when it occurs.

(104)Connection reset by peer: ajp_ilink_receive() can't receive header ajp_read_header: ajp_ilink_receive failed (120006)APR does not understand this error code: proxy: read response failed from : ()

it happens quite frequently when we do load test and on normal traffic it happens but rarely. As load ramps up we see cpu utilization going up(not hinting that this is reason) but we start seeing this error usually happens once we cross about 300 user load.

we also have firewall in play between webserver and appserver.

After we see above error webserver jumps from one app server to another app server. probably thinks original server is marked down. This has become very comman with load going up hence I took thread dump to see what's happening and I did not find any blocked threads. I can post whole thread dump if required here is unique thread stack trace where most of threads are under load.

1) "ajp-bio-8009-exec-3396" daemon prio=10 tid=0x00007fa165b99800 nid=0x538b runnable [0x00007fa069ad9000] 
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:152)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at org.apache.coyote.ajp.AjpProcessor.read(AjpProcessor.java:312)
    at org.apache.coyote.ajp.AjpProcessor.readMessage(AjpProcessor.java:367)
    at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:118)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
    - locked <0x00000007d2998118> (a org.apache.tomcat.util.net.SocketWrapper)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)


2) "pool-8-thread-1281" prio=10 tid=0x00007fa0de140800 nid=0x5368 waiting on condition [0x00007fa0721d9000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000050e5f11f8> (a java.util.concurrent.SynchronousQueue$TransferStack)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
    at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

3) "PooledThread[50]" prio=10 tid=0x00007fa0c4125000 nid=0x734 in Object.wait() [0x00007fa0f064e000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000006915ccf60> (a de.hybris.platform.util.threadpool.PoolableThread)
    at java.lang.Object.wait(Object.java:503)
    at de.hybris.platform.util.threadpool.PoolableThread.resetAndReturnToPool(PoolableThread.java:246)
    - locked <0x00000006915ccf60> (a de.hybris.platform.util.threadpool.PoolableThread)
    at de.hybris.platform.util.threadpool.PoolableThread.run(PoolableThread.java:219)

4) "PooledThread[49]" prio=10 tid=0x00007fa0b801f800 nid=0x733 in Object.wait() [0x00007fa066cab000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000653594388> (a de.hybris.platform.util.threadpool.PoolableThread)
    at java.lang.Object.wait(Object.java:503)
    at de.hybris.platform.util.threadpool.PoolableThread.resetAndReturnToPool(PoolableThread.java:246)
    - locked <0x0000000653594388> (a de.hybris.platform.util.threadpool.PoolableThread)
    at de.hybris.platform.util.threadpool.PoolableThread.run(PoolableThread.java:219)

 5) "FD_SOCK client connection handler,hybris-broadcast,hybrisnode-2" daemon prio=10 tid=0x00007fa0bc09d800 nid=0x67b7 runnable [0x00007fa06b9f8000]
    java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:152)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at java.net.SocketInputStream.read(SocketInputStream.java:210)
    at org.jgroups.protocols.FD_SOCK$ClientConnectionHandler.run(FD_SOCK.java:1120)
    at java.lang.Thread.run(Thread.java:745)

Here's our AJP connector config on tomcat

Connector  protocol="AJP/1.3" port="8009" redirectPort="443" useIPVHosts="true" 
URIEncoding="UTF-8" maxThreads="850" minSpareThreads="100" connectionTimeout="30000" 
backlog="1000" keepAliveTimeout="60000" maxConnections="700" acceptorThreadCount="4"/

And below is apache conf

IfModule prefork.c
StartServers 20
MaxSpareServers 40
MinSpareServers 40
ServerLimit 700
MaxClients 700
IfModule

and lb.conf

BalancerMember ajp://<host_ip>:8009 route=app5 retry=60

ProxySet stickysession=JSESSIONID
ProxySet lbmethod=byrequests failonstatus=503,504
ProxySet disablereuse=On