blob: 700140e58227c25049dc1a8e1ec61ed255320506 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#include <library/cpp/http/client/cookies/cookie.h>
#include <util/datetime/parser.h>
namespace NHttp {
namespace {
%%{
machine http_cookie_parser;
include HttpDateTimeParser "../../../../../util/datetime/parser.rl6";
alphtype unsigned char;
################# Actions #################
action set_name {
result.Name = TString((const char*)S_, p - S_);
}
action set_value {
valueSet = true;
result.Value = TString((const char*)S_, p - S_);
}
action set_expires {
// TODO take care about server's date ?
result.Expires = TString((const char*)S_, p - S_);
}
action set_max_age {
// TODO take care about server's date ?
result.MaxAge = I;
}
action set_domain {
result.Domain = TString((const char*)S_, p - S_);
result.Domain.to_lower();
}
action set_path {
result.Path = TString((const char*)S_, p - S_);
}
action set_secure {
result.IsSecure = true;
}
action set_httponly {
result.IsHttpOnly = true;
}
################# Basic Rules #################
ws = [ \t];
separators = '(' | ')' | '<' | '>' | '@' | ',' | ';' | ':' | '\\' |
'"' | '/' | '[' | ']' | '?' | '=' | '{' | '}' | 32 | 9;
token_octet = 32..126 - separators;
token = token_octet+;
other_octet = 32..126 - ';';
other = other_octet+;
cookie_name_octet = other_octet - '=';
############ Set-Cookie line #################
# See https://tools.ietf.org/html/rfc6265
cookie_name = cookie_name_octet+ > { S_ = p; } %set_name;
cookie_value = other_octet* > { S_ = p; } %set_value;
cookie_pair = cookie_name "=" cookie_value;
expires_av = "expires="i other > { S_ = p; } %set_expires;
max_age_av = "max-age="i int %set_max_age;
domain_av = "domain="i "."? other > { S_ = p; } %set_domain;
path_av = "path="i other > { S_ = p; } %set_path;
secure_av = "secure"i %set_secure;
httponly_av = "httponly"i %set_httponly;
extension_av = other;
cookie_av = extension_av | expires_av | max_age_av | domain_av |
path_av | secure_av | httponly_av;
set_cookie_string = cookie_pair ( ";" ws* cookie_av )*;
################# main ############################
main := set_cookie_string;
}%%
%% write data;
} // namespace
///////////////////////////////////////////////////////////////////////////////
TCookie TCookie::Parse(const TString& data) {
TCookie result;
{
const unsigned char* S_ = nullptr;
long I = -1;
int Dc;
int cs;
const unsigned char *p = (const unsigned char*)data.data();
const unsigned char *pe = p + data.size();
const unsigned char* eof = pe;
bool valueSet = false;
%% write init;
%% write exec;
if (cs == %%{ write error; }%%) {
throw yexception() << "Cookie parse error";
}
if (!valueSet) {
throw yexception() << "Cookie value not set";
}
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
} // namespace NHttp
|