Skip to content

Instantly share code, notes, and snippets.

@progandy
Last active August 26, 2020 11:20
Show Gist options
  • Save progandy/6ed4eeea60f6277c3e39 to your computer and use it in GitHub Desktop.
Save progandy/6ed4eeea60f6277c3e39 to your computer and use it in GitHub Desktop.
mod_proxy_handler for apache 2.4

mod_proxy_handler

This module for apache 2.4 allows you to use e.g. mod_proxy_fcgi in AddHandler or SetHandler directives.

Compile and install the module with apxs:

apxs -i -a -c mod_proxy_handler.c

Example:

Send php files to php-fpm running on a TCP socket:

# set handler for php
LoadModule proxy_handler_module modules/mod_proxy_handler.so
<FilesMatch \.php$>
    SetHandler "proxy:fcgi://127.0.0.1:9000/"
</FilesMatch>

# configuration for phpmyadmin package in archlinux 
Alias /phpmyadmin "/usr/share/webapps/phpMyAdmin"
<Directory "/usr/share/webapps/phpMyAdmin">
    DirectoryIndex index.html index.php
    AllowOverride All
    Options FollowSymlinks
    Require all granted
</Directory>
/*
* Copyright 2014 Andreas Bosch
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
#include "apr_strings.h"
#include "http_request.h"
static int proxy_handler_handler(request_rec *r)
{
// This function is adapted from a patch to mod_proxy
// http://svn.apache.org/viewvc?view=revision&revision=1573626
if (r->filename && !r->proxyreq) {
/* We may have forced the proxy handler via config or .htaccess */
if (r->handler &&
strncmp(r->handler, "proxy:", 6) == 0 &&
strncmp(r->filename, "proxy:", 6) != 0) {
r->proxyreq = PROXYREQ_REVERSE;
r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL);
apr_table_setn(r->notes, "rewrite-proxy", "1");
r->handler = "proxy-server";
// always return declined since we do some weird stuff:
// we modify the request in a handler
return DECLINED;
}
}
return DECLINED;
}
static void proxy_handler_register_hooks(apr_pool_t *p)
{
static const char * const aszSucc[] = { "mod_proxy.c", NULL };
ap_hook_handler(proxy_handler_handler, NULL, aszSucc, APR_HOOK_REALLY_FIRST);
}
/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA proxy_handler_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 */
proxy_handler_register_hooks /* register hooks */
};
@RafaelKa
Copy link

RafaelKa commented May 6, 2014

Hey folks, if you want to use UDS then make it as follows:

Send php files to php-fpm running on a UDS socket:

# set handler for php
LoadModule proxy_handler_module modules/mod_proxy_handler.so
<FilesMatch \.php$>
    SetHandler "proxy:unix:/path/to/socket.sock|fcgi://./"
</FilesMatch>

tested on SVN 2.4.10 candidate

@inthl
Copy link

inthl commented May 9, 2014

what modules are required for this? I am testing the module with 2.4.9 and apache is unable to process any request due to AH01144: No protocol handler was valid for the URL. I have mod_proxy and mod_proxy_http as well as mod_proxy_fcgi loaded

@dzuelke
Copy link

dzuelke commented Jun 2, 2014

@RafaelKa did you (or anyone else) try this with rewrites? When rewriting to path info, e.g. RewriteRule (.*) index.php/$1, it doesn't work; FPM says no input file specified...

@Tragen
Copy link

Tragen commented Sep 2, 2014

I like this module. But why is it so much slower than using ProxyPassMatch?
After the page php page is parsed, it takes nearly 2 seconds until I get the result in my browser.
With ProxyPassMatch it is shown immediately.

@valmirselmani
Copy link

This script helped me a lot, thanks progandy! I just have one problem, if I type a url with a non-existent php file it still goes through the proxy instead of ignoring it and it doesn't use the standard 404 error document from apache. Anyone had the same problem?

OS: RedHat 6
PHP: 5.5.18
Apache: 2.4.6

@BtbN
Copy link

BtbN commented Nov 24, 2014

It is slow because it opens a new connection to php-fpm on every request, instead of reusing an existing pool like ProxyPass(Match) does.
This can be workarounded by setting up a dummy worker for the same proxy url as explained here:
http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#workers

An example configuration could be:

ProxyPass /dummyproxy unix:/path/to/socket.sock|fcgi://./ connectiontimeout=5 timeout=30
<Location /dummyproxy>
    Require all denied
</Location>
AddHandler proxy:unix:/path/to/socket.sock|fcgi://./ .php

It is important that the URLs to the proxy match, in order for them to use the same worker.

Also, i just noticed that support for this was merged into Apache 2.4.10. So if you are running at least that version, you don't need this module anymore. See http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#handler

@butesa
Copy link

butesa commented Jul 24, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment