| 1480 | /* Require Https hook */ |
| 1481 | |
| 1482 | static int md_require_https_maybe(request_rec *r) |
| 1483 | { |
| 1484 | const md_srv_conf_t *sc; |
| 1485 | apr_uri_t uri; |
| 1486 | const char *s, *host; |
| 1487 | const md_t *md; |
| 1488 | int status; |
| 1489 | |
| 1490 | /* Requests outside the /.well-known path are subject to possible |
| 1491 | * https: redirects or HSTS header additions. |
| 1492 | */ |
| 1493 | sc = ap_get_module_config(r->server->module_config, &md_module); |
| 1494 | if (!sc || !sc->assigned || !sc->assigned->nelts || !r->parsed_uri.path |
| 1495 | || !strncmp(WELL_KNOWN_PREFIX, r->parsed_uri.path, sizeof(WELL_KNOWN_PREFIX)-1)) { |
| 1496 | goto declined; |
| 1497 | } |
| 1498 | |
| 1499 | host = ap_get_server_name_for_url(r); |
| 1500 | md = md_get_for_domain(r->server, host); |
| 1501 | if (!md) goto declined; |
| 1502 | |
| 1503 | if (ap_ssl_conn_is_ssl(r->connection)) { |
| 1504 | /* Using https: |
| 1505 | * if 'permanent' and no one else set a HSTS header already, do it */ |
| 1506 | if (md->require_https == MD_REQUIRE_PERMANENT |
| 1507 | && sc->mc->hsts_header && !apr_table_get(r->headers_out, MD_HSTS_HEADER)) { |
| 1508 | apr_table_setn(r->headers_out, MD_HSTS_HEADER, sc->mc->hsts_header); |
| 1509 | } |
| 1510 | } |
| 1511 | else { |
| 1512 | if (md->require_https > MD_REQUIRE_OFF) { |
| 1513 | /* Not using https:, but require it. Redirect. */ |
| 1514 | if (r->method_number == M_GET) { |
| 1515 | /* safe to use the old-fashioned codes */ |
| 1516 | status = ((MD_REQUIRE_PERMANENT == md->require_https)? |
| 1517 | HTTP_MOVED_PERMANENTLY : HTTP_MOVED_TEMPORARILY); |
| 1518 | } |
| 1519 | else { |
| 1520 | /* these should keep the method unchanged on retry */ |
| 1521 | status = ((MD_REQUIRE_PERMANENT == md->require_https)? |
| 1522 | HTTP_PERMANENT_REDIRECT : HTTP_TEMPORARY_REDIRECT); |
| 1523 | } |
| 1524 | |
| 1525 | s = ap_construct_url(r->pool, r->uri, r); |
| 1526 | if (APR_SUCCESS == apr_uri_parse(r->pool, s, &uri)) { |
| 1527 | uri.scheme = (char*)"https"; |
| 1528 | uri.port = 443; |
| 1529 | uri.port_str = (char*)"443"; |
| 1530 | uri.query = r->parsed_uri.query; |
| 1531 | uri.fragment = r->parsed_uri.fragment; |
| 1532 | s = apr_uri_unparse(r->pool, &uri, APR_URI_UNP_OMITUSERINFO); |
| 1533 | if (s && *s) { |
| 1534 | apr_table_setn(r->headers_out, "Location", s); |
| 1535 | return status; |
| 1536 | } |
| 1537 | } |
| 1538 | } |
| 1539 | } |
nothing calls this directly
no test coverage detected