Skip to content

Commit c985508

Browse files
committed
ssl reverse proxy fix based on mod_rapf.c and https://bz.apache.org/bugzilla/show_bug.cgi?id=59829
1 parent 01dd238 commit c985508

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

mod_reverseproxy.c

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
* Derived from mod_remoteip.c and mod_cloudflare.c.
1717
* Credits to cloudflare team and mod_remoteip team.
18-
*
18+
* Modification has been done as per mod_rpaf.c and https://bz.apache.org/bugzilla/show_bug.cgi?id=59829
1919
*/
2020

2121
#include "ap_config.h"
@@ -30,10 +30,14 @@
3030
#define APR_WANT_BYTEFUNC
3131
#include "apr_want.h"
3232
#include "apr_network_io.h"
33+
#include "mod_ssl.h"
34+
#include <stdio.h>
35+
#include <stdlib.h>
3336

3437
module AP_MODULE_DECLARE_DATA reverseproxy_module;
3538

3639
#define AB_DEFAULT_IP_HEADER "X-Real-IP"
40+
#define AB_DEFAULT_PROTO_HEADER "X-Forwarded-Proto"
3741
#define AB_DEFAULT_TRUSTED_PROXY {"127.0.0.1"}
3842
#define AB_DEFAULT_TRUSTED_PROXY_COUNT 1
3943

@@ -56,12 +60,17 @@ typedef struct {
5660
* with the most commonly encountered listed first
5761
*/
5862

59-
int enable_module;
60-
63+
int enable_module;
6164
/**
6265
* you can trun off or turn on this module by using this directive.
6366
*/
6467
apr_array_header_t *proxymatch_ip;
68+
const char *orig_scheme;
69+
int orig_port;
70+
int http_port;
71+
int https_port;
72+
const char *https_scheme;
73+
const char *ab_proto;
6574
} reverseproxy_config_t;
6675

6776
typedef struct {
@@ -79,6 +88,8 @@ typedef struct {
7988
apr_sockaddr_t proxied_addr;
8089
} reverseproxy_conn_t;
8190

91+
apr_OFN_ssl_is_https_t *optfn_is_https = NULL ;
92+
//static APR_OPTIONAL_FN_TYPE(ssl_is_https) *optfn_is_https;
8293
static apr_status_t set_cf_default_proxies(apr_pool_t *p, reverseproxy_config_t *config);
8394

8495
static void *create_reverseproxy_server_config(apr_pool_t *p, server_rec *s)
@@ -95,9 +106,26 @@ static void *create_reverseproxy_server_config(apr_pool_t *p, server_rec *s)
95106
}
96107
config->enable_module = 0;
97108
config->header_name = AB_DEFAULT_IP_HEADER;
109+
config->ab_proto = AB_DEFAULT_PROTO_HEADER;
110+
config->orig_port = s->port;
111+
/* server_rec->server_scheme only available after 2.2.3 */
112+
#if AP_SERVER_MINORVERSION_NUMBER > 1 && AP_SERVER_PATCHLEVEL_NUMBER > 2
113+
config->orig_scheme = s->server_scheme;
114+
#endif
115+
config->https_scheme = apr_pstrdup(p, "https");
116+
config->http_port = 80;
117+
config->https_port = 443;
118+
98119
return config;
99120
}
100121

122+
int ssl_is_https(conn_rec *c) {
123+
const char* rpaf_https = apr_table_get(c->notes, "rpaf_https");
124+
125+
return (rpaf_https != NULL && !strcasecmp(rpaf_https, "on")) || (optfn_is_https && optfn_is_https(c));
126+
127+
}
128+
101129
static void *merge_reverseproxy_server_config(apr_pool_t *p, void *globalv,
102130
void *serverv)
103131
{
@@ -232,6 +260,7 @@ static const char *proxies_set(cmd_parms *cmd, void *internal,
232260
static int reverseproxy_modify_connection(request_rec *r)
233261
{
234262
conn_rec *c = r->connection;
263+
235264
reverseproxy_config_t *config = (reverseproxy_config_t *)
236265
ap_get_module_config(r->server->module_config, &reverseproxy_module);
237266
if (!config->enable_module)
@@ -251,9 +280,33 @@ static int reverseproxy_modify_connection(request_rec *r)
251280
char *eos;
252281
unsigned char *addrbyte;
253282
void *internal = NULL;
283+
const char *scheme;
284+
const char *httpsvalue = apr_table_get(r->headers_in, config->ab_proto) ? apr_table_get(r->headers_in, config->ab_proto) : "http";
285+
apr_table_t *e = r->subprocess_env;
286+
287+
if (strcmp(httpsvalue, config->https_scheme) == 0) {
288+
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, r, "its ssl");
289+
apr_table_setn(r->connection->notes, "rpaf_https", "on");
290+
apr_table_setn(e, "HTTPS", "on");
291+
apr_table_setn(e, "SERVER_PORT", "443");
292+
293+
r->server->port = config->https_port;
294+
r->parsed_uri.port = r->server->port;
295+
scheme = config->https_scheme;
296+
}
297+
else {
298+
apr_table_set(r->connection->notes, "rpaf_https" , "off");
299+
apr_table_set(e, "HTTPS" , "off");
300+
apr_table_set(e, "SERVER_PORT", "80");
254301

255-
apr_pool_userdata_get((void*)&conn, "mod_reverseproxy-conn", c->pool);
302+
r->server->port = config->orig_port;
303+
scheme = config->orig_scheme;
304+
}
305+
#if AP_SERVER_MINORVERSION_NUMBER > 1 && AP_SERVER_PATCHLEVEL_NUMBER > 2
306+
r->server->server_scheme = scheme;
307+
#endif
256308

309+
apr_pool_userdata_get((void*)&conn, "mod_reverseproxy-conn", c->pool);
257310
if (conn) {
258311
if (remote && (strcmp(remote, conn->prior_remote) == 0)) {
259312
/* TODO: Recycle r-> overrides from previous request
@@ -537,6 +590,7 @@ static void register_hooks(apr_pool_t *p)
537590
// We need to run very early so as to not trip up mod_security.
538591
// Hence, this little trick, as mod_security runs at APR_HOOK_REALLY_FIRST.
539592
ap_hook_post_read_request(reverseproxy_modify_connection, NULL, NULL, APR_HOOK_REALLY_FIRST - 10);
593+
APR_REGISTER_OPTIONAL_FN(ssl_is_https);
540594
}
541595

542596
module AP_MODULE_DECLARE_DATA reverseproxy_module = {

0 commit comments

Comments
 (0)