diff --git a/docs/guides/routes.md b/docs/guides/routes.md index 18c26d011..c4ef4683c 100644 --- a/docs/guides/routes.md +++ b/docs/guides/routes.md @@ -20,6 +20,19 @@ CROW_ROUTE(app, "/add//") ``` you can see the first `` is defined as `a` and the second as `b`. If you were to run this and call `http://example.com/add/1/2`, the result would be a page with `3`. Exciting! +Another example is to ask for the first part in a string, and the remainder in a path. +Note that strings are in URL-encoding (aka Percent-encoding, eg `"image%20file.png"`). +To decode into UTF-8, use `crow::decode_url(...)` to in-place decode the string. +```cpp +CROW_ROUTE(app, "/combine//") +([](std::string first, std::string remainder) +{ + // first can remain percent-encoded: perhaps we know for certain that it will always be simple text + crow::decode_url(remainder); + return first + " --> " + remainder; +}); +``` + ## Methods You can change the HTTP methods the route uses from just the default `GET` by using `method()`, your route macro should look like `CROW_ROUTE(app, "/add//").methods(crow::HTTPMethod::GET, crow::HTTPMethod::PATCH)` or `CROW_ROUTE(app, "/add//").methods("GET"_method, "PATCH"_method)`. diff --git a/include/crow/http_request.h b/include/crow/http_request.h index bd65c0710..2c5c03895 100644 --- a/include/crow/http_request.h +++ b/include/crow/http_request.h @@ -31,6 +31,22 @@ namespace crow // NOTE: Already documented in "crow/app.h" return empty; } + /// URLs given to routes are in URL-encoding (aka Percent-encoding) + /// eg "image file.png" --> "image%20file.png" + /// This operates on the string in-place and decodes a percent-encoded string to UTF-8 + /// The resulting string will always be shorter than the original, so this function + /// will set a new null terminator at the end of the string. + inline int url_decode( char* url ) + { + return qs_decode(url); + } + + /// This will decode the url in-place, resizing the string to the new shorter size. + inline void url_decode( std::string& url ) + { + url.resize( url_decode(&url[0]) ); + } + /// An HTTP request. struct request { diff --git a/tests/unittest.cpp b/tests/unittest.cpp index 5437275cd..1dc45dde6 100644 --- a/tests/unittest.cpp +++ b/tests/unittest.cpp @@ -4116,3 +4116,10 @@ TEST_CASE("option_header_passed_in_full") CHECK(res.find(ServerName) != std::string::npos); app.stop(); } + +TEST_CASE("url_decoding") +{ + std::string url = "image%20file.png"; + crow::url_decode(url); + CHECK(url == "image file.png"); +} \ No newline at end of file