#!/usr/bin/env python
#
#  File: custom-errors.py
# 
#  Copyright (C) 2006 Christopher R. Gabriel <cgabriel@truelite.it>
#  Copyright (C) 2006 Truelite Srl <info@truelite.it>
# 
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
# 
#  This is a small python script to generate custom error pages
#  for the squid proxy server.

import sys, os.path


header_start = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>
%(result)s: %(result_message)s
</TITLE>
<STYLE type="text/css">
<!--
"""

header_end = """

-->
</STYLE>
</HEAD>
<BODY>
<h1 id="result">%(result)s</h1>
<h2 id="result_message">%(result_message)s</h2>

"""
# don't forget that squid will add the closure for <body>
# and <html>, plus an <address> with the information
# about page generation

footer = """
<p id="adminaddress">Your proxy/cache administrator is <a href="mailto:%w">%w</a></p>
<p id="footer">Truelite ProxyServer</p>
"""

if len(sys.argv) > 1:
	css = open(sys.argv[1]).read()
else:
	css = """
body {
background: #fff;
color: #000;
font-family: Trebuchet MS, Arial, Verdana;
margin: 0px;
}

#page {
margin: 40px
}

#result {
color: #a00;
border: 1px solid black;
margin: 20px;
padding: 20px;
}

#result_message {
   margin: 30px;
}

#reason {
background: #ddd;
padding: 30px;
border: 1px solid #aaa;
}

#error {
border: 1px solid #aaa;
padding: 10px;
}

#reasonhelp {
font-size: 12px;
}

#adminaddress {
font-size: 12px;
text-align: center;
text-decoration: underline;
}

#footer {
padding: 20px;
color: #fff;
font-size: 14px;
text-align: center;
width: 100%;
background: #666;
}

address {
font-size: 8px;
width: 100%;
text-align:center;

}

"""

# this dictionary can be created by using something like
# for i in `ls ERR_*`; do echo \"$i\": {\"result\": \"`grep H1 $i | sed 's/H1//g' | sed -e 's/<//g' #| sed 's/>//g' | sed 's/\///g'`\",\"result_message\":\"`grep H2 $i | sed 's/H2//g' | 
#sed -e 's/<//g'| sed 's/>//g' | sed 's/\///g'`\", \"body\":\"\" }, >> file; done
#
# in the squid error template directory
# dirty, but it works

mesg = {
"ERR_ACCESS_DENIED": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Access Denied.</p>
</div>
<div id="reasonhelp">
<p>
Access control configuration prevents your request from
being allowed at this time.  Please contact your service provider if
you feel this is incorrect.</p>
</div>
</div>

""" },
"ERR_CACHE_ACCESS_DENIED": {"result": "ERROR","result_message":"Cache Access Denied", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error">
<p>The following error was encountered:</p>
<p id="reason">Cache Access Denied.</p>
</div>
<div id="reasonhelp">
<p>
Sorry, you are not currently allowed to request:
<PRE>%U</PRE>
from this cache until you have authenticated yourself.
</p><p>
You need to use Netscape version 2.0 or greater, or Microsoft Internet
Explorer 3.0, or an HTTP/1.1 compliant browser for this to work.  Please
contact the <a href="mailto:%w">cache administrator</a> if you have
difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>
</div></div>
""" },
"ERR_CACHE_MGR_ACCESS_DENIED": {"result": "ERROR","result_message":"Cache Manager Access Denied", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error">
<p>The following error was encountered:</p>
<p id="reason">Cache Manager Access Denied.</p>
<div>
<div id="reasonhelp">
<p>
Sorry, you are not currently allowed to request:
<PRE>%U</PRE>
from this cache manager until you have authenticated yourself.
</p><p>
You need to use Netscape version 2.0 or greater, or Microsoft Internet
Explorer 3.0, or an HTTP/1.1 compliant browser for this to work.  Please
contact the <a href="mailto:%w">cache administrator</a> if you have
difficulties authenticating yourself or, if you <em>are</em> the
administrator, read Squid documentation on cache manager interface and check
cache log for more detailed error messages.
</p>
</div></div>
""" },
"ERR_CANNOT_FORWARD": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Unable to forward this request at this time.</p>
</div>
<div id="reasonhelp">
<p>
This request could not be forwarded to the origin server or to any
parent caches.  The most likely cause for this error is that:
<UL>
<LI>The cache administrator does not allow this cache to make
    direct connections to origin servers, and
