ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

112 lines
2.8 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #ifndef CPPCMS_IMPL_REWRITE_H
  9. #define CPPCMS_IMPL_REWRITE_H
  10. #include <cppcms/defs.h>
  11. #include <booster/regex.h>
  12. #include <cppcms/json.h>
  13. #include <cppcms/cppcms_error.h>
  14. #include "string_map.h"
  15. namespace cppcms {
  16. namespace impl {
  17. class url_rewriter {
  18. struct rule {
  19. rule(std::string const &r,std::string const &pat,bool fin=true) :
  20. expression(r),
  21. final(fin)
  22. {
  23. size_t pos = 0;
  24. bool append = false;
  25. for(;;){
  26. size_t start = pos;
  27. pos = pat.find('$',pos);
  28. std::string subpat = pat.substr(start,pos-start);
  29. if(append)
  30. pattern.back().append(subpat);
  31. else
  32. pattern.push_back(subpat);
  33. if(pos==std::string::npos)
  34. break;
  35. pos++;
  36. char c;
  37. if(pos >= pat.size() || ((c=pat[pos++])!='$' && c < '0' && '9' < c))
  38. throw cppcms_error("Invalid rewrite pattern :" + pat);
  39. if(c=='$') {
  40. pattern.back()+='$';
  41. append=true;
  42. }
  43. else {
  44. index.push_back(c-'0');
  45. append=false;
  46. }
  47. }
  48. pattern_size = 0;
  49. for(size_t i=0;i<pattern.size();i++)
  50. pattern_size+=pattern[i].size();
  51. }
  52. booster::regex expression;
  53. std::vector<std::string> pattern;
  54. std::vector<int> index;
  55. size_t pattern_size;
  56. bool final;
  57. char *rewrite_once(booster::cmatch const &m,string_pool &pool) const
  58. {
  59. size_t total_size = pattern_size;
  60. for(size_t i=0;i<index.size();i++) {
  61. total_size += m[index[i]].length();
  62. }
  63. char *new_url = pool.alloc(total_size+1);
  64. char *ptr = new_url;
  65. for(size_t i=0;i<index.size();i++) {
  66. ptr = std::copy(pattern[i].begin(),pattern[i].end(),ptr);
  67. ptr = std::copy(m[index[i]].first,m[index[i]].second,ptr);
  68. }
  69. ptr = std::copy(pattern.back().begin(),pattern.back().end(),ptr);
  70. *ptr = 0;
  71. return new_url;
  72. }
  73. };
  74. public:
  75. url_rewriter(json::array const &ar)
  76. {
  77. rules_.reserve(ar.size());
  78. for(size_t i=0;i<ar.size();i++) {
  79. std::string r = ar[i].get<std::string>("regex");
  80. std::string p = ar[i].get<std::string>("pattern");
  81. bool final = ar[i].get("final",true);
  82. rules_.push_back(rule(r,p,final));
  83. }
  84. }
  85. char *rewrite(char *url,string_pool &pool) const
  86. {
  87. booster::cmatch m;
  88. for(size_t i=0;i<rules_.size();i++) {
  89. rule const &r = rules_[i];
  90. if(booster::regex_match(url,m,r.expression)) {
  91. url = r.rewrite_once(m,pool);
  92. if(r.final)
  93. break;
  94. }
  95. }
  96. return url;
  97. }
  98. private:
  99. std::vector<rule> rules_;
  100. };
  101. } // impl
  102. } // cppcms
  103. #endif