prevent Apache from serving pages with 304 status code - apache

I have a server, LAMP, set up and a CakePHP App. When I request a web page through any web browser, it always replies with a 304 status, serving old pages even after i have changed the page. It seems like the server keeps any previously accessed page in a cache and serves it back to anybody that request it afterwards. E.g: User "X" logs into this system and access the page "home" and logs out. When a different user "Y" logs into the system, he is going to see "X"'s "home" whereas he is supposed to access his home page with his name displayed. Instead he sees it as X has previously accessed it. When I completely delete a resource, say "home" page, it can still be accessed. I have checked and the pages are served with a 304 not modified status code; However I failed to modify this behavior in my apache Settings; I am a newbie and I am out of solutions. Any help would be much appreciated here.

In case anyone else has the same problem, I will reply to my own question. I have found a potential cause to this behaviour. My apache settings are fine but my lan has an Apache Traffic Server, which kind of caches some resources, things like images and css files are cached by default. If modification is brought to the file, it is advised to rename it so that the old file is not served. For the web pages, I forced their non caching by adding the following:
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="cache-control" content="no-store" />
<meta http-equiv="cache-control" content="must-revalidate" />
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="expires" content="0" />
As I was using cakePHP, I also added the following lines in my beforeFilter method of AppController file (asked here):
function beforeFilter() {
/**
* https://stackoverflow.com/questions/27804628/cakephp-caching-issue-when-redirecting-back-to-same-page
*/
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
}
I hope it helps someone.

Related

How can I get my Hostinger shared hosting server to execute .htaccess file in hidden /.well-known folder?

I am on a Hostinger shared plan, trying to set a CORS header on a single TOML file that MUST reside in the public_html/.well-known folder. I have an .htaccess file in the ".well-known" folder but the Apache server will not process it.
However, if I rename the ".well-known" folder to "well-known" (just removing the period), the .htaccess file works and I can set whatever headers I want for files in that folder.
At this point I have deleted my entire site and replaced it with an extremely simple one in order to try and make this work.
The current file structure is as follows:
public_html
/.well-known
.htaccess
test.toml
/well-known
.htaccess
test.toml
index.html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Apache Header Test</title>
</head>
<body>
Apache Header Test
</body>
</html>
.htaccess (identical in the ".well-known" and "well-known" folders)
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
test.toml (identical in the ".well-known" and "well-known" folders)
Apache Header Test
When I navigate to /well-known/test.toml, the response is served with the CORS header set and a content-type of "text-plain", and the toml file contents show as plain text in Chrome, which is the desired and expected behavior for both folders.
However when I navigate to /.well-known/test.toml (with the period), there is no CORS header, it shows a content-type of "application/octet-stream", and the toml file downloads instead of showing in the browser.
What exactly is happening here and how can I fix it? Thank you!
After finally asking the right question to Hostinger (thank you MrWhite!), they confirmed that making changes to the /.well-known folder is not possible on a shared hosting plan. Here is the official response I received:
The .well-known directory is server-default, so that is why overriding and making changes to it is not possible on a shared hosting plan, as important data/information is stored there.
To make meaningful changes in this directory, you would need root access, which is only available on our VPS plans.

Is it possible to set http headers from SSI?

I have this configuration for static html pages, where redirects are done from flat files as well:
old-location.html
<!-- {new-location.html} -->
<!DOCTYPE html>
<html>
<head>
<title>Redirecting to new location</title>
<link rel="canonical" href="new-location.html" />
<meta name="robots" content="noindex, follow">
<noscript><meta http-equiv="refresh" content="0;URL='new-location.html'" /></noscript>
<script>window.location = "new-location.html"</script>
</head>
<body>
[old-location.html moved here]
</body>
The html is supposed to only serve as a graceful chain of fallbacks, while the comment on the first line is a configuration hook for proper http redirects that, since there's no runtime environment, need to be done by the webserver.
Currently I do this in Openresty, with Lua's matching patterns, finding the new-location and then setting it as a 301 redirect.
header_filter_by_lua_block {
local address = ngx.var.document_root .. ngx.var.document_uri
local file = io.open(address, "rb")
local content = file:read(100)
file:close()
local location = string.match(content, "{(%g+)}")
ngx.header['location'] = location
ngx.status = 301
}
-- ideally I should intercept the response body and spare the extra file read, but it seems that even with Lua this is not possible
However, not everybody accepts to switch to a new webserver. So I wonder if there's a way to do it with off-the-shelf Nginx or, even better, with a generic method that's supported by most/all webservers.
Since the server side includes (is there a way to retrieve a ssi variable from the file and set it as header?) and the sub_module (replace anything except the needed part with some regex, maybe?) both do parse the entire body already, I thought there might be a way, but I don't quite know where to start looking.
There is no built-in way to set HTTP headers from SSI, but you could use a CGI program to do this.