<LI>All configured parent caches are currently unreachable.
</UL>
</div>
</div>
""" },
"ERR_CONNECT_FAIL": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Connection Failed.</p>
</div>
<div id="reasonhelp">
<p>
The system returned:
<pre>%E</pre>
</p>
<p>
The remote host or network may be down.  Please try the request again.
</p>
</div>
</div>
""" },
"ERR_DNS_FAIL": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Unable to determine IP address from host name for <i>%H</i>
</p>
</div>
<div id="reasonhelp">
<p>
The dns server returned:
<BLOCKQUOTE>
%z
</BLOCKQUOTE>
</p>
<p>
This means that the cache was not able to resolve the hostname presented in the URL. Check if the address is correct.
</p>
</div>
</div>
""" },
"ERR_FORWARDING_DENIED": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Forwarding Denied.</p>
</div>
<div id="reasonhelp">
<p>
This cache will not forward your request because it is trying to enforce a
sibling relationship.  Perhaps the client at %i is a cache which has been
misconfigured.
</p>
</div>
</div>
""" },
"ERR_FTP_DISABLED": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">FTP is disabled.</p>
</div>
<div id="reasonhelp">
<p>
This cache does not support FTP.
</p>
</div>
</div>
""" },
"ERR_FTP_FAILURE": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">An FTP protocol error occurred while trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">FTP Protocol Error</p>
</div>
<div id="reasonhelp">
<p>
Squid sent the following FTP command:
<pre>%f</pre>
and then received this reply
<pre>%F</pre>
<pre>%g</pre>
</p>
</div>
</div>
""" },
"ERR_FTP_FORBIDDEN": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">An FTP protocol error occurred while trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">FTP Protocol Error</p>
</div>
<div id="reasonhelp">
<p>
Squid sent the following FTP command:
<pre>%f</pre>
and then received this reply
<pre>%F</pre>
<pre>%g</pre>
</p>
</div>
</div>
""" },
"ERR_FTP_NOT_FOUND": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">An FTP protocol error occurred while trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">FTP Protocol Error</p>
</div>
<div id="reasonhelp">
<p>
Squid sent the following FTP command:
<pre>%f</pre>
and then received this reply
<pre>%F</pre>
<pre>%g</pre>
</p>
</div>
</div>
""" },
"ERR_FTP_PUT_CREATED": {"result": "Operation successful","result_message":"File created", "body":"""
<div id="page">
</div>

""" },
"ERR_FTP_PUT_ERROR": {"result": "ERROR","result_message":"FTP PUT/upload failed", "body":"""
<div id="page">
<p id="while">An FTP protocol error occurred while trying to PUT the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">FTP Protocol Error</p>
</div>
<div id="reasonhelp">
<p>
Squid sent the following FTP command:
<pre>%f</pre>
and then received this reply
<pre>%F</pre>
</p>
<p>
This means that you have to: Check path, permissions, diskspace and try again.
</p>
</div>
</div>
""" },
"ERR_FTP_PUT_MODIFIED": {"result": "Operation successful","result_message":"File updated", "body":"""
<div id="page">
</div>

""" },
"ERR_FTP_UNAVAILABLE": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">The FTP server was too busy while trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">FTP Server Busy</p>
</div>
<div id="reasonhelp">
<p>
Squid sent the following FTP command:
<pre>%f</pre>
and then received this reply
<pre>%F</pre>
<pre>%g</pre>
</p>
</div>
</div>

