Score:2

How can I remove 2 separate portions of a URL using mod_rewrite?

cz flag

I have this unfortunate URL:

dom.tld/library/Photography/index.php?cmd=image&sfpg=2021/*IMG_3468.jpg
dom.tld/library/Photography/index.php?sfpg=2021/*

This should look like this

dom.tld/library/Photography/2021/IMG_3468.jpg
dom.tld/library/Photography/2021/

Essentially, I want to remove index.php?cmd=image&sfpg= and the asterisk * before the filename.

The folder structure looks like this:

root /var/www/domain.tld/main/library/Photography -> tree -a
.
|-- .htaccess
|-- index.php
|-- _GalData
|   |-- info
|   |   |-- 2018
|   |   |   |-- April
|   |   |   |   |-- _sfpg_dir
|   |   |   |   `-- image.png
|   |   |   |-- _sfpg_dir
|   |   |   `-- image.png
|   |   |-- 2019
|   |   |   |-- _sfpg_dir
|   |   |   `-- image.png
|   |   `-- _sfpg_dir
|   `-- thumb
|       |-- 2018
|       |   |-- April
|       |   |   `-- image.jpg
|       |   `-- image.jpg
|       `-- 2019
|           `-- image.jpg
`-- synced
    |-- 2018
    |   |-- April
    |   |   `-- image.jpg
    |   `-- image.jpg
    `-- 2019
        `-- image.jpg

The real images are stored in synced/ and _GalData/ is generated by index.php The main website resides at /var/www/domain.tld/main/index.html

kz flag
Following your update... presumably `folder/image.jpg` then refers to the file-path within the `synced` subdirectory? And you wish to serve the "real images" directly? Presumably `/var/www/domain.tld/main` the document-root directory?
Score:1
sb flag

I am not 100% sure this is the best way to do it, but given the following folder structure

user@instance-apache:/var/www/html$ tree -a
.
├── .htaccess
├── index.html
└── library
    └── photography
        └── folder
            └── image.jpg

and this content of the .htaccess file [UPDATED]

RewriteEngine on
RewriteCond %{QUERY_STRING} .*\=(.*)\*(.*)
RewriteRule (.*/)index.php /$1%1%2 [QSD]

apache should makes

http://127.0.0.1/library/photography/index.php?cmd=image&sfpg=folder/*image.jpg

into

http://127.0.0.1/library/photography/folder/image.jpg

Apver2t5kM avatar
cz flag
This works in an htaccess tester but it makes the whole photography folder return 404 if I put it on my actual site.
Apver2t5kM avatar
cz flag
error.log shows this `applying pattern '/index.php' to uri 'library/Photography/index.php'` `RewriteCond: input='cmd=image&sfpg=2022/*IMG_1991.jpg' pattern='.*\\=(.*?)\\*(.*)' => matched` `rewrite 'library/Photography/index.php' -> '/2022/IMG_1991.jpg'` `discarding query string` I don't know what any of this means
jabbson avatar
sb flag
changed the code block, should be better now, hopefully. I believe the htaccess tester (which I also used to validate), doesn't use the root level .htaccess
Apver2t5kM avatar
cz flag
Thank you. I think I found a problem in the general approach, however. The actual files do not reside where the link would imply. Please see my updated question. The URL is made up by index.php.
Score:1
kz flag

In the .htaccess file located in the subdirectory at /library/photography/.htaccess you can do something like the following using mod_rewrite to internally rewrite the request to the desired URL.

RewriteEngine On

RewriteCond %{QUERY_STRING} (^|&)cmd=image(&|$)
RewriteCond %{QUERY_STRING} (?:^|&)sfpg=([^&*]+)\*([^&]+)(&|$)
RewriteRule ^index\.php$ %1%2 [QSD,L]

The first condition (RewriteCond directive) simply confirms that the cmd=image URL parameter is present anywhere in the query string.

The second condition captures the parts of the sfpg URL parameter value surrounding the * character (which needs to be backslash-escaped when used outside of a regex character class in order to negate its special meaning). These are then available in the %1 and %2 backreferences respectively and used in the substitution string (2nd argument of the RewriteRule directive) is construct a relative file-path (ie. relative to the /library/photography/ subdirectory that contains the .htaccess file).

There URL parameters can appear in any order. eg. ?sfpg=folder/*image.jpg&cmd=image would also successfully match. And there can be additional URL parameters, which are discarded.

The QSD (Query String Discard) flag removes the original query string from the rewritten request (not that it really matters for an internal rewrite).


Aside:

RewriteRule /index.php /

This doesn't really make sense as an internal rewrite, since both /index.php and / should return the same resource. (This would ordinarily be implemented as an external redirect in order to resolve any SEO issues with regards to duplicate content.)


UPDATE:

I think I found a problem in the general approach, however. The actual files do not reside where the link would imply. Please see my updated question.

If I understand your update correctly, the "real file" that you wish to serve is stored in the synced subdirectory and the sfpg URL parameter refers to the file-path within that subdirectory (less the *)? (Which is all within the /library/Photography subdirectory, including the .htaccess file. Or at least the .htaccess file that we are working on here.)

In which case, you would only seem to need to modify the RewriteRule directive by prefixing the substitution string with synced/. For example:

:
RewriteRule ^index\.php$ synced/%1%2 [QSD,L]

(Everything else remains unchanged from the rule above, at the top of my answer.)

Apver2t5kM avatar
cz flag
Thank you. I think I found a problem in the general approach, however. The actual files do not reside where the link would imply. Please see my updated question. The URL is made up by index.php.
kz flag
@Apver2t5kM I've updated my answer following your update.
Apver2t5kM avatar
cz flag
This is very, very close! If I manually enter synced/folder/image.jpg it works. When I go to photography/ through the link found in library/, it still shows the old undesired link. I guess it's not within the scope of mod_rewrite to serve the correct link, but instead the php file? Additionally is it possible to hide the synced/ folder from the URL?
Apver2t5kM avatar
cz flag
I updated the post to clarify what I want the new URLs to look like.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.