Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build
.vscode
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not fully on board with adding vscode specific ignores. The idea was for this repository to be a template - if an user will use CLion IDE, they don't need this entry, but need other, CLion specific ones.
We could either keep the gitignore as brief as possible and let users extend it as they need, or we could try to pull in as broad gitignore as possible, ignoring stuff from vscode, CLion, clangd, vim, emacs, etc...


cmake/credentials.cmake
cmake/pico_sdk_import.cmake
Expand Down
23 changes: 9 additions & 14 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
set(PROGRAM_NAME pico_w_webserver)

set(MAKE_FS_DATA_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/external/makefsdata)
set(MAKE_FS_DATA_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/makefsdata.py)

find_package(Python3 COMPONENTS Interpreter REQUIRED)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the approach of using CMake to find the interpreter executable.
IMO if we introduce this kind of mechanism we should also introduce error handling for when Python is not found on the system.


if (NOT EXISTS ${MAKE_FS_DATA_SCRIPT})
file(DOWNLOAD
https://raw.githubusercontent.com/krzmaz/lwip/e15654409d14a238aec5ed4bd5516063938c9345/src/apps/http/makefsdata/makefsdata
${MAKE_FS_DATA_SCRIPT}
)
endif()
execute_process(COMMAND
perl ${MAKE_FS_DATA_SCRIPT}
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
execute_process(COMMAND
mv fsdata.c my_fsdata.c
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
)
${Python3_EXECUTABLE} ${MAKE_FS_DATA_SCRIPT}
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
RESULT_VARIABLE FSDATA_RESULT
)

file(RENAME fsdata.c my_fsdata.c)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome, I wasn't aware of RENAME functionality!
This should definitely go in.


add_executable(${PROGRAM_NAME}
main.cpp
Expand Down
105 changes: 105 additions & 0 deletions src/makefsdata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/python3

import os
import binascii

#Create file to write output into
output = open('fsdata.c', 'w')

#Traverse directory, generate list of files
files = list()
os.chdir('./fs')
for(dirpath, dirnames, filenames) in os.walk('.'):
files += [os.path.join(dirpath, file) for file in filenames]

filenames = list()
varnames = list()

#Generate appropriate HTTP headers
for file in files:

if '404' in file:
header = "HTTP/1.0 404 File not found\r\n"
else:
header = "HTTP/1.0 200 OK\r\n"

header += "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n"

if '.html' in file:
header += "Content-type: text/html\r\n"
elif '.shtml' in file:
header += "Content-type: text/html\r\n"
elif '.jpg' in file:
header += "Content-type: image/jpeg\r\n"
elif '.gif' in file:
header += "Content-type: image/gif\r\n"
elif '.png' in file:
header += "Content-type: image/png\r\n"
elif '.class' in file:
header += "Content-type: application/octet-stream\r\n"
elif '.js' in file:
header += "Content-type: text/javascript\r\n"
elif '.css' in file:
header += "Content-type: text/css\r\n"
elif '.svg' in file:
header += "Content-type: image/svg+xml\r\n"
else:
header += "Content-type: text/plain\r\n"

header += "\r\n"

fvar = file[1:] #remove leading dot in filename
fvar = fvar.replace('/', '_') #replace *nix path separator with underscore
fvar = fvar.replace('\\', '_') #replace DOS path separator with underscore
fvar = fvar.replace('.', '_') #replace file extension dot with underscore

output.write("static const unsigned char data{}[] = {{\n".format(fvar))
output.write("\t/* {} */\n\t".format(file))

#first set of hex data encodes the filename
b = bytes(file[1:].replace('\\', '/'), 'utf-8') #change DOS path separator to forward slash
for byte in binascii.hexlify(b, b' ', 1).split():
output.write("0x{}, ".format(byte.decode()))
output.write("0,\n\t")

#second set of hex data is the HTTP header/mime type we generated above
b = bytes(header, 'utf-8')
count = 0
for byte in binascii.hexlify(b, b' ', 1).split():
output.write("0x{}, ".format(byte.decode()))
count = count + 1
if(count == 10):
output.write("\n\t")
count = 0
output.write("\n\t")

#finally, dump raw hex data from files
with open(file, 'rb') as f:
count = 0
while(byte := f.read(1)):
byte = binascii.hexlify(byte)
output.write("0x{}, ".format(byte.decode()))
count = count + 1
if(count == 10):
output.write("\n\t")
count = 0
output.write("};\n\n")

filenames.append(file[1:])
varnames.append(fvar)

for i in range(len(filenames)):
prevfile = "NULL"
if(i > 0):
prevfile = "file" + varnames[i-1]

output.write("const struct fsdata_file file{0}[] = {{{{ {1}, data{2}, ".format(varnames[i], prevfile, varnames[i]))
output.write("data{} + {}, ".format(varnames[i], len(filenames[i]) + 1))
output.write("sizeof(data{}) - {}, ".format(varnames[i], len(filenames[i]) + 1))
output.write("FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT}};\n")

output.write("\n#define FS_ROOT file{}\n".format(varnames[-1]))
output.write("#define FS_NUMFILES {}\n".format(len(filenames)))