Keep Server Online
If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.
or
A donation makes a contribution towards the costs, the time and effort that's going in this site and building.
Thank You! Steffen
Your donations will help to keep this site alive and well, and continuing building binaries. Apache Lounge is not sponsored.
| |
|
Topic: Custom module to modify headers before ProxyPass |
|
Author |
|
ApacheUser1212123
Joined: 22 Feb 2021 Posts: 7
|
Posted: Mon 22 Feb '21 23:25 Post subject: Custom module to modify headers before ProxyPass |
|
|
Hey,
I have created my own module to modify request headers based on query from database. my module looks like this:
Code: |
static int my_apache2_module_handler(request_rec *r) {
PGconn* conn = PQconnectdb(pg_connection_string);
if (PQstatus(conn) == CONNECTION_BAD) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Connection to database failed : % s\n", PQerrorMessage(conn));
return HTTP_INTERNAL_SERVER_ERROR;
}
// All query logic
apr_table_setn(r->headers_out, my_header, PQgetvalue(res, 0, 0));
PQclear(res);
return OK;
}
static void my_apache2_module_register_hooks(apr_pool_t *p)
{
ap_hook_handler(my_apache2_module_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
...
/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA my_apache2_module_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
NULL, /* create per-server config structures */
NULL, /* merge per-server config structures */
directives, /* table of config file commands */
my_apache2_module_register_hooks /* register hooks */
};
|
I'm trying to make this headers modification before proxy pass (I.E. get some header from user request and add header with value from db before passing it).
I have created vhost looks like that:
Code: |
LoadFile /usr/lib64/libpq.so.5
<VirtualHost *:443>
...
DirectoryIndex index.html index.php
ProxyPreserveHost On
<LocationMatch "/*">
LoadModule my_apache2_module_module /usr/lib64/httpd/modules/mod_my_apache2_module.so
...
ProxyPasssReverse http://127.0.0.1:4444
</LocationMatch>
</VirtualHost>
Listen 444 http
|
The module itself seems to work. I can see the headers I have added, but the request doesn't forwarded.
By this virtual host logs, it looks like it trying to access index file in his /var/www folder, instead of forward the request.
If I remove my custom module the resquest is forwarded correctly.
How can I make the headers modification works with the proxypass? |
|
Back to top |
|
tangent Moderator
Joined: 16 Aug 2020 Posts: 348 Location: UK
|
Posted: Tue 23 Feb '21 14:02 Post subject: |
|
|
Not sure if I'm missing something obvious, but if you're looking to add to the headers being passed through mod_proxy, then don't you need to update r->headers_in rather than r->headers_out?
Request rather than response. |
|
Back to top |
|
ApacheUser1212123
Joined: 22 Feb 2021 Posts: 7
|
Posted: Tue 23 Feb '21 14:57 Post subject: |
|
|
Thanks for your replay.
I have used RequestHeader set before so I thought it should be the same.
I have tried to change the request headers instead, but I still have the same problem.
If I register my module with
Code: | ap_hook_handler(my_apache2_module_handler, NULL, NULL, APR_HOOK_REALLY_LAST); |
The request reach the destination without the wanted header.
and If I change it to
Code: | ap_hook_handler(my_apache2_module_handler, NULL, NULL, APR_HOOK_REALLY_FIRST); |
The request is handled by my module and doesn't forwarded to the destination at all.
My current configuration is like that:
Code: |
LoadFile /usr/lib64/libpq.so.5
LoadModule my_apache2_module_module /usr/lib64/httpd/modules/mod_my_apache2_module.so
<LocationMatch "/*">
pgConnectionString "postgresql:///..."
#RequestHeader set "myheader" "somevalue"
ProxyPassMatch http://127.0.0.1:4440
ProxyPassReverse http://127.0.0.1:4440
</LocationMatch>
|
the pgConnectionString is parameter for my module. I have tried to use the RequestHeader set and the header was added correctly.
Is there a way to make the request handle by my module and then keep it handled by the proxy module? |
|
Back to top |
|
tangent Moderator
Joined: 16 Aug 2020 Posts: 348 Location: UK
|
Posted: Tue 23 Feb '21 16:29 Post subject: |
|
|
Believe you'll need to review and debug your module code somewhat further, in conjunction with https://httpd.apache.org/docs/2.4/developer/modguide.html, and also by looking at existing module code for guidance.
For me, I'd comment out the database query aspect of your module for now, and simply try to add a static string to the request headers.
Code: | apr_table_setn(r->headers_in, "test_header", "testing"); |
Once you've confirmed that's being passed through mod_proxy, you can then go back to adding your database query result.
You might want to consider apr_table_set() rather than apr_table_setn(), since presumably PQclear(res) clears down the results before the headers are processed by mod_proxy.
Last edited by tangent on Wed 24 Feb '21 18:01; edited 2 times in total |
|
Back to top |
|
ApacheUser1212123
Joined: 22 Feb 2021 Posts: 7
|
Posted: Tue 23 Feb '21 19:05 Post subject: |
|
|
Thanks
I couldn't make my module work with the mod_proxy, so I have tried to copy the mod_headers module (from https://github.com/apache/httpd/blob/trunk/modules/metadata/mod_headers.c) and recompile it (I have changed the TAKE variables names and the module name), so I can try to see how it works. But once I have tried to load it, I got the following error:
Quote: |
... is garbled - expected signature 41503234 but saw 00000000 - perhaps this is not an Apache module DSO, or was compiled for a different Apache version?
|
Do you know where can I find the current version of the mod_headers module? |
|
Back to top |
|
tangent Moderator
Joined: 16 Aug 2020 Posts: 348 Location: UK
|
Posted: Tue 23 Feb '21 19:31 Post subject: |
|
|
I'm a little confused.
I'd have thought you were compiling your custom module around the appropriate release of source code, since you'll need any number of header files, libraries, etc.
Based on your Apache version, you can download the appropriate source package from here https://archive.apache.org/dist/httpd |
|
Back to top |
|
ApacheUser1212123
Joined: 22 Feb 2021 Posts: 7
|
Posted: Tue 23 Feb '21 19:46 Post subject: |
|
|
Yes, I'm trying to create my own module, but I couldn't manage to get the headers modification works with the mod_proxy, so I copied the mod_headers module and try to recompile it.
I have tried to copy the module and copy its logic to my own module.
I saw the mod_headers module use filter rather than hooks register. Do you think filter is needed for what I'm trying to do? |
|
Back to top |
|
tangent Moderator
Joined: 16 Aug 2020 Posts: 348 Location: UK
|
Posted: Tue 23 Feb '21 22:58 Post subject: |
|
|
I don't believe you need to go down the complexity of a filter for what you're trying to achieve, but will bow to wisdom from other forum contributors to this site.
Start simple, test and iterate to build up the functionality you require. |
|
Back to top |
|
tangent Moderator
Joined: 16 Aug 2020 Posts: 348 Location: UK
|
Posted: Mon 01 Mar '21 22:43 Post subject: |
|
|
This topic has been niggling me, so I've spent a while looking into it.
The following stripped down module source code does insert a request header (fixed string for testing), which then gets passed through mod_proxy.
The only trick used beyond your code is to ensure the successive module in the ap_hook_fixups is mod_proxy (based on this tip: https://stackoverflow.com/questions/11097096/ensure-execution-order-of-two-apache-filters).
Code: | #include "httpd.h"
#include "http_log.h"
#include "http_request.h"
static int add_headers_in_module_fixups_handler(request_rec* r) {
apr_table_set(r->headers_in, "Apache-Lounge", "Testing");
return OK;
}
static void add_headers_in_register_hooks(apr_pool_t* p) {
static const char * const aszSucc[] = {"mod_proxy.c", NULL};
ap_hook_fixups(add_headers_in_module_fixups_handler, NULL, aszSucc, APR_HOOK_FIRST);
}
/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA add_headers_in_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
NULL, /* create per-server config structures */
NULL, /* merge per-server config structures */
NULL, /* table of config file commands */
add_headers_in_register_hooks /* register hooks */
}; |
Here's sample proxied request / response headers captured with Wireshark, showing the Apache-Lounge request header is present.
GET /images/default.gif HTTP/1.1
Host: dsldevice.lan
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: image/webp,*/*
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: identity
Referer: https://test.somewhere.net/
DNT: 1
Sec-GPC: 1
If-Modified-Since: Thu, 08 Nov 2018 16:22:35 GMT
Cache-Control: max-age=0
Apache-Lounge: Testing
X-Forwarded-For: 192.168.56.1
X-Forwarded-Host: test.somewhere.net
X-Forwarded-Server: test.somewhere.net
Connection: Keep-Alive
HTTP/1.1 304 Not Modified
Content-Type: image/gif
Cache-Control: public
Pragma: cache
Expires: Mon, 01 Mar 2021 20:32:23 GMT
Date: Mon, 01 Mar 2021 20:02:23 GMT
Last-Modified: Thu, 08 Nov 2018 16:22:35 GMT
Accept-Ranges: bytes
Connection: Keep-Alive Hope this helps. |
|
Back to top |
|
James Blond Moderator
Joined: 19 Jan 2006 Posts: 7371 Location: Germany, Next to Hamburg
|
|
Back to top |
|
|
|
|
|
|