summaryrefslogtreecommitdiffstats
path: root/Lib/http/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/http/server.py')
-rw-r--r--Lib/http/server.py39
1 files changed, 35 insertions, 4 deletions
diff --git a/Lib/http/server.py b/Lib/http/server.py
index 61ddecc..429490b 100644
--- a/Lib/http/server.py
+++ b/Lib/http/server.py
@@ -87,6 +87,9 @@ __all__ = [
"SimpleHTTPRequestHandler", "CGIHTTPRequestHandler",
]
+import argparse
+import copy
+import datetime
import email.utils
import html
import http.client
@@ -101,8 +104,6 @@ import socketserver
import sys
import time
import urllib.parse
-import copy
-import argparse
from http import HTTPStatus
@@ -686,12 +687,42 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
except OSError:
self.send_error(HTTPStatus.NOT_FOUND, "File not found")
return None
+
try:
+ fs = os.fstat(f.fileno())
+ # Use browser cache if possible
+ if ("If-Modified-Since" in self.headers
+ and "If-None-Match" not in self.headers):
+ # compare If-Modified-Since and time of last file modification
+ try:
+ ims = email.utils.parsedate_to_datetime(
+ self.headers["If-Modified-Since"])
+ except (TypeError, IndexError, OverflowError, ValueError):
+ # ignore ill-formed values
+ pass
+ else:
+ if ims.tzinfo is None:
+ # obsolete format with no timezone, cf.
+ # https://tools.ietf.org/html/rfc7231#section-7.1.1.1
+ ims = ims.replace(tzinfo=datetime.timezone.utc)
+ if ims.tzinfo is datetime.timezone.utc:
+ # compare to UTC datetime of last modification
+ last_modif = datetime.datetime.fromtimestamp(
+ fs.st_mtime, datetime.timezone.utc)
+ # remove microseconds, like in If-Modified-Since
+ last_modif = last_modif.replace(microsecond=0)
+
+ if last_modif <= ims:
+ self.send_response(HTTPStatus.NOT_MODIFIED)
+ self.end_headers()
+ f.close()
+ return None
+
self.send_response(HTTPStatus.OK)
self.send_header("Content-type", ctype)
- fs = os.fstat(f.fileno())
self.send_header("Content-Length", str(fs[6]))
- self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
+ self.send_header("Last-Modified",
+ self.date_time_string(fs.st_mtime))
self.end_headers()
return f
except: