-1

Here is my .htaccess file:

RewriteEngine On

RewriteCond %{HTTP_HOST} ^mywebsite\.com [NC]
RewriteRule ^(.*)$ https://www.mywebsite.com/$1 [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?$1 [L,QSA]

And here is my index.php file:

<?php

$GLOBALS["DEBUG"] = true;

$GLOBALS["DEBUG_MODE"] = "file";
// $GLOBALS["DEBUG_MODE"] = "stdout";
// $GLOBALS["DEBUG_MODE"] = "global";

$GLOBALS["DEBUG_REGEX"] = "^[^b]";
$GLOBALS["ERROR_LOG"]   = true;
// $GLOBALS["DEBUG_SQL"] = true;
// $GLOBALS["PROFILER_SQL"] = true;

// $GLOBALS["DEBUG_CLASS_WALK"]  = true;
// $GLOBALS["DEBUG_CLASS_FOUND"] = true;
// $GLOBALS["DEBUG_CLASS_MATCH"] = "c_";

define("DIR_WEBROOT", realpath(dirname(__FILE__)));

include DIR_WEBROOT . "/xfw/app/startup.php";

d();





// pr(db0()->oQueryFetchArray("SELECT * FROM core_contact"));


pr(r::parseUrl());



if ($a = x_Route::path("^/JSON/(JSON|RAW|DIRECT)/([^/]*)/([^/]*)")) {
    $class  = $a[2];
    $method = $a[3];
    
    $a_params = json_decode(trim(file_get_contents("php://input")), true);
    // $a_params = array_map('sql_escape_string', $a_params);

    try {
        $data = [
            "message" => "ok",
            "data"    => call_user_func_array("$class::$method", [$a_params]),
        ];
    } catch (Exception $e) {
        $data = [
            "message" => "Erreur",
            "data"    => $e->getMessage() . "\n\n" . getExceptionTraceAsString($e),
        ];

        h("err");

        pr(getExceptionTraceAsString($e));
        h("$class::$method");
        pr($a_params);
    }
    
    if ($a[1] == "JSON") {
        echo json_encode($data);
    } elseif ($a[1] == "DIRECT") {
        echo json_encode($data["data"]);
    } else {
        echo $data;
    }

    exit;
}


if ($a = r::path("^/$")) {
    header("Location: /fr/ ");

    exit;
}


if (!r::path("/$")) {
    header("Location: ".ROUTE_PATH."/");

    exit;
}


if ($a = r::path("^/fr/$")) {
    echo View::renderTemplatePublic("public/fr/home.html");

    exit;
}


if ($a = r::path("^/fr/contact/$")) {
    echo View::renderTemplatePublic("public/fr/contact.html", [
        "message" => c_Page::message()
    ]);

    exit;
}


if ($a = r::path("^/fr/(.*)/")) {
    echo View::renderTemplatePublic("public/fr/$a[1].html");

    exit;
}

I want a rule that would add a trailing slash to all URLs except for URLs with an extension (.pdf, .html, ...). Could anyone help me achieve this so that when I have a URL like mywebsite.com/example.pdf it does not redirect me to mywebsite.com/example.pdf/ with a trailing slash at the end?

WhoCares
  • 13
  • 3
  • None of the code you have shown adds a trailing slash. The first block is the HTTPS redirect, and the second one the internal rewrite for non-existing files or folders, to the index.php – CBroe Jun 30 '21 at 11:56
  • How can I fix it then? What's to be added? – WhoCares Jun 30 '21 at 12:56
  • _“What's to be added?”_ - first of all, a _proper_ problem description. We don’t know where those trailing slashes you are talking about are supposed to come from in the first place here, all we can currently tell, is that they _do not_ appear to be coming from the rewrite configuration you have shown us so far. – CBroe Jun 30 '21 at 12:58
  • I found the file that rewrite the URLs to give them a trailing slash at the end (sorry, I keep learning everyday) – WhoCares Jun 30 '21 at 13:30
  • Then it’s probably the `if (!r::path("/$")) { header("Location: ".ROUTE_PATH."/");` part that needs to be modified here. I don’t know what `r::path` is (you did not mention what system/framework you are using here so far), but it seems to work with regular expressions. `/$` only checks if the value ends with a slash, and the condition is negated, to redirect when it doesn’t. – CBroe Jun 30 '21 at 13:41
  • Instead of a complex regular expression, I’d probably use [`pathinfo`](https://www.php.net/manual/en/function.pathinfo.php) here. Try and replace that part with `if (!r::path("/$") && pathinfo(ROUTE_PATH, PATHINFO_EXTENSION) === '') { header("Location: ".ROUTE_PATH."/"); exit; }` The `PATHINFO_EXTENSION` flag makes `pathinfo` return the extension only, and if the path didn’t actually have any, it will just return an empty string. – CBroe Jun 30 '21 at 13:46
  • I tried but it keeps adding the trailing slash to URLs ending with a file extension. – WhoCares Jun 30 '21 at 13:49
  • Oh I tried again and it seems to work fine now, thanks very much! – WhoCares Jun 30 '21 at 13:54

1 Answers1

0

Looks like

if (!r::path("/$")) {
    header("Location: ".ROUTE_PATH."/");

    exit;
}

is the part that needs to be modified here. This appears to be using regular expressions; /$ only checks if the value ends with a slash, and the condition is negated, to redirect when it doesn’t.

Instead of trying to come up with a more complex regular expression, I’d probably use pathinfo here. Try and replace that section with

if (!r::path("/$") && pathinfo(ROUTE_PATH, PATHINFO_EXTENSION) === '') {
  header("Location: ".ROUTE_PATH."/");

  exit;
}

The PATHINFO_EXTENSION flag makes pathinfo return the extension only, and if the path didn’t actually have any, it will just return an empty string.

CBroe
  • 91,630
  • 14
  • 92
  • 150