Is it possible to set http headers from SSI? - apache

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.

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.

prevent Apache from serving pages with 304 status code

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.

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.

What HTTP header indicates when Index.html has been served?

Excuse the awkward title: I'm building a simple web server (don't ask...) and have this problem:
The browser requests mydomain.com/MyFolder
My server spots this is a folder, so instead, delivers mydomain.com/MyFolder/index.html
All fine so far, except that index.html has link to mycss.css, but the browser requests it as a top-level file mydomain.com/mycss.css instead of mydomain.com/myFolder/mycss.css.
Is there some HTTP header that needs setting up to indicate that a different page has been served? I've tried returning Content-Location: /myFolder/index.html, but without any visible success.
index.html basically contains this:
<link rel="stylesheet" href="mycss.css" />
Return a 301 Moved Permanently status code, instead of the 200.
Provide a Location header pointing to the same url plus a slash in the end /
Like so:
Location: mydomain.com/MyFolder/
Do not serve the index.html file on that same request, wait for the browser to request again with the slash at the end.
Or just try to add something like this to your .htaccess file:
RewriteEngine On
RewriteBase /
RewriteRule ^(.+)$ myFolder/$1
Can you just try to change this:
<link rel="stylesheet" href="mycss.css" />
to this:
<link rel="stylesheet" href="/myFolder/mycss.css" />
?
Ok, actually the information given was not correct so I'm modifying the answer. If you are implementing a web-server, you must follow the standard specification. The definition <link rel="stylesheet" href="mycss.css" /> shall retrieve the the CSS file from the same location as the file in which it is defined in (index.html) is. When using relative paths, it is not the browser that requests from a specific location but the web-server should determine the location from which to serve the resource.
Check section 2.4.6 and 3 in the standards document: http://www.ietf.org/rfc/rfc1808.txt
In other words, if the path of a resource does not start with the slash (/), it is considered as relative and should be located relative to the base URL.

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.