'python and BaseHTTPRequestHandler : add an empty favicon in the header of the generated page
On python 3.8, I created a minimalist python server for my students with BaseHTTPRequestHandler and HTTPServer from the module http.server
When I go to the url on the server, I see in the browser debug tool two http request :
- one for the page
- one for the favicon (the current head html page does not contains a link tag for a favicon, the current head is empty)
I want to prevent the second request (for favicon). My question is : with the classes "BaseHTTPRequestHandler" and "HTTPServer" is it possible to custom the header of the generated page ? I am looking for a way to add an empty favicon like this : <link rel="icon" href="data:;base64,=">
(https://stackoverflow.com/a/13416784/2137454)
Solution 1:[1]
from http.server import SimpleHTTPRequestHandler
class CustomHttpRequestHandler(SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/favicon.ico':
self.send_response(200)
self.send_header('Content-Type', 'image/x-icon')
self.send_header('Content-Length', 0)
self.end_headers()
return
return super().do_GET()
This will suppress the console error as Chrome thinks it has received a favicon -- even though it is a 0-byte response with a correct content type and response code.
Solution 2:[2]
It is clearly possible. After all, you are in complete control of what your server sends to the client. However, I think you should not do this. Just serve that annoying little file favicon.ico. It is the easiest way:
import socketserver
from http.server import SimpleHTTPRequestHandler
class CustomHttpRequestHandler(SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
# here do whatever your custom server would normally do
self.path = 'static/index.html'
if self.path == '/favicon.ico':
self.path = 'static/favicon.ico'
return SimpleHTTPRequestHandler.do_GET(self)
if __name__ == '__main__':
PORT = 8001
my_server = socketserver.TCPServer(("", PORT), CustomHttpRequestHandler)
my_server.serve_forever()
To make this work, all you need to do is to place a png file in folder static
and name it favicon.ico
.
Of course, you could also modify the html content you are sending. As there is no code in your question, I hacked a little mock together:
import socketserver
from http.server import SimpleHTTPRequestHandler
import io
favicon = '<link rel="icon" href="data:;base64,=">\n'
class CustomHttpRequestHandler(SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
self.path = 'index.html'
f = self.send_head() # f is the file to send or None
# following code will break easily. don't do this...
content = ""
for line in f:
line = line.decode("utf8")
# 'parsing' html like this is really a bad idea. don't do it...
if "</head>" in line:
content += favicon
content += line
f2 = io.BytesIO(content.encode("utf-8"))
self.copyfile(f2, self.wfile)
if __name__ == '__main__':
PORT = 8001
my_server = socketserver.TCPServer(("", PORT), CustomHttpRequestHandler)
my_server.serve_forever()
Here I am assuming, you are serving a static file from the current directory. Before sending it to the client the <link rel="icon">
tag is appended right before the closing <head>
tag. This will break easily, of course.
But if you are indeed generating the html instead of serving a static file, placement of the line content += favicon
in your code might be simple and save.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | MrValdez |
Solution 2 | Lydia van Dyke |