From de8da9aecc61bdaba2b21f13d4552e8a30465a4d Mon Sep 17 00:00:00 2001
From: Kira-sempai <kira-sempai@narod.ru>
Date: Thu, 27 Jul 2017 14:50:57 +0300
Subject: [PATCH 2/2] apps/httpd: add ETag header support

---
 src/apps/httpd/httpd.c         | 20 ++++++++++++++++++--
 src/apps/httpd/httpd_structs.h | 12 ++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/apps/httpd/httpd.c b/src/apps/httpd/httpd.c
index f8d2233f..4f3ef304 100644
--- a/src/apps/httpd/httpd.c
+++ b/src/apps/httpd/httpd.c
@@ -182,12 +182,14 @@ static char http_uri_buf[LWIP_HTTPD_URI_BUF_LEN+1];
 /* The number of individual strings that comprise the headers sent before each
  * requested file.
  */
-#define NUM_FILE_HDR_STRINGS 5
+#define NUM_FILE_HDR_STRINGS 7
 #define HDR_STRINGS_IDX_HTTP_STATUS          0 /* e.g. "HTTP/1.0 200 OK\r\n" */
 #define HDR_STRINGS_IDX_SERVER_NAME          1 /* e.g. "Server: "HTTPD_SERVER_AGENT"\r\n" */
 #define HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE 2 /* e.g. "Content-Length: xy\r\n" and/or "Connection: keep-alive\r\n" */
 #define HDR_STRINGS_IDX_CONTENT_LEN_NR       3 /* the byte count, when content-length is used */
-#define HDR_STRINGS_IDX_CONTENT_TYPE         4 /* the content type (or default answer content type including default document) */
+#define HDR_STRINGS_IDX_ETAG                 4 /* e.g. "ETag: "2073041041"" */
+#define HDR_STRINGS_IDX_CACHE_CONTROL_MAX_AGE 5 /* e.g. "Cache-Control: max-age=31536000\r\nExpires: Tue, 01 Jan 2030 00:00:00 GMT\r\n" */
+#define HDR_STRINGS_IDX_CONTENT_TYPE         6 /* the content type (or default answer content type including default document) */
 
 /* The dynamically generated Content-Length buffer needs space for CRLF + NULL */
 #define LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET 3
@@ -869,6 +871,12 @@ get_http_headers(struct http_state *hs, const char *uri)
     hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_BAD_REQUEST];
   } else if (strstr(uri, "501")) {
     hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_IMPL];
+  } else if (strstr(uri, "304")) {
+    hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_MODIFIED];
+    hs->hdrs[HDR_STRINGS_IDX_CACHE_CONTROL_MAX_AGE] = g_psHTTPHeaderStrings[CACHE_CONTROL_MAX_AGE];
+    hs->hdr_index = 0;
+    hs->hdr_pos = 0;
+    return;
   } else {
     hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_OK];
   }
@@ -905,6 +913,14 @@ get_http_headers(struct http_state *hs, const char *uri)
     *vars = '?';
   }
 
+  if (hs->handle && hs->handle->is_custom_file){
+    char * const eTagHeader = getETagHeader(hs->handle->pextension);
+    if (eTagHeader != NULL) {
+      hs->hdrs[HDR_STRINGS_IDX_ETAG] = eTagHeader;
+      hs->hdrs[HDR_STRINGS_IDX_CACHE_CONTROL_MAX_AGE] = g_psHTTPHeaderStrings[CACHE_CONTROL_MAX_AGE];
+    }
+  }
+
 #if LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI
   /* Does the URL passed have any file extension?  If not, we assume it
      is a special-case URL used for control state notification and we do
diff --git a/src/apps/httpd/httpd_structs.h b/src/apps/httpd/httpd_structs.h
index 4b829072..3a41818e 100644
--- a/src/apps/httpd/httpd_structs.h
+++ b/src/apps/httpd/httpd_structs.h
@@ -33,6 +33,9 @@ static const char * const g_psHTTPHeaderStrings[] =
 #if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
  ,"Connection: keep-alive\r\nContent-Length: 77\r\n\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
 #endif
+ ,"Cache-Control: max-age=31536000\r\nExpires: Tue, 01 Jan 2030 00:00:00 GMT\r\n",
+ "HTTP/1.0 304 Not Modified\r\n",
+ "HTTP/1.0 302 Found\r\n",
 };
 
 /* Indexes into the g_psHTTPHeaderStrings array */
@@ -53,6 +56,15 @@ static const char * const g_psHTTPHeaderStrings[] =
 #if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
 #define DEFAULT_404_HTML_PERSISTENT 14 /* default 404 body, but including Connection: keep-alive */
 #endif
+#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
+#define CACHE_CONTROL_MAX_AGE   15 /* file expires in 1 year */
+#define HTTP_HDR_NOT_MODIFIED   16 /* file not modified */
+#define HTTP_HDR_FOUND			17 /* file not modified */
+#else
+#define CACHE_CONTROL_MAX_AGE   14 /* file expires in 1 year */
+#define HTTP_HDR_NOT_MODIFIED   15 /* file not modified */
+#define HTTP_HDR_FOUND          16 /* file not modified */
+#endif
 
 #define HTTP_CONTENT_TYPE(contenttype) "Content-Type: "contenttype"\r\n\r\n"
 #define HTTP_CONTENT_TYPE_ENCODING(contenttype, encoding) "Content-Type: "contenttype"\r\nContent-Encoding: "encoding"\r\n\r\n"
-- 
2.12.2.windows.2

