Allow response to be specified in makefsdata script (#3000)

* Allow response to be changed in makefsdata script

Currently the response contents are hardcoded.
This prevents using the makefsdata script to implement a captive
portal where we have to send a redirect when a 404 result would be
returned.

When loading file contents, look for a file with the same name with
a "response" extension and use its contents for the response.

We can then use this for the access point example which can then be
simplified.

Fixes #2646

* Change .hdr file to .response

Only return on zero contents if a .response file is found.

* Apply suggestion from @lurch

Co-authored-by: Andrew Scheller <lurch@durge.org>

---------

Co-authored-by: Andrew Scheller <lurch@durge.org>
diff --git a/src/rp2_common/pico_lwip/tools/makefsdata.py b/src/rp2_common/pico_lwip/tools/makefsdata.py
index e50c898..f23e54c 100755
--- a/src/rp2_common/pico_lwip/tools/makefsdata.py
+++ b/src/rp2_common/pico_lwip/tools/makefsdata.py
@@ -18,6 +18,10 @@
 def process_file(input_dir, file):
     results = []
 
+    # Ignore response files
+    if file.suffix == ".response":
+        return None
+
     # Check content type
     content_type, content_encoding = mimetypes.guess_type(file)
     if content_type is None:
@@ -31,16 +35,27 @@
         data += "\x00"
     results.append({'data': bytes(data, "utf-8"), 'comment': comment});
 
-    # Header
-    response_type = 200
-    for response_id in response_types:
-        if file.name.startswith(f"{response_id}."):
-            response_type = response_id
-            break
-    data = f"{response_types[response_type]}\r\n"
-    comment = f"\"{response_types[response_type]}\" ({len(data)} chars)"
+    # If we find a file with the same name and a "response" extension - use its contents for the response
+    response_file = file.with_suffix('.response')
+    if response_file.is_file():
+        data = response_file.read_text()
+        comment = f"content from {response_file.name} ({len(data)} chars)"
+    else:
+        # response result
+        response_type = 200
+        for response_id in response_types:
+            if file.name.startswith(f"{response_id}."):
+                response_type = response_id
+                break
+        data = f"{response_types[response_type]}\r\n"
+        comment = f"\"{response_types[response_type]}\" ({len(data)} chars)"
     results.append({'data': bytes(data, "utf-8"), 'comment': comment});
 
+    # load file contents
+    file_contents = file.read_bytes()
+    if len(file_contents) == 0 and response_file.is_file():
+        return results
+
     # user agent
     data = f"Server: {HTTPD_SERVER_AGENT}\r\n"
     comment = f"\"Server: {HTTPD_SERVER_AGENT}\" ({len(data)} chars)"
@@ -64,10 +79,9 @@
         comment = f"\"{content_type_header} {content_encoding_header}\" ({len(data)} chars)"
     results.append({'data': bytes(data, "utf-8"), 'comment': comment});
 
-    # file contents
-    data = file.read_bytes()
-    comment = f"raw file data ({len(data)} bytes)"
-    results.append({'data': data, 'comment': comment});
+    # add file contents
+    comment = f"raw file data ({len(file_contents)} bytes)"
+    results.append({'data': file_contents, 'comment': comment});
 
     return results;
 
@@ -85,6 +99,8 @@
         if input_dir is None:
             input_dir = file.parent
         results = process_file(input_dir, file)
+        if not results:
+            continue
 
         # make a variable name
         var_name = str(file.relative_to(input_dir))