router.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "router.h"
  2. #include "handler.h"
  3. #include "hthread.h" // import hv_gettid
  4. #include "hasync.h" // import hv::async
  5. #include "requests.h" // import requests::async
  6. void Router::Register(hv::HttpService& router) {
  7. /* handler chain */
  8. // headerHandler -> preprocessor -> middleware -> processor -> postprocessor
  9. // processor: pathHandlers -> staticHandler -> errorHandler
  10. router.headerHandler = Handler::headerHandler;
  11. router.preprocessor = Handler::preprocessor;
  12. router.postprocessor = Handler::postprocessor;
  13. // router.errorHandler = Handler::errorHandler;
  14. // router.largeFileHandler = Handler::sendLargeFile;
  15. // middleware
  16. // router.Use(Handler::Authorization);
  17. // curl -v http://ip:port/ping
  18. router.GET("/ping", [](HttpRequest* req, HttpResponse* resp) {
  19. return resp->String("pong");
  20. });
  21. // curl -v http://ip:port/data
  22. router.GET("/data", [](HttpRequest* req, HttpResponse* resp) {
  23. static char data[] = "0123456789";
  24. return resp->Data(data, 10 /*, false */);
  25. });
  26. // curl -v http://ip:port/html/index.html
  27. router.GET("/html/index.html", [](HttpRequest* req, HttpResponse* resp) {
  28. return resp->File("html/index.html");
  29. });
  30. // curl -v http://ip:port/paths
  31. router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) {
  32. return resp->Json(router.Paths());
  33. });
  34. // curl -v http://ip:port/service
  35. router.GET("/service", [](const HttpContextPtr& ctx) {
  36. ctx->setContentType("application/json");
  37. ctx->set("base_url", ctx->service->base_url);
  38. ctx->set("document_root", ctx->service->document_root);
  39. ctx->set("home_page", ctx->service->home_page);
  40. ctx->set("error_page", ctx->service->error_page);
  41. ctx->set("index_of", ctx->service->index_of);
  42. return 200;
  43. });
  44. // curl -v http://ip:port/get?env=1
  45. router.GET("/get", [](const HttpContextPtr& ctx) {
  46. hv::Json resp;
  47. resp["origin"] = ctx->ip();
  48. resp["url"] = ctx->url();
  49. resp["args"] = ctx->params();
  50. resp["headers"] = ctx->headers();
  51. return ctx->send(resp.dump(2));
  52. });
  53. // curl -v http://ip:port/echo -d "hello,world!"
  54. router.POST("/echo", [](const HttpContextPtr& ctx) {
  55. return ctx->send(ctx->body(), ctx->type());
  56. });
  57. // wildcard *
  58. // curl -v http://ip:port/wildcard/any
  59. router.GET("/wildcard*", [](HttpRequest* req, HttpResponse* resp) {
  60. std::string str = req->path + " match /wildcard*";
  61. return resp->String(str);
  62. });
  63. // curl -v http://ip:port/async
  64. router.GET("/async", [](const HttpRequestPtr& req, const HttpResponseWriterPtr& writer) {
  65. writer->Begin();
  66. writer->WriteHeader("X-Response-tid", hv_gettid());
  67. writer->WriteHeader("Content-Type", "text/plain");
  68. writer->WriteBody("This is an async response.\n");
  69. writer->End();
  70. });
  71. // curl -v http://ip:port/www.*
  72. // curl -v http://ip:port/www.example.com
  73. router.GET("/www.*", [](const HttpRequestPtr& req, const HttpResponseWriterPtr& writer) {
  74. auto req2 = std::make_shared<HttpRequest>();
  75. req2->url = req->path.substr(1);
  76. requests::async(req2, [writer](const HttpResponsePtr& resp2){
  77. writer->Begin();
  78. if (resp2 == NULL) {
  79. writer->WriteStatus(HTTP_STATUS_NOT_FOUND);
  80. writer->WriteHeader("Content-Type", "text/html");
  81. writer->WriteBody("<center><h1>404 Not Found</h1></center>");
  82. } else {
  83. writer->WriteResponse(resp2.get());
  84. }
  85. writer->End();
  86. });
  87. });
  88. // curl -v http://ip:port/sleep?t=1000
  89. router.GET("/sleep", Handler::sleep);
  90. // curl -v http://ip:port/setTimeout?t=1000
  91. router.GET("/setTimeout", Handler::setTimeout);
  92. // curl -v http://ip:port/query?page_no=1\&page_size=10
  93. router.GET("/query", Handler::query);
  94. // Content-Type: application/x-www-form-urlencoded
  95. // curl -v http://ip:port/kv -H "content-type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456'
  96. router.POST("/kv", Handler::kv);
  97. // Content-Type: application/json
  98. // curl -v http://ip:port/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}'
  99. router.POST("/json", Handler::json);
  100. // Content-Type: multipart/form-data
  101. // bin/curl -v http://ip:port/form -F 'user=admin' -F 'pswd=123456'
  102. router.POST("/form", Handler::form);
  103. // curl -v http://ip:port/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello'
  104. // curl -v http://ip:port/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}'
  105. // bin/curl -v http://ip:port/test -F 'bool=1' -F 'int=123' -F 'float=3.14' -F 'string=hello'
  106. router.POST("/test", Handler::test);
  107. // Content-Type: application/grpc
  108. // bin/curl -v --http2 http://ip:port/grpc -H "content-type:application/grpc" -d 'protobuf'
  109. router.POST("/grpc", Handler::grpc);
  110. // RESTful API: /group/:group_name/user/:user_id
  111. // curl -v -X DELETE http://ip:port/group/test/user/123
  112. router.Delete("/group/:group_name/user/:user_id", Handler::restful);
  113. // router.Delete("/group/{group_name}/user/{user_id}", Handler::restful);
  114. // curl -v http://ip:port/login -H "Content-Type:application/json" -d '{"username":"admin","password":"123456"}'
  115. router.POST("/login", Handler::login);
  116. // curl -v http://ip:port/upload?filename=LICENSE -d '@LICENSE'
  117. // curl -v http://ip:port/upload -F 'file=@LICENSE'
  118. router.POST("/upload", Handler::upload);
  119. // curl -v http://ip:port/upload/README.md -d '@README.md'
  120. router.POST("/upload/{filename}", Handler::recvLargeFile);
  121. // SSE: Server Send Events
  122. // @test html/EventSource.html EventSource.onmessage
  123. router.GET("/sse", Handler::sse);
  124. }