<!--toc--> |
|
## Introduction |
|
Now we would learn how to connect between different URLs and the application functions easily. |
|
When client requests specific URL from the HTTP server |
it divides it into several parts: `SCRIPT_NAME`, `PATH_INFO` and `QUERY_STRING`. For example |
URL `/foo/bar.php/test?x=10` is separated into: |
|
- `SCRIPT_NAME` = `/foo/bar.php` |
- `PATH_INFO` = `/test` |
- `QUERY_STRING` = `x=10` |
|
Today web applications are not distributed into several |
scripts but rather written using a single FastCGI application that runs on specific url like "/myapp", So |
generally URLs would look like `/myapp/page/10`, when |
`SCRIPT_NAME` = "/myapp" remains constant and `PATH_INFO` = `/page/10` is changed according to user's needs. |
|
So the mapping between URL and applications member functions |
are done by matching a regular expression against `PATH_INFO` part of URL, even thou this behavior can be changed by using `mount_point` class. |
|
## Example |
|
Lets rewrite our [hello class](/wikipp/en/page/cppcms_1x_tut_hello): |
|
First let's write our constructor: |
Since we will be routing URLs, let's include the `url_dispatcher.h` header file. Your include list should look like: |
|
#include <cppcms/application.h> |
#include <cppcms/applications_pool.h> |
#include <cppcms/service.h> |
#include <cppcms/http_response.h> |
#include <cppcms/url_dispatcher.h> |
#include <iostream> |
|
Now in our constructor, let's map some URLs to member functions: |
|
hello(cppcms::service &srv) : |
cppcms::application(srv) |
{ |
dispatcher().assign("/number/(\\d+)",&hello::number,this,1); |
dispatcher().assign("/smile",&hello::smile,this); |
dispatcher().assign("",&hello::welcome,this); |
dispatcher().assign("/number/(\\d+)", &hello::number, this, 1); |
dispatcher().assign("/smile", &hello::smile, this); |
dispatcher().assign("", &hello::welcome, this); |
} |
|
In the fourth line we connect the regular expression `/number/(\d+)` to the member function `number` of `this` |
instance that receives `std::string` as parameter, |
and 1st captured subexpression is passed to it. |
|
In this case the subexpression is nonempty string that contains digits. |
|
In next two lines we connect member functions `smile` and `welcome` to the appropriate URLs. |
|
So when the script name the HTTP server matches against is |
`/hello` then for URLs |
|
- `/hello` - `welcome` function would be called |
- `/hello/smile` - `smile` function would be called |
- `/hello/number/10` - `number` function would be called and receive a string "10" as parameter. |
|
Now lets complete rest of parts of the code: |
We want our parent application class to handle dispatching the requests now that we have informed the dispatcher how to route them; however, we still need to define those member functions. |
|
Replace the old `main` member function: |
|
virtual void main(std::string url); |
|
. . . with the following (action) member functions: |
|
void number(std::string num) |
{ |
int no = atoi(num.c_str()); |
response().out() << "The number is " << no << "\n"; |
} |
void smile() |
{ |
response().out() << ":-)"; |
} |
void welcome() |
{ |
response().out() << |
"<h1> Wellcome To Page with links </h1>\n" |
"<a href=\"/hello/number/1\">1</a><br>\n" |
"<a href=\"/hello/number/15\">15</a><br>\n" |
"<a href=\"/hello/smile\">:-)</a><br>\n"; |
} |
|
Start an application: |
Don't forget to recompile it: |
|
c++ hello.cpp -lcppcms -o hello |
|
And now for the exciting part, start your application: |
|
./hello -c config.js |
|
And hit the URL: <http://localhost:8080/hello> |