) I wou" /> ) I wou" /> ) I wou"/>

Is it possible to have dynamic routes in pion?

132 Views Asked by At

I'd like to use pion 5.0.6 as a small webserver in a VS2017 c++ project. For static routes I can use

add_resource("/my/static/route", <handler>)

I would need dynamic routes as well - like "/data/:id/info How do I do this?

1

There are 1 best solutions below

0
x y On

For those who may need it: I found a solution to add dynamic routing to the pion webserver. It requires smart router code I found at hxoht on github, and works the way that

  • all routes - static and dynamic - are set with httpd->add_resource(<url>, <handler);
  • a 404-handler has to be set with httpd->set_not_found_handler(<handler>); and is responsible for dispatching the dynamic routes to the handlers added above.
  • your webserver class must derive from pion::http::server in order to find the handler by name with httpd->find_request_handler(<url>, <handler>);
  • in your 404-handler, you use the Match::test(<dynamic-route>) method to detect a dynamic route - like in the following code fragment:

    void handle_404(http::request_ptr& req, tcp::connection_ptr& con)
    {
        Route target;
        Match dynamic = target.set(req->get_resource());
        for (auto& route : dynamic_routes) // Our list of dynamic routes
        {
            if (dynamic.test(route)) // Does the url match the dynamic route pattern?
            {
                request_handler_t h;
                if (find_request_handler(route, h))
                {
                    auto name = get_param_name(route); // e.g. /a/:b -> "b"
                    value = dynamic.get(name); // Save value in string or map<name, value>
                    h(req, con); // Call original handler with value set properly
                    return;
                }
            }
        }
        // If no match then return a 404.
        http::response_writer_ptr w(http::response_writer::create(con, *req,
        boost::bind(&tcp::connection::finish, con)));
        http::response& res = w->get_response();
        res.set_status_code(http::types::RESPONSE_CODE_NOT_FOUND);
        res.set_status_message(http::types::RESPONSE_MESSAGE_NOT_FOUND);
        w->send();
    }
    

For using the pion webserver in a multi-threaded way, I would store the parsed value inside the request object, which would be derived from pion::http::request.

This would work for Windows and Linux :)