Skip to content

Commit

Permalink
Merge pull request #8 from troublegum/dev
Browse files Browse the repository at this point in the history
Release 1.4
  • Loading branch information
troublegum authored Nov 13, 2021
2 parents 522797c + 7aeebd9 commit ac72bf2
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 1 deletion.
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,30 @@ server.add_route("/404", not_found)
server.start()
```

### Parse HTTP request. Get query params from request.
Type in browser http://IP_ADDRESS_ESP/?param_one=one&param_two=two

```
''' Example of HTTP request: GET /?param_one=one&param_two=two HTTP/1.1\r\nHost: localhost\r\n\r\n '''
from micropyserver import MicroPyServer
import utils
''' there should be a wi-fi connection code here '''
def show_params(request):
''' request handler '''
params = utils.get_request_query_params(request)
print(params)
''' will return {"param_one": "one", "param_two": "two"} '''
server = MicroPyServer()
''' add route '''
server.add_route("/", show_params)
''' start server '''
server.start()
```


## MicroPyServer methods

Expand All @@ -220,8 +244,19 @@ Set handler on 404 - server.on_not_found(handler)

Set handler on server error - server.on_error(handler)


## Utils methods

Send response to client - utils.send_response(server, response, http_code=200, content_type="text/html", extend_headers=None)

Get HTTP request method - utils.get_request_method(request)
Get HTTP request method (example of return value: POST) - utils.get_request_method(request)

Return http request query string (example of return value: param_one=one&param_two=two) - utils.get_request_query_string(request)

Return params from query string (example of return value: {"param_one": "one", "param_two": "two"}) - utils.parse_query_string(query_string)

Return http request query params (example of return value: {"param_one": "one", "param_two": "two"}) - utils.get_request_query_params(request)

Return params from POST request (example of return value: {"param_one": "one", "param_two": "two"}) - utils.get_request_post_params(request)

Unquote string - unquote(string)
48 changes: 48 additions & 0 deletions test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import unittest
import utils


class TestUtils(unittest.TestCase):
def test_get_request_method_should_return_get(self):
request = "GET / HTTP/1.1\r\nHost: localhost"
self.assertEqual(utils.get_request_method(request), "GET", "Should be GET")

def test_get_request_method_should_return_post(self):
request = "POST /post HTTP/1.1\r\nHost: localhost\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 0\r\n\r\n"
self.assertEqual(utils.get_request_method(request), "POST", "Should be POST")

def test_get_request_query_string_method_should_return_string(self):
request = "GET /?param_one=one&param_two=two HTTP/1.1\r\nHost: localhost\r\n\r\n"
self.assertEqual(utils.get_request_query_string(request), "param_one=one&param_two=two",
"Should be 'param_one=one&param_two=two'")

def test_parse_query_string_method_should_return_two_params(self):
query_string = "param_one=one&param_two=two"
self.assertEqual(utils.parse_query_string(query_string), {"param_one": "one", "param_two": "two"},
"Should be result with two params")

def test_get_request_query_params_method_should_return_two_params(self):
request = "GET /?param_one=one&param_two=two HTTP/1.1\r\nHost: localhost\r\n\r\n"
self.assertEqual(utils.get_request_query_params(request), {"param_one": "one", "param_two": "two"},
"Should be 'param_one=one&param_two=two'")

def test_get_request_post_params_method_should_return_two_params(self):
request = "POST /post HTTP/1.1\r\nHost: localhost\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 27\r\n\r\nparam_one=one&param_two=two"
self.assertEqual(utils.get_request_post_params(request), {"param_one": "one", "param_two": "two"},
"Should be 'param_one=one&param_two=two'")

def test_unquote_method_should_return_empty_string(self):
self.assertEqual(utils.unquote(""), "", "Should be empty string")

def test_unquote_method_should_return_string(self):
self.assertEqual(utils.unquote("param"), "param", "Should be 'param'")

def test_unquote_method_should_return_unquoted_string(self):
self.assertEqual(utils.unquote(
"%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%20%D0%B8%20%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%25"),
"параметр и значение %",
"Should be 'параметр и значение %'")


if __name__ == "__main__":
unittest.main()
72 changes: 72 additions & 0 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,75 @@ def get_request_method(request):
""" return http request method """
lines = request.split("\r\n")
return re.search("^([A-Z]+)", lines[0]).group(1)


def get_request_query_string(request):
""" return http request query string """
lines = request.split("\r\n")
match = re.search("\\?(.+)\\s", lines[0])
if match is None:
return ""
else:
return match.group(1)


def parse_query_string(query_string):
""" return params from query string """
if len(query_string) == 0:
return {}
query_params_string = query_string.split("&")
query_params = {}
for param_string in query_params_string:
param = param_string.split("=")
key = param[0]
if len(param) == 1:
value = ""
else:
value = param[1]
query_params[key] = value
return query_params


def get_request_query_params(request):
""" return http request query params """
query_string = get_request_query_string(request)
return parse_query_string(query_string)


def get_request_post_params(request):
""" return params from POST request """
request_method = get_request_method(request)
if request_method != "POST":
return None
match = re.search("\r\n\r\n(.+)", request)
if match is None:
return {}
query_string = match.group(1)
return parse_query_string(query_string)


def unquote(string):
""" unquote string """
if not string:
return ""

if isinstance(string, str):
string = string.encode("utf-8")

bits = string.split(b"%")
if len(bits) == 1:
return string.decode("utf-8")

res = bytearray(bits[0])
append = res.append
extend = res.extend

for item in bits[1:]:
try:
append(int(item[:2], 16))
extend(item[2:])
except KeyError:
append(b"%")
extend(item)

return bytes(res).decode("utf-8")

0 comments on commit ac72bf2

Please sign in to comment.