Redict Apache Directory Index

I've got an Apache server, and I'd like to set it up such that when a directory is requested that does not have an index.html file (and thus, Apache would, by default, generate a directory listing), Apache instead redirects (ideally using HTTP code 303) to a given url.
Unless absolutely necessary, I'd like to stay away from going outside Apache (for example, by having Apache load a php script which writes the headers manually). This is an otherwise static site, and I'd like to avoid having to introduce scripting languages into the mix.
Also, note that this post doesn't solve my problem since all of the proposed solutions use external scripts.
So I figured out that by using a combination of HTML meta refreshing and JavaScript redirection, I could cover almost all browsers in use and still have a static file. So what I did was this. In the apache site config, I put a directive that told apache to first look for index.html files, and if that failed, use a site-wide /no-index.html:
<Directory /path/to/web/root>
DirectoryIndex index.html /no-index.html
</Directory>
no-index.html, then, contained the following:
<html>
<head>
<meta http-equiv="refresh" content="0; url=/">
<script type="text/javascript">
window.location = "/";
</script>
</head>
</html>
(in this example it redirects to the web root, /, but you could replace that with whatever url you wanted)
See here for an explanation of what the <meta> tag is doing.

Why output content with a redirect?

When you configure Apache to do a redirect, by default it outputs not just the Location header but also some content, presumably for the benefit of user agents which do not support the Location header:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>301 Moved Permanently</TITLE>
</HEAD><BODY>
<H1>Moved Permanently</H1>
The document has moved here.<P>
<HR>
<ADDRESS>Apache/1.3.37 Server at example.com Port 80</ADDRESS>
</BODY></HTML>
Is this necessary? Is there any user agent, anywhere, that I need to worry about that won't understand a Location header and a blank body?
I suspect not, as example.net itself outputs a blank body. In that case, why does Apache do this?
A number of programmatic tools for accessing websites will not follow redirects by default without explicit configuration. Returning content like this makes it a lot easier to diagnose problems caused by not following a redirect. For example, curl, commonly used in scripts, will only follow redirects if you pass it the -L option.

Favicon for all the pages in my website

I've learned that the way to add favicon for a web page is to have the following lines in the page.
<link rel="SHORTCUT ICON" type="image/x-icon" href="http://mysite.com/faviconfilename.ico"/>
<link rel="icon" type="image/x-icon" href="http://mysite.com/faviconfilename.ico" />
Should i add this code in each and every page my site has?? I use Apache - tomcat clustering to serve pages. Is there any other easy way to do this?
It is usually enough to place a file called "favicon.ico" in the root of your website.
You can get rid of the unnecessary processing and traffic as well as the error log entries by using the following Apache configuration incantations:
# Don't bother looking for favicon.ico
Redirect 404 /favicon.ico
# Send custom text instead of sending the custom error page
<Location /favicon.ico>
ErrorDocument 404 "No favicon"
</Location>
Modify the apache config.
upload this file to the root directory of your website. Make sure that it is readable so that apache can read it. If you have shell access, type: "chmod +r favicon.ico".
Then edit httpd.conf and insert the following line:
"AddType image/x-icon .ico"
Your approach works when you don't have access to your apache config. In this case, if you are using any framework then you should add it to your layout/template.
Here is my method for php sites. It ensures that if you update the favicon, it will be updated immediatly when your clients visit your site:
<link rel="shortcut icon" href="favicon.ico?v=<?php echo time() ?>" />