mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
add cookie support
This commit is contained in:
parent
770732d644
commit
12c443e6fb
@ -22,8 +22,9 @@
|
||||
extractor.h \
|
||||
httpAuthorization.I httpAuthorization.h \
|
||||
httpBasicAuthorization.I httpBasicAuthorization.h \
|
||||
httpClient.I httpClient.h \
|
||||
httpChannel.I httpChannel.h \
|
||||
httpClient.I httpClient.h \
|
||||
httpCookie.I httpCookie.h \
|
||||
httpDate.I httpDate.h \
|
||||
httpDigestAuthorization.I httpDigestAuthorization.h \
|
||||
httpEntityTag.I httpEntityTag.h \
|
||||
@ -50,8 +51,9 @@
|
||||
extractor.cxx \
|
||||
httpAuthorization.cxx \
|
||||
httpBasicAuthorization.cxx \
|
||||
httpClient.cxx \
|
||||
httpChannel.cxx \
|
||||
httpClient.cxx \
|
||||
httpCookie.cxx \
|
||||
httpDate.cxx \
|
||||
httpDigestAuthorization.cxx \
|
||||
httpEntityTag.cxx \
|
||||
@ -76,8 +78,9 @@
|
||||
extractor.h \
|
||||
httpAuthorization.I httpAuthorization.h \
|
||||
httpBasicAuthorization.I httpBasicAuthorization.h \
|
||||
httpClient.I httpClient.h \
|
||||
httpChannel.I httpChannel.h \
|
||||
httpClient.I httpClient.h \
|
||||
httpCookie.I httpCookie.h \
|
||||
httpDate.I httpDate.h \
|
||||
httpDigestAuthorization.I httpDigestAuthorization.h \
|
||||
httpEntityTag.I httpEntityTag.h \
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "httpBasicAuthorization.cxx"
|
||||
#include "httpChannel.cxx"
|
||||
#include "httpClient.cxx"
|
||||
#include "httpCookie.cxx"
|
||||
#include "httpDate.cxx"
|
||||
#include "httpDigestAuthorization.cxx"
|
||||
#include "httpEntityTag.cxx"
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "httpChannel.h"
|
||||
#include "httpClient.h"
|
||||
#include "httpCookie.h"
|
||||
#include "bioStream.h"
|
||||
#include "ssl_utils.h"
|
||||
#include "chunkedStream.h"
|
||||
@ -791,7 +792,11 @@ reached_done_state() {
|
||||
<< "Unable to download body.\n";
|
||||
}
|
||||
return false;
|
||||
|
||||
} else {
|
||||
if (_state != S_reading_body) {
|
||||
_body_stream = NULL;
|
||||
}
|
||||
_started_download = true;
|
||||
_last_run_time = ClockObject::get_global_clock()->get_real_time();
|
||||
return true;
|
||||
@ -1831,7 +1836,12 @@ run_begin_body() {
|
||||
reset_to_new();
|
||||
|
||||
} else {
|
||||
nassertr(_body_stream == NULL, false);
|
||||
// We shouldn't already be in the middle of reading some other
|
||||
// body when we come here.
|
||||
nassertd(_body_stream == NULL) {
|
||||
reset_to_new();
|
||||
return false;
|
||||
}
|
||||
_body_stream = read_body();
|
||||
if (_body_stream == (ISocketStream *)NULL) {
|
||||
if (downloader_cat.is_debug()) {
|
||||
@ -1841,7 +1851,9 @@ run_begin_body() {
|
||||
reset_to_new();
|
||||
|
||||
} else {
|
||||
_state = S_reading_body;
|
||||
if (_state != S_reading_body) {
|
||||
_body_stream = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3115,6 +3127,8 @@ make_header() {
|
||||
break;
|
||||
}
|
||||
|
||||
_client->send_cookies(stream, _request.get_url());
|
||||
|
||||
if (!_body.empty()) {
|
||||
stream
|
||||
<< "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
@ -3220,6 +3234,10 @@ store_header_field(const string &field_name, const string &field_value) {
|
||||
(*hi).second += ", ";
|
||||
(*hi).second += field_value;
|
||||
}
|
||||
|
||||
if (field_name == "set-cookie") {
|
||||
_client->set_cookie(HTTPCookie(field_value, _request.get_url()));
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -609,6 +609,140 @@ get_username(const string &server, const string &realm) const {
|
||||
return string();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::set_cookie
|
||||
// Access: Published
|
||||
// Description: Stores the indicated cookie in the client's list of
|
||||
// cookies, as if it had been received from a server.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPClient::
|
||||
set_cookie(const HTTPCookie &cookie) {
|
||||
if (cookie.is_expired()) {
|
||||
clear_cookie(cookie);
|
||||
|
||||
} else {
|
||||
pair<Cookies::iterator, bool> result = _cookies.insert(cookie);
|
||||
if (!result.second) {
|
||||
// We already had a cookie matching the supplied domain/path/name,
|
||||
// so replace it.
|
||||
const HTTPCookie &orig_cookie = *result.first;
|
||||
((HTTPCookie &)orig_cookie).update_from(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::clear_cookie
|
||||
// Access: Published
|
||||
// Description: Removes the cookie with the matching domain/path/name
|
||||
// from the client's list of cookies. Returns true if
|
||||
// it was removed, false if the cookie was not matched.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPClient::
|
||||
clear_cookie(const HTTPCookie &cookie) {
|
||||
Cookies::iterator ci = _cookies.find(cookie);
|
||||
if (ci != _cookies.end()) {
|
||||
_cookies.erase(ci);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::clear_all_cookies
|
||||
// Access: Published
|
||||
// Description: Removes the all stored cookies from the client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPClient::
|
||||
clear_all_cookies() {
|
||||
_cookies.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::has_cookie
|
||||
// Access: Published
|
||||
// Description: Returns true if there is a cookie in the client
|
||||
// matching the given cookie's domain/path/name, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPClient::
|
||||
has_cookie(const HTTPCookie &cookie) const {
|
||||
Cookies::const_iterator ci = _cookies.find(cookie);
|
||||
return (ci != _cookies.end());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::get_cookie
|
||||
// Access: Published
|
||||
// Description: Looks up and returns the cookie in the client
|
||||
// matching the given cookie's domain/path/name. If
|
||||
// there is no matching cookie, returns an empty cookie.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
HTTPCookie HTTPClient::
|
||||
get_cookie(const HTTPCookie &cookie) const {
|
||||
Cookies::const_iterator ci = _cookies.find(cookie);
|
||||
if (ci != _cookies.end()) {
|
||||
return (*ci);
|
||||
}
|
||||
|
||||
return HTTPCookie();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::write_cookies
|
||||
// Access: Published
|
||||
// Description: Outputs the complete list of cookies stored on the
|
||||
// client, for all domains, including the expired
|
||||
// cookies (which will normally not be sent back to a
|
||||
// host).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPClient::
|
||||
write_cookies(ostream &out) const {
|
||||
Cookies::const_iterator ci;
|
||||
for (ci = _cookies.begin(); ci != _cookies.end(); ++ci) {
|
||||
out << *ci << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::send_cookies
|
||||
// Access: Published
|
||||
// Description: Writes to the indicated ostream a set of Cookie:
|
||||
// lines for sending the cookies appropriate to the
|
||||
// indicated URL along with an HTTP request. This also
|
||||
// removes expired cookies.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPClient::
|
||||
send_cookies(ostream &out, const URLSpec &url) {
|
||||
HTTPDate now = HTTPDate::now();
|
||||
bool any_expired = false;
|
||||
|
||||
Cookies::const_iterator ci;
|
||||
for (ci = _cookies.begin(); ci != _cookies.end(); ++ci) {
|
||||
const HTTPCookie &cookie = (*ci);
|
||||
if (cookie.is_expired(now)) {
|
||||
any_expired = true;
|
||||
|
||||
} else if (cookie.matches_url(url)) {
|
||||
out << "Cookie: " << cookie.get_name() << "="
|
||||
<< cookie.get_value() << "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (any_expired) {
|
||||
Cookies new_cookies;
|
||||
Cookies::const_iterator ci;
|
||||
for (ci = _cookies.begin(); ci != _cookies.end(); ++ci) {
|
||||
const HTTPCookie &cookie = (*ci);
|
||||
if (!cookie.is_expired(now)) {
|
||||
new_cookies.insert(new_cookies.end(), cookie);
|
||||
}
|
||||
}
|
||||
_cookies.swap(new_cookies);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPClient::load_client_certificate
|
||||
// Access: Published
|
||||
|
@ -31,10 +31,12 @@
|
||||
#include "urlSpec.h"
|
||||
#include "httpAuthorization.h"
|
||||
#include "httpEnum.h"
|
||||
#include "httpCookie.h"
|
||||
#include "globPattern.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pvector.h"
|
||||
#include "pmap.h"
|
||||
#include "pset.h"
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
@ -82,6 +84,15 @@ PUBLISHED:
|
||||
void set_username(const string &server, const string &realm, const string &username);
|
||||
string get_username(const string &server, const string &realm) const;
|
||||
|
||||
void set_cookie(const HTTPCookie &cookie);
|
||||
bool clear_cookie(const HTTPCookie &cookie);
|
||||
void clear_all_cookies();
|
||||
bool has_cookie(const HTTPCookie &cookie) const;
|
||||
HTTPCookie get_cookie(const HTTPCookie &cookie) const;
|
||||
|
||||
void write_cookies(ostream &out) const;
|
||||
void send_cookies(ostream &out, const URLSpec &url);
|
||||
|
||||
INLINE void set_client_certificate_filename(const Filename &filename);
|
||||
INLINE void set_client_certificate_pem(const string &pem);
|
||||
INLINE void set_client_certificate_passphrase(const string &passphrase);
|
||||
@ -157,7 +168,7 @@ private:
|
||||
typedef pmap<string, string> Usernames;
|
||||
Usernames _usernames;
|
||||
|
||||
typedef map<string, PT(HTTPAuthorization) > Realms;
|
||||
typedef pmap<string, PT(HTTPAuthorization) > Realms;
|
||||
class Domain {
|
||||
public:
|
||||
Realms _realms;
|
||||
@ -165,6 +176,9 @@ private:
|
||||
typedef pmap<string, Domain> Domains;
|
||||
Domains _proxy_domains, _www_domains;
|
||||
|
||||
typedef pset<HTTPCookie> Cookies;
|
||||
Cookies _cookies;
|
||||
|
||||
Filename _client_certificate_filename;
|
||||
string _client_certificate_pem;
|
||||
string _client_certificate_passphrase;
|
||||
|
232
panda/src/downloader/httpCookie.I
Normal file
232
panda/src/downloader/httpCookie.I
Normal file
@ -0,0 +1,232 @@
|
||||
// Filename: httpCookie.I
|
||||
// Created by: drose (26Aug04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs an empty cookie.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE HTTPCookie::
|
||||
HTTPCookie() :
|
||||
_secure(false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs a cookie according to the indicated
|
||||
// string, presumably the tag of a Set-Cookie header.
|
||||
// There is no way to detect a formatting error in the
|
||||
// string with this constructor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE HTTPCookie::
|
||||
HTTPCookie(const string &format, const URLSpec &url) {
|
||||
parse_set_cookie(format, url);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs a cookie with the indicated name, path,
|
||||
// and domain values, but no other data. This is most
|
||||
// useful for looking up an existing cookie in the
|
||||
// HTTPClient.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE HTTPCookie::
|
||||
HTTPCookie(const string &name, const string &path, const string &domain) :
|
||||
_name(name),
|
||||
_path(path),
|
||||
_domain(domain),
|
||||
_secure(false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE HTTPCookie::
|
||||
~HTTPCookie() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::set_name
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPCookie::
|
||||
set_name(const string &name) {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::get_name
|
||||
// Access: Published
|
||||
// Description: Returns the name of the cookie. This is the key
|
||||
// value specified by the server.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &HTTPCookie::
|
||||
get_name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::set_value
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPCookie::
|
||||
set_value(const string &value) {
|
||||
_value = value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::get_value
|
||||
// Access: Published
|
||||
// Description: Returns the value of the cookie. This is the
|
||||
// arbitrary string associated with the cookie's name,
|
||||
// as specified by the server.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &HTTPCookie::
|
||||
get_value() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::set_domain
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPCookie::
|
||||
set_domain(const string &domain) {
|
||||
_domain = domain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::get_domain
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &HTTPCookie::
|
||||
get_domain() const {
|
||||
return _domain;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::set_path
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPCookie::
|
||||
set_path(const string &path) {
|
||||
_path = path;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::get_path
|
||||
// Access: Published
|
||||
// Description: Returns the prefix of the URL paths on the server for
|
||||
// which this cookie will be sent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &HTTPCookie::
|
||||
get_path() const {
|
||||
return _path;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::set_expires
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPCookie::
|
||||
set_expires(const HTTPDate &expires) {
|
||||
_expires = expires;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::clear_expires
|
||||
// Access: Published
|
||||
// Description: Removes the expiration date on the cookie.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPCookie::
|
||||
clear_expires() {
|
||||
_expires = HTTPDate();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::has_expires
|
||||
// Access: Published
|
||||
// Description: Returns true if the cookie has an expiration date,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool HTTPCookie::
|
||||
has_expires() const {
|
||||
return _expires.is_valid();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::get_expires
|
||||
// Access: Published
|
||||
// Description: Returns the expiration date of the cookie if it is
|
||||
// set, or an invalid date if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE HTTPDate HTTPCookie::
|
||||
get_expires() const {
|
||||
return _expires;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::set_secure
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void HTTPCookie::
|
||||
set_secure(bool secure) {
|
||||
_secure = secure;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::get_secure
|
||||
// Access: Published
|
||||
// Description: Returns true if the server has indicated this is a
|
||||
// "secure" cookie which should only be sent over an
|
||||
// HTTPS channel.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool HTTPCookie::
|
||||
get_secure() const {
|
||||
return _secure;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::is_expired
|
||||
// Access: Published
|
||||
// Description: Returns true if the cookie's expiration date is
|
||||
// before the indicated date, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool HTTPCookie::
|
||||
is_expired(const HTTPDate &now) const {
|
||||
return _expires.is_valid() && _expires < now;
|
||||
}
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const HTTPCookie &cookie) {
|
||||
cookie.output(out);
|
||||
return out;
|
||||
}
|
221
panda/src/downloader/httpCookie.cxx
Normal file
221
panda/src/downloader/httpCookie.cxx
Normal file
@ -0,0 +1,221 @@
|
||||
// Filename: httpCookie.cxx
|
||||
// Created by: drose (26Aug04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "httpCookie.h"
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
#include "ctype.h"
|
||||
#include "httpChannel.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::operator <
|
||||
// Access: Published
|
||||
// Description: The sorting operator allows the cookies to be stored
|
||||
// in a single dictionary; it returns nonequal only if
|
||||
// the cookies are different in name, path, or domain.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPCookie::
|
||||
operator < (const HTTPCookie &other) const {
|
||||
if (_domain != other._domain) {
|
||||
return _domain < other._domain;
|
||||
}
|
||||
|
||||
if (_path != other._path) {
|
||||
// We use reverse sorting on the path, so that cookies with longer
|
||||
// paths will be sent to the server before cookies with shorter
|
||||
// paths.
|
||||
return _path > other._path;
|
||||
}
|
||||
|
||||
if (_name != other._name) {
|
||||
return _name < other._name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::update_from
|
||||
// Access: Published
|
||||
// Description: Assuming the operator < method, above, has already
|
||||
// evaluated these two cookies as equal, then assign the
|
||||
// remaining values (value, expiration date, secure
|
||||
// flag) from the indicated cookie. This is guaranteed
|
||||
// not to change the ordering of the cookie in a set,
|
||||
// and so can be used to update an existing cookie
|
||||
// within a set with new values.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPCookie::
|
||||
update_from(const HTTPCookie &other) {
|
||||
nassertv(!(other < *this) && !(*this < other));
|
||||
|
||||
_value = other._value;
|
||||
_expires = other._expires;
|
||||
_secure = other._secure;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::parse_set_cookie
|
||||
// Access: Published
|
||||
// Description: Separates out the parameter/value pairs of the
|
||||
// Set-Cookie header and assigns the values of the
|
||||
// cookie appropriate. Returns true if the header is
|
||||
// parsed correctly, false if something is not
|
||||
// understood.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPCookie::
|
||||
parse_set_cookie(const string &format, const URLSpec &url) {
|
||||
_name = string();
|
||||
_value = string();
|
||||
_domain = url.get_server();
|
||||
_path = url.get_path();
|
||||
_expires = HTTPDate();
|
||||
_secure = false;
|
||||
|
||||
bool okflag = true;
|
||||
bool first_param = true;
|
||||
|
||||
size_t start = 0;
|
||||
while (start < format.length() && isspace(format[start])) {
|
||||
start++;
|
||||
}
|
||||
size_t semicolon = format.find(';', start);
|
||||
|
||||
while (semicolon != string::npos) {
|
||||
if (!parse_cookie_param(format.substr(start, semicolon - start),
|
||||
first_param)) {
|
||||
okflag = false;
|
||||
}
|
||||
first_param = false;
|
||||
start = semicolon + 1;
|
||||
while (start < format.length() && isspace(format[start])) {
|
||||
start++;
|
||||
}
|
||||
semicolon = format.find(';', start);
|
||||
}
|
||||
|
||||
if (!parse_cookie_param(format.substr(start), first_param)) {
|
||||
okflag = false;
|
||||
}
|
||||
|
||||
return okflag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::matches_url
|
||||
// Access: Published
|
||||
// Description: Returns true if the cookie is appropriate to send
|
||||
// with the indicated URL request, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPCookie::
|
||||
matches_url(const URLSpec &url) const {
|
||||
string server = url.get_server();
|
||||
if (server == _domain ||
|
||||
(server.length() > _domain.length() &&
|
||||
server.substr(server.length() - _domain.length()) == _domain &&
|
||||
server[server.length() - _domain.length() - 1] == '.')) {
|
||||
// The domain matches.
|
||||
|
||||
string path = url.get_path();
|
||||
if (path.length() >= _path.length() &&
|
||||
path.substr(0, _path.length()) == _path) {
|
||||
|
||||
// The path matches too.
|
||||
if (_secure && !url.is_ssl()) {
|
||||
// Oops, can't send a secure cookie over a non-secure connection.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPCookie::
|
||||
output(ostream &out) const {
|
||||
out << _name << "=" << _value
|
||||
<< "; path=" << _path << "; domain=" << _domain;
|
||||
|
||||
if (has_expires()) {
|
||||
out << "; expires=" << _expires;
|
||||
}
|
||||
|
||||
if (_secure) {
|
||||
out << "; secure";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPCookie::parse_cookie_param
|
||||
// Access: Private
|
||||
// Description: Called internally by parse_set_cookie() with each
|
||||
// parameter=value pair split out from the header
|
||||
// string. first_param will be true for the first
|
||||
// parameter (which has special meaning). This should
|
||||
// return true on success, false on failure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool HTTPCookie::
|
||||
parse_cookie_param(const string ¶m, bool first_param) {
|
||||
size_t equals = param.find('=');
|
||||
|
||||
string key, value;
|
||||
if (equals == string::npos) {
|
||||
key = param;
|
||||
} else {
|
||||
key = param.substr(0, equals);
|
||||
value = param.substr(equals + 1);
|
||||
}
|
||||
|
||||
if (first_param) {
|
||||
_name = key;
|
||||
_value = value;
|
||||
|
||||
} else {
|
||||
key = HTTPChannel::downcase(key);
|
||||
if (key == "expires") {
|
||||
_expires = HTTPDate(value);
|
||||
if (!_expires.is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (key == "path") {
|
||||
_path = value;
|
||||
|
||||
} else if (key == "domain") {
|
||||
_domain = HTTPChannel::downcase(value);
|
||||
|
||||
} else if (key == "secure") {
|
||||
_secure = true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // HAVE_SSL
|
93
panda/src/downloader/httpCookie.h
Normal file
93
panda/src/downloader/httpCookie.h
Normal file
@ -0,0 +1,93 @@
|
||||
// Filename: httpCookie.h
|
||||
// Created by: drose (26Aug04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef HTTPCOOKIE_H
|
||||
#define HTTPCOOKIE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
// This module requires OpenSSL to compile, even if you do not intend
|
||||
// to use this to establish https connections; this is because it uses
|
||||
// the OpenSSL library to portably handle all of the socket
|
||||
// communications.
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
#include "httpDate.h"
|
||||
#include "urlSpec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : HTTPCookie
|
||||
// Description : A cookie sent from an HTTP server to be stored on the
|
||||
// client and returned when the path and/or domain
|
||||
// matches.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS HTTPCookie {
|
||||
PUBLISHED:
|
||||
INLINE HTTPCookie();
|
||||
INLINE HTTPCookie(const string &format, const URLSpec &url);
|
||||
INLINE HTTPCookie(const string &name, const string &path, const string &domain);
|
||||
INLINE ~HTTPCookie();
|
||||
|
||||
INLINE void set_name(const string &name);
|
||||
INLINE const string &get_name() const;
|
||||
|
||||
INLINE void set_value(const string &value);
|
||||
INLINE const string &get_value() const;
|
||||
|
||||
INLINE void set_domain(const string &domain);
|
||||
INLINE const string &get_domain() const;
|
||||
|
||||
INLINE void set_path(const string &path);
|
||||
INLINE const string &get_path() const;
|
||||
|
||||
INLINE void set_expires(const HTTPDate &expires);
|
||||
INLINE void clear_expires();
|
||||
INLINE bool has_expires() const;
|
||||
INLINE HTTPDate get_expires() const;
|
||||
|
||||
INLINE void set_secure(bool flag);
|
||||
INLINE bool get_secure() const;
|
||||
|
||||
bool operator < (const HTTPCookie &other) const;
|
||||
void update_from(const HTTPCookie &other);
|
||||
|
||||
bool parse_set_cookie(const string &format, const URLSpec &url);
|
||||
INLINE bool is_expired(const HTTPDate &now = HTTPDate::now()) const;
|
||||
bool matches_url(const URLSpec &url) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
bool parse_cookie_param(const string ¶m, bool first_param);
|
||||
|
||||
string _name;
|
||||
string _value;
|
||||
string _domain;
|
||||
string _path;
|
||||
HTTPDate _expires;
|
||||
bool _secure;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const HTTPCookie &cookie);
|
||||
|
||||
#include "httpCookie.I"
|
||||
|
||||
#endif // HAVE_SSL
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user