""" },
"ERR_INVALID_REQ": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Invalid request.</p>
</div>
<div id="reasonhelp">
<p>
Some aspect of the HTTP Request is invalid.  Possible problems:
<ul>
<li>Missing or unknown request method</li>
<li>Missing URL</li>
<li>Missing HTTP Identifier (HTTP/1.0)</li>
<li>Request is too large</li>
<li>Content-Length missing for POST or PUT requests</li>
<li>Illegal character in hostname; underscores are not allowed</li>
</ul>
</p>
</div>
</div>
""" },
"ERR_INVALID_RESP": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Invalid response.</p>
</div>
<div id="reasonhelp">
<p>
The HTTP Response message received from the contacted server
could not be understood or was otherwise malformed. Please contact
the site operator. Your cache administrator may be able to provide
you with more details about the exact nature of the problem if needed.
</p>
</div>
</div>
""" },
"ERR_INVALID_URL": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Invalid URL</p>
</div>
<div id="reasonhelp">
<p>
Some aspect of the requested URL is incorrect.  Possible problems:
<ul>
<li>Missing or incorrect access protocol (should be `http://'' or similar)</li>
<li>Missing hostname</li>
<li>Illegal double-escape in the URL-Path</li>
<li>Illegal character in hostname; underscores are not allowed</li>
</ul>
</p>
</div>
</div>
""" },
"ERR_LIFETIME_EXP": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Connection Lifetime Expired.</p>
</div>
<div id="reasonhelp">
<p>
Squid has terminated the request because it has exceeded the maximum
connection lifetime.
</p>
</div>
</div>
""" },
"ERR_NO_RELAY": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">No Wais Relay</p>
</div>
<div id="reasonhelp">
<p>
There is no WAIS Relay host defined for this Cache!  Yell at the administrator.
</p>
</div>
</div>
""" },
"ERR_ONLY_IF_CACHED_MISS": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Valid document was not found in the cache and <code>only-if-cached</code>
directive was specified.</p>
</div>
<div id="reasonhelp">
<p>
You have issued a request with a <code>only-if-cached</code> cache control
directive. The document was not found in the cache, <em>or</em> it required
revalidation prohibited by <code>only-if-cached</code> directive.
</p>
</div>
</div>
""" },
"ERR_READ_ERROR": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Read error.</p>
</div>
<div id="reasonhelp">
<p>
An error condition occurred while reading data from the network.  Please
retry your request.
</p>
</div>
</div>
""" },
"ERR_READ_TIMEOUT": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Read timeout.</p>
</div>
<div id="reasonhelp">
<p>
Please retry your request again soon.
</p>
</div>
</div>
""" },
"ERR_SHUTTING_DOWN": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">This cache is in the process of shutting down and can not
service your request at this time.</p>
</div>
<div id="reasonhelp">
<p>Please retry your request again soon.
</p>
</div>
</div>
""" },
"ERR_SOCKET_FAILURE": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Socket failure.</p>
</div>
<div id="reasonhelp">
<p>
The system returned:
<pre>%E</pre>
</p>
<p>
Squid is unable to create a TCP socket, presumably due to excessive load.
Please retry your request.
</p>
</div>
</div>
""" },
"ERR_TOO_BIG": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">The request or reply is too large.</p>
</div>
<div id="reasonhelp">
<p>
If you are making a POST or PUT request, then your request body
(the thing you are trying to upload) is too large.  If you are
making a GET request, then the reply body (what you are trying
to download) is too large.   These limits have been established
by the Internet Service Provider who operates this cache.  Please
contact them directly if you feel this is an error.
</p>
</div>
</div>
""" },
"ERR_UNSUP_REQ": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Unsupported Request Method and Protocol.</p>
</div>
<div id="reasonhelp">
<p>
Squid does not support all request methods for all access protocols.
For example, you can not POST a Gopher request.
</p>
</div>
</div>
""" },
"ERR_URN_RESOLVE": {"result": "ERROR","result_message":"A URL for the requested URN could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Cannot Resolve URN.</p>
</div>
<div id="reasonhelp">
<p>
Hey, don't expect too much from URNs on %T :)
</p>
</div>
</div>
""" },
"ERR_WRITE_ERROR": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
<div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Write Error.</p>
</div>
<div id="reasonhelp">
<p>
An error condition occurred while writing to the network.  Please retry your
request.
</p>
</div>
</div>
""" },
"ERR_ZERO_SIZE_OBJECT": {"result": "ERROR","result_message":"The requested URL could not be retrieved", "body":"""
div id="page">
<p id="while">While trying to retrieve the URL: <a href="%U">%U</a></p>
<div id="error"
<p>The following error was encountered:</p>
<p id="reason">Zero Sized Reply.</p>
</div>
<div id="reasonhelp">
<p>
Squid did not receive any data for this request.
</p>
</div>
</div>
""" }


}


for file in mesg.keys():
	try:
		n = open(os.path.join("/usr/share/squid/errors/English",file), "w")
	except IOError, m:
		print "Errore creating proxy error page: %s" % m
		sys.exit(1)
	n.write(header_start % mesg[file])
	n.write(css)
	n.write(header_end % mesg[file])
	n.write(mesg[file]["body"])
	n.write(footer)
	n.close()
	
