Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
168 lines (136 sloc) 4.12 KB
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_request.h"
#include "apr_strings.h"
module AP_MODULE_DECLARE_DATA common_redirect_module;
typedef struct {
int canonical;
int force_ssl;
const char *dir;
} cr_cfg;
static
char *cr_construct_url(request_rec *r, const char *host, const char *scheme)
{
unsigned int port = ap_get_server_port(r);
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"constructing URL from scheme=%s, host=%s, port=%u, uri=%s",
scheme, host, port, r->unparsed_uri);
if (ap_is_default_port(port, r))
return apr_pstrcat(r->pool, scheme, "://", host,
r->unparsed_uri, NULL);
/* XXX: does not work with RedirectForceSSL */
return apr_psprintf(r->pool, "%s://%s:%u%s", scheme, host,
port, r->unparsed_uri);
}
static
int cr_post_read_request(request_rec *r)
{
cr_cfg *cfg = ap_get_module_config(r->per_dir_config,
&common_redirect_module);
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
"%s: checking common redirects", __FUNCTION__);
/* do not run in subrequests */
if (r->main)
return DECLINED;
/* get current scheme */
const char *scheme = ap_http_scheme(r);
/* canonicalize first to prevent possible CN mismatch in SSL certs */
if (cfg->canonical > 0
&& r->hostname
&& strlen(r->hostname) > 0
&& strcmp(r->hostname, r->server->server_hostname) != 0) {
apr_table_setn(r->headers_out, "Location",
cr_construct_url(r, r->server->server_hostname, scheme));
return HTTP_MOVED_PERMANENTLY;
}
if (cfg->force_ssl > 0 && strcmp(scheme, "https") != 0) {
apr_table_setn(r->headers_out, "Location",
cr_construct_url(r, r->hostname, "https"));
return HTTP_MOVED_PERMANENTLY;
}
/* nothing to do */
return DECLINED;
}
static
void *cr_create_dir_config(apr_pool_t *p, char *dir)
{
cr_cfg *cfg = apr_pcalloc(p, sizeof(cr_cfg));
cfg->dir = dir;
cfg->canonical = cfg->force_ssl = -1;
return cfg;
}
static
void *cr_merge_dir_config(apr_pool_t *p, void *parent, void *current)
{
cr_cfg *parent_cfg = (cr_cfg *) parent;
cr_cfg *current_cfg = (cr_cfg *) current;
cr_cfg *cfg = apr_pcalloc(p, sizeof(cr_cfg));
cfg->dir = apr_pstrdup(p, current_cfg->dir);
cfg->canonical = current_cfg->canonical < 0 ? parent_cfg->canonical : current_cfg->canonical;
cfg->force_ssl = current_cfg->force_ssl < 0 ? parent_cfg->force_ssl : current_cfg->force_ssl;
return cfg;
}
static
void *cr_create_srv_config(apr_pool_t *p, server_rec *s)
{
cr_cfg *cfg = apr_pcalloc(p, sizeof(cr_cfg));
cfg->dir = NULL;
cfg->canonical = cfg->force_ssl = -1;
return cfg;
}
static
void *cr_merge_srv_config(apr_pool_t *p, void *parent, void *current)
{
cr_cfg *parent_cfg = (cr_cfg *) parent;
cr_cfg *current_cfg = (cr_cfg *) current;
cr_cfg *cfg = apr_pcalloc(p, sizeof(cr_cfg));
cfg->canonical = current_cfg->canonical < 0 ? parent_cfg->canonical : current_cfg->canonical;
cfg->force_ssl = current_cfg->force_ssl < 0 ? parent_cfg->force_ssl : current_cfg->force_ssl;
return cfg;
}
static
const char *cmd_redirect_canonical(cmd_parms *cmd, void *mconfig, int arg)
{
cr_cfg *cfg = (cr_cfg *) mconfig;
cfg->canonical = arg;
return NULL;
}
static
const char *cmd_redirect_force_ssl(cmd_parms *cmd, void *mconfig, int arg)
{
cr_cfg *cfg = (cr_cfg *) mconfig;
cfg->force_ssl = arg;
return NULL;
}
static
const command_rec cr_cmds[] = {
AP_INIT_FLAG(
"RedirectCanonical",
cmd_redirect_canonical,
NULL,
OR_FILEINFO,
"whether or not to redirect to the canonical hostname"),
AP_INIT_FLAG(
"RedirectForceSSL",
cmd_redirect_force_ssl,
NULL,
OR_FILEINFO,
"whether or not to redirect to the SSL port"),
{ NULL }
};
static
void cr_register_hooks(apr_pool_t *p)
{
ap_hook_post_read_request(cr_post_read_request, NULL, NULL, APR_HOOK_FIRST);
}
module AP_MODULE_DECLARE_DATA common_redirect_module = {
STANDARD20_MODULE_STUFF,
cr_create_dir_config, /* per-directory config creater */
cr_merge_dir_config, /* dir config merger */
cr_create_srv_config, /* server config creator */
cr_merge_srv_config, /* server config merger */
cr_cmds, /* command table */
cr_register_hooks /* set up other request processing hooks */
};
Jump to Line
Something went wrong with that request. Please try again.