00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "httpCookie.h"
00016
00017 #ifdef HAVE_OPENSSL
00018
00019 #include "ctype.h"
00020 #include "httpChannel.h"
00021
00022
00023
00024
00025
00026
00027
00028
00029 bool HTTPCookie::
00030 operator < (const HTTPCookie &other) const {
00031 if (_domain != other._domain) {
00032 return _domain < other._domain;
00033 }
00034
00035 if (_path != other._path) {
00036
00037
00038
00039 return _path > other._path;
00040 }
00041
00042 if (_name != other._name) {
00043 return _name < other._name;
00044 }
00045
00046 return false;
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 void HTTPCookie::
00061 update_from(const HTTPCookie &other) {
00062 nassertv(!(other < *this) && !(*this < other));
00063
00064 _value = other._value;
00065 _expires = other._expires;
00066 _secure = other._secure;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 bool HTTPCookie::
00079 parse_set_cookie(const string &format, const URLSpec &url) {
00080 _name = string();
00081 _value = string();
00082 _domain = url.get_server();
00083 _path = url.get_path();
00084 _expires = HTTPDate();
00085 _secure = false;
00086
00087 bool okflag = true;
00088 bool first_param = true;
00089
00090 size_t start = 0;
00091 while (start < format.length() && isspace(format[start])) {
00092 start++;
00093 }
00094 size_t semicolon = format.find(';', start);
00095
00096 while (semicolon != string::npos) {
00097 if (!parse_cookie_param(format.substr(start, semicolon - start),
00098 first_param)) {
00099 okflag = false;
00100 }
00101 first_param = false;
00102 start = semicolon + 1;
00103 while (start < format.length() && isspace(format[start])) {
00104 start++;
00105 }
00106 semicolon = format.find(';', start);
00107 }
00108
00109 if (!parse_cookie_param(format.substr(start), first_param)) {
00110 okflag = false;
00111 }
00112
00113 return okflag;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 bool HTTPCookie::
00123 matches_url(const URLSpec &url) const {
00124 if (_domain.empty()) {
00125 return false;
00126 }
00127 string server = url.get_server();
00128 if (server == _domain ||
00129 (string(".") + server) == _domain ||
00130 (server.length() > _domain.length() &&
00131 server.substr(server.length() - _domain.length()) == _domain &&
00132 (_domain[0] == '.' || server[server.length() - _domain.length() - 1] == '.'))) {
00133
00134
00135 string path = url.get_path();
00136 if (path.length() >= _path.length() &&
00137 path.substr(0, _path.length()) == _path) {
00138
00139
00140 if (_secure && !url.is_ssl()) {
00141
00142 return false;
00143 }
00144
00145 return true;
00146 }
00147 }
00148
00149 return false;
00150 }
00151
00152
00153
00154
00155
00156
00157 void HTTPCookie::
00158 output(ostream &out) const {
00159 out << _name << "=" << _value
00160 << "; path=" << _path << "; domain=" << _domain;
00161
00162 if (has_expires()) {
00163 out << "; expires=" << _expires;
00164 }
00165
00166 if (_secure) {
00167 out << "; secure";
00168 }
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 bool HTTPCookie::
00181 parse_cookie_param(const string ¶m, bool first_param) {
00182 size_t equals = param.find('=');
00183
00184 string key, value;
00185 if (equals == string::npos) {
00186 key = param;
00187 } else {
00188 key = param.substr(0, equals);
00189 value = param.substr(equals + 1);
00190 }
00191
00192 if (first_param) {
00193 _name = key;
00194 _value = value;
00195
00196 } else {
00197 key = HTTPChannel::downcase(key);
00198 if (key == "expires") {
00199 _expires = HTTPDate(value);
00200 if (!_expires.is_valid()) {
00201 return false;
00202 }
00203
00204 } else if (key == "path") {
00205 _path = value;
00206
00207 } else if (key == "domain") {
00208 _domain = HTTPChannel::downcase(value);
00209
00210
00211
00212 if (!_domain.empty() && _domain[0] != '.') {
00213 _domain = string(".") + _domain;
00214 }
00215
00216 } else if (key == "secure") {
00217 _secure = true;
00218
00219 } else {
00220 return false;
00221 }
00222 }
00223
00224 return true;
00225 }
00226
00227 #endif // HAVE_OPENSSL