Check-in [67e91438e6]

Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1 Hash:67e91438e664cd39afc8ed818f62a62dc68039f7
Date: 2008-09-18 14:56:40
User: stephan
Comment:added unescaping of %XX sequences in GET parameter values
Tags And Properties
Changes
hide diffs unified diffs patch

Changes to parsepp_url.hpp

Old (541b0345e82133a7) New (68112ef8f8acc8d9)
1 #ifndef S11N_NET_PARSEPP_URL_H_INCLUDED 1 #ifndef S11N_NET_PARSEPP_URL_H_INCLUDED
2 #define S11N_NET_PARSEPP_URL_H_INCLUDED 1 2 #define S11N_NET_PARSEPP_URL_H_INCLUDED 1
3 3
4 #include "parsepp.hpp" 4 #include "parsepp.hpp"
5 #include <map> 5 #include <map>
6 #include <string> 6 #include <string>
> 7 #include <sstream>
7 8
8 namespace Ps { 9 namespace Ps {
9 10
10 /** 11 /**
11 Ps::url encapsulates a parser for URLs. It does no escaping at all - that is | 12 Ps::url encapsulates a parser for URLs. It unescaped %XX sequences in the
12 up to client code. | 13 value parts of URL parameter values, but does no other unescaping.
| 14
| 15 For historical reasons, file:// URLs are handled a bit less strictly
| 16 than other URL schemes. The following are valid for this parser:
| 17
| 18 file:relative/path
| 19
| 20 file://relative/path
| 21
| 22 file:/absolute/path
| 23
| 24 file:///absolute/path
| 25
| 26
| 27 Aside from that, it handles normal URLs:
| 28
| 29 protocol://[user[:[password]]@]hostname/path?KVP
| 30
| 31 Where KVP are key/value pairs in the form KEY[=[VALUE]], separated
| 32 by a '&' character. The VALUE part of each pair gets unescaped,
| 33 such that %XX (where XX is a hexidecimal value of a character) get
| 34 transformed into their ASCII value (note that results are undefined
| 35 here with characters >127).
| 36
13 */ 37 */
14 namespace url { 38 namespace url {
15 using namespace Ps; 39 using namespace Ps;
16 #define RL rule_list 40 #define RL rule_list
17 #define CL char_list 41 #define CL char_list
3 hidden lines
21 struct url_state 45 struct url_state
22 { 46 {
23 typedef std::map<std::string,std::string> kvpmap; 47 typedef std::map<std::string,std::string> kvpmap;
24 kvpmap params; // key/value pairs for GET params 48 kvpmap params; // key/value pairs for GET params
25 kvpmap parts; // key/value pairs for various parts of URL 49 kvpmap parts; // key/value pairs for various parts of URL
26 std::string key; // last-read key. | 50 std::string key; // buffer for the last-read key.
27 void clear() 51 void clear()
28 { 52 {
29 this->params.clear(); 53 this->params.clear();
30 this->parts.clear(); 54 this->parts.clear();
31 this->key.clear(); 55 this->key.clear();
10 hidden lines
42 //COUT << "set_key: " << m << '\n'; 66 //COUT << "set_key: " << m << '\n';
43 s.params[s.key = m] = ""; // ensure an empty value in case the val field is empty. 67 s.params[s.key = m] = ""; // ensure an empty value in case the val field is empty.
44 } 68 }
45 }; 69 };
46 70
47 /** Action to set a value. Uses the last-read key as the lookup key. */ | 71
| 72 template <bool IsEsc>
| 73 struct a_esc_append
| 74 {
| 75 static void matched( Ps::parser_state &, const std::string & m, std::string & s )
| 76 {
| 77 CERR << "a_esc_append<"<<IsEsc<<">:["<<m<<"]\n";
| 78 if( IsEsc )
| 79 {
| 80 std::istringstream is(m);
| 81 int x = '?';
| 82 is >> std::hex >> x; // weird: reading directly into ch missing the std::hex handling
| 83 s.push_back(std::string::value_type(x));
| 84 }
| 85 else
| 86 {
| 87 s += m;
| 88 }
| 89 }
| 90 };
| 91
| 92
| 93 /**
| 94 Action to set a value. Uses the last-read key as the lookup key.
| 95
| 96 The value is automatically un-percent-escaped (e.g. %20 is converted
| 97 to a space).
| 98 */
48 struct a_kvp_set_val 99 struct a_kvp_set_val
49 { 100 {
50 static void matched( Ps::parser_state &, const std::string & v, url_state & s ) | 101 static void matched( Ps::parser_state &, const std::string & m, url_state & s )
51 { 102 {
52 //COUT << "set_val: " << s.key << '='<<v << '\n'; | 103 COUT << "a_kvp_set_val: " << s.key << '='<<m << '\n';
53 s.params[s.key] = v; | 104 if( ! m.empty() )
| 105 {
| 106 std::string unesc;
| 107 typedef r_ch<'%'> PCT;
| 108 typedef r_repeat<r_xdigit,2> DIGITS;
| 109 typedef r_and<RL<PCT,DIGITS> > ESC;
| 110 typedef r_and<RL<PCT,
| 111 r_action< DIGITS, a_esc_append<true> >
| 112 > > AESC;
| 113 typedef r_action< r_plus< r_and<RL<r_notat<ESC>,r_advance<1> > > >, a_esc_append<false> > NESC;
| 114 typedef r_plus< r_or< RL< AESC, NESC > > > START;
| 115 Ps::parser_state ps(m);
| 116 Ps::parse<START>(ps, unesc);
| 117 s.params[s.key] = unesc;
| 118 }
| 119 else
| 120 {
| 121 s.params[s.key] = m;
| 122 }
54 s.key = ""; 123 s.key = "";
55 } 124 }
56 }; 125 };
57 126
58 /** 127 /**
206 hidden lines
265 } 334 }
266 335
267 }} // namespaces 336 }} // namespaces
268 337
269 #endif // S11N_NET_PARSEPP_URL_H_INCLUDED 338 #endif // S11N_NET_PARSEPP_URL_H_INCLUDED