4

I'm having trouble using modrewrite to redirect a URL with multiple strings.

I have a PDF handling script.

I want to redirect something like:

https://www.example.com/pdfs/samplepdf.pdf/open [or /download]

to

https://www.example.com/pdftools/openpdf.php?file=samplepdf.pdf&task=get&dsp=open [or dsp=download]

In some cases, an ID number is also taken, as a query string:

https://www.example.com/pdfs/samplepdf.pdf/open?id=4334

And the 'extract' function takes two further parameters, thus:

https://www.example.com/pdfs/samplepdf.pdf/32-33/open

Would rewrite to:

https://www.example.com/pdftools/openpdf.php?file=samplepdf.pdf&task=extract&from=32&to=33&dsp=open

So far, I've come up with the following, which does not work:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^pdfs/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /pdftools/openpdf.php?file=$1&task=$2&dsp=$3&id=$4 [L]
RewriteRule ^pdfs/([^/]*)/([^/]*)/([^/]*)$ /pdftools/openpdf.php?file=$1&task=$2&dsp=$3 [L]
RewriteRule ^pdfs/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /pdftools/openpdf.php?file=$1&task=$2&dsp=$3&start=$4&end=$5 [L]  
4
  • "In some cases, an ID number is also taken, as a query string:" / /pdfs/samplepdf.pdf/get/open?id=4334 - so what do you want to happen in this scenario?
    – MrWhite
    Dec 30, 2020 at 15:51
  • Please confirm... It looks like you have omitted /get from the requested URL in the first example? And is /extract not part of the requested URL in the later example (so must be hardcoded in the rewrite)?
    – MrWhite
    Dec 30, 2020 at 16:03
  • 1
    Thanks @MrWhite. In first case "get" was a mistake - ie I want 'task' string invisible, and determined by whether 'to' and 'from' are visible. Dec 30, 2020 at 18:11
  • 1
    /pdfs/samplepdf.pdf/open?id=4334 would redirect to pdftools/openpdf.php?file=samplepdf.pdf&task=get&dsp=open&id=4334 amd /pdfs/samplepdf.pdf/3-4/open?id=4334 would redirect to pdftools/openpdf.php?file=samplepdf.pdf&task=extract&from=3&tp=4&dsp=open&id=4334 Dec 30, 2020 at 18:16

1 Answer 1

3

Just a few notes regarding your existing directives:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^pdfs/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /pdftools/openpdf.php?file=$1&task=$2&dsp=$3&id=$4 [L]
RewriteRule ^pdfs/([^/]*)/([^/]*)/([^/]*)$ /pdftools/openpdf.php?file=$1&task=$2&dsp=$3 [L]
RewriteRule ^pdfs/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /pdftools/openpdf.php?file=$1&task=$2&dsp=$3&start=$4&end=$5 [L]

The conditions that check that the request does not map to a directory and is not a symlink would seem to be superfluous. But these conditions only apply to the first RewriteRule directive anyway.

You seem to be matching against too many path segments. In the examples you posted there would only seem to be either 2 or 3 additional path segments that need to be captured. The one that uses the "extract" function has 3 path segments, one of which contains two numbers separated by a hyphen, which would need to be captured separately.

You also seem to be capturing the value for the task URL parameter from the requested URL, but you've stated that this is not present in the requested URL, so must therefore be hardcoded in the substitution string.

You have 3 rules, but there only appears to be 2 different URLs you need to account for. (One for "get" and another for "extract".)

You are using start and end in the 3rd rule, which should presumably be from and to? Although these also appear to be in the wrong order.

You should be as specific as possible in the regex when matching the input URL. This allows you to avoid conflicts (matching the wrong URL) and provides a certain amount of validation. eg. If the last path segment can only be open or download then match just that, rather than anything. Likewise, if you specifically match the from/to range ie. /NN-NN then this determines that you should be using the "extract" function in the rewritten URL.


Try something like the following instead:

RewriteRule ^pdfs/([\w-]+\.pdf)/(open|download)$ pdftools/openpdf.php?file=$1&task=get&dsp=$2 [QSA,L]
RewriteRule ^pdfs/([\w-]+\.pdf)/(\d+)-(\d+)/(open|download)$ pdftools/openpdf.php?file=$1&task=extract&from=2&to=$3&dsp=$4 [QSA,L]

This assumes that the PDF file (2nd path segment) basename can only consist of the characters a-z, A-Z, 0-9, _ (underscore) or - (hyphen).

This also assumes that the "extract" function can also be open or download (same as the "get" URL).

Since the value for the task parameter does not appear in the requested URL, this must be hardcoded in the rewritten URL, depending on whether the /NN-NN path segment is present or not in the requested URL.

The QSA (Query String Append) flag appends any query string that was present on the original request, eg. id=4334 to the end of the new query string on the rewritten URL. Note, however, that this doesn't specifically check for the id parameter - any parameter(s) will be appended from the initial request.

1
  • 1
    Thank you very helpful. This works Dec 31, 2020 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.