im trying to decode user input from a website into a plaintext file on a rpi pico w running micropython. I'm running into issues with certain characters being decoded, specifically spaces
the code is running HTML for someone to input a wifi username and password and then returns it to the pico to connect to the internet
# Manual URL-decoding function
def url_decode(URL):
"""Manually decode a URL-encoded string."""
counter = 0
while '%' in url and counter < 100: # A check to break out of the loop after 100 iterations
index = url.index('%')
# Extract hex code after '%'
hex_code = url[index + 1:index + 3]
# Handle special cases (e.g., "%20" is a space, "%2B" is a plus)
if hex_code == '20': # "%20" represents a space
char = ' '
elif hex_code == '2B': # "%2B" represents the plus sign (+)
char = '+'
else:
try:
# Decode other URL-encoded characters
char = chr(int(hex_code, 16))
except ValueError:
char = '%' # In case of invalid encoding, retain '%'
# Replace the encoded part with the decoded character
url = url[:index] + char + url[index + 3:]
counter += 1
return url
currently if you enter details such as Hello+ -, 123. you get Hello++-,+123.
I need to keep all characters accurate as it will be used to connect to a wifi router so special characters and spaces are important.
there is also an issue where there is a ' at the end of the password which is entered second. i can always have it just delete the last character, but would like it to just not be there to begin with
if it helps here is the other function that handles parsing and saving the data
def parse_post_data(request):
"""Parse POST data and return ssid and password."""
try:
# Extract 'ssid' and 'password' from POST request (no URL encoding here)
match_ssid = request.split('ssid=')[1].split('&')[0] # Get the SSID
match_password = request.split('password=')[1].split('&')[0] # Get the password
# Manually decode the URL-encoded data
ssid = url_decode(match_ssid).strip() # Decode URL and strip spaces
password = url_decode(match_password).strip() # Decode URL and strip spaces
print(f"Decoded SSID: {ssid}")
print(f"Decoded Password: {password}")
return ssid, password
except Exception as e:
print(f"Error parsing POST data: {e}")
return None, None
def save_wifi_config(ssid, password):
"""Save the Wi-Fi configuration to a file."""
try:
# Save to the file directly as plain text (no encoding)
with open('wifi_config.txt', 'w') as f:
f.write(f"{ssid}\n{password}\n")
print(f"Wi-Fi credentials saved to wifi_config.txt")
except Exception as e:
print(f"Error saving Wi-Fi credentials: {e}")
HTML section that creates form for user to enter info
html_form = '''<!DOCTYPE HTML>
<HTML>
<head>
<title>Enter WiFi Credentials</title>
</head>
<body>
<h2>Enter your WiFi details</h2>
<form action="/submit" method="POST">
SSID: <input type="text" name="ssid" /><be>
Password: <input type="text" name="password" /><be>
<input type="submit" value="Submit" />
</form>
</body>
</html>'''
html_failure_form = '''<!DOCTYPE HTML>
<HTML>
<head>
<title>WiFi Connection Failed</title>
</head>
<body>
<h2>Failed to connect to the WiFi network.</h2>
<p>Please check your SSID and Password and try again.</p>
<form action="/retry" method="POST">
SSID: <input type="text" name="ssid" /><be>
Password: <input type="text" name="password" /><be>
<input type="submit" value="Retry" />
</form>
</body>
</html>'''
initializing the AP
# Initialize the access point
ap = network.WLAN(network.AP_IF)
ap.config(essid='Pico_WiFi_Config', password='12345678') # Set a
default SSID and password for the AP
ap.active(True)
Hello+ -, 123gets entered by the user?+you put into your form gets encoded as%2B, and the space character as+. You reverted only the first, but you leave the second one as is. You still need to replace+with a space character, in addition to the processing of the%XYparts you are already doing.