mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
add cookie support
This commit is contained in:
parent
770732d644
commit
12c443e6fb
@ -22,8 +22,9 @@
|
|||||||
extractor.h \
|
extractor.h \
|
||||||
httpAuthorization.I httpAuthorization.h \
|
httpAuthorization.I httpAuthorization.h \
|
||||||
httpBasicAuthorization.I httpBasicAuthorization.h \
|
httpBasicAuthorization.I httpBasicAuthorization.h \
|
||||||
httpClient.I httpClient.h \
|
|
||||||
httpChannel.I httpChannel.h \
|
httpChannel.I httpChannel.h \
|
||||||
|
httpClient.I httpClient.h \
|
||||||
|
httpCookie.I httpCookie.h \
|
||||||
httpDate.I httpDate.h \
|
httpDate.I httpDate.h \
|
||||||
httpDigestAuthorization.I httpDigestAuthorization.h \
|
httpDigestAuthorization.I httpDigestAuthorization.h \
|
||||||
httpEntityTag.I httpEntityTag.h \
|
httpEntityTag.I httpEntityTag.h \
|
||||||
@ -50,8 +51,9 @@
|
|||||||
extractor.cxx \
|
extractor.cxx \
|
||||||
httpAuthorization.cxx \
|
httpAuthorization.cxx \
|
||||||
httpBasicAuthorization.cxx \
|
httpBasicAuthorization.cxx \
|
||||||
httpClient.cxx \
|
|
||||||
httpChannel.cxx \
|
httpChannel.cxx \
|
||||||
|
httpClient.cxx \
|
||||||
|
httpCookie.cxx \
|
||||||
httpDate.cxx \
|
httpDate.cxx \
|
||||||
httpDigestAuthorization.cxx \
|
httpDigestAuthorization.cxx \
|
||||||
httpEntityTag.cxx \
|
httpEntityTag.cxx \
|
||||||
@ -76,8 +78,9 @@
|
|||||||
extractor.h \
|
extractor.h \
|
||||||
httpAuthorization.I httpAuthorization.h \
|
httpAuthorization.I httpAuthorization.h \
|
||||||
httpBasicAuthorization.I httpBasicAuthorization.h \
|
httpBasicAuthorization.I httpBasicAuthorization.h \
|
||||||
httpClient.I httpClient.h \
|
|
||||||
httpChannel.I httpChannel.h \
|
httpChannel.I httpChannel.h \
|
||||||
|
httpClient.I httpClient.h \
|
||||||
|
httpCookie.I httpCookie.h \
|
||||||
httpDate.I httpDate.h \
|
httpDate.I httpDate.h \
|
||||||
httpDigestAuthorization.I httpDigestAuthorization.h \
|
httpDigestAuthorization.I httpDigestAuthorization.h \
|
||||||
httpEntityTag.I httpEntityTag.h \
|
httpEntityTag.I httpEntityTag.h \
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "httpBasicAuthorization.cxx"
|
#include "httpBasicAuthorization.cxx"
|
||||||
#include "httpChannel.cxx"
|
#include "httpChannel.cxx"
|
||||||
#include "httpClient.cxx"
|
#include "httpClient.cxx"
|
||||||
|
#include "httpCookie.cxx"
|
||||||
#include "httpDate.cxx"
|
#include "httpDate.cxx"
|
||||||
#include "httpDigestAuthorization.cxx"
|
#include "httpDigestAuthorization.cxx"
|
||||||
#include "httpEntityTag.cxx"
|
#include "httpEntityTag.cxx"
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "httpChannel.h"
|
#include "httpChannel.h"
|
||||||
#include "httpClient.h"
|
#include "httpClient.h"
|
||||||
|
#include "httpCookie.h"
|
||||||
#include "bioStream.h"
|
#include "bioStream.h"
|
||||||
#include "ssl_utils.h"
|
#include "ssl_utils.h"
|
||||||
#include "chunkedStream.h"
|
#include "chunkedStream.h"
|
||||||
@ -791,7 +792,11 @@ reached_done_state() {
|
|||||||
<< "Unable to download body.\n";
|
<< "Unable to download body.\n";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (_state != S_reading_body) {
|
||||||
|
_body_stream = NULL;
|
||||||
|
}
|
||||||
_started_download = true;
|
_started_download = true;
|
||||||
_last_run_time = ClockObject::get_global_clock()->get_real_time();
|
_last_run_time = ClockObject::get_global_clock()->get_real_time();
|
||||||
return true;
|
return true;
|
||||||
@ -1831,7 +1836,12 @@ run_begin_body() {
|
|||||||
reset_to_new();
|
reset_to_new();
|
||||||
|
|
||||||
} else {
|
} 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();
|
_body_stream = read_body();
|
||||||
if (_body_stream == (ISocketStream *)NULL) {
|
if (_body_stream == (ISocketStream *)NULL) {
|
||||||
if (downloader_cat.is_debug()) {
|
if (downloader_cat.is_debug()) {
|
||||||
@ -1841,7 +1851,9 @@ run_begin_body() {
|
|||||||
reset_to_new();
|
reset_to_new();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_state = S_reading_body;
|
if (_state != S_reading_body) {
|
||||||
|
_body_stream = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3115,6 +3127,8 @@ make_header() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_client->send_cookies(stream, _request.get_url());
|
||||||
|
|
||||||
if (!_body.empty()) {
|
if (!_body.empty()) {
|
||||||
stream
|
stream
|
||||||
<< "Content-Type: application/x-www-form-urlencoded\r\n"
|
<< "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 += ", ";
|
||||||
(*hi).second += field_value;
|
(*hi).second += field_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (field_name == "set-cookie") {
|
||||||
|
_client->set_cookie(HTTPCookie(field_value, _request.get_url()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -609,6 +609,140 @@ get_username(const string &server, const string &realm) const {
|
|||||||
return string();
|
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
|
// Function: HTTPClient::load_client_certificate
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -31,10 +31,12 @@
|
|||||||
#include "urlSpec.h"
|
#include "urlSpec.h"
|
||||||
#include "httpAuthorization.h"
|
#include "httpAuthorization.h"
|
||||||
#include "httpEnum.h"
|
#include "httpEnum.h"
|
||||||
|
#include "httpCookie.h"
|
||||||
#include "globPattern.h"
|
#include "globPattern.h"
|
||||||
#include "pointerTo.h"
|
#include "pointerTo.h"
|
||||||
#include "pvector.h"
|
#include "pvector.h"
|
||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
|
#include "pset.h"
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
@ -82,6 +84,15 @@ PUBLISHED:
|
|||||||
void set_username(const string &server, const string &realm, const string &username);
|
void set_username(const string &server, const string &realm, const string &username);
|
||||||
string get_username(const string &server, const string &realm) const;
|
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_filename(const Filename &filename);
|
||||||
INLINE void set_client_certificate_pem(const string &pem);
|
INLINE void set_client_certificate_pem(const string &pem);
|
||||||
INLINE void set_client_certificate_passphrase(const string &passphrase);
|
INLINE void set_client_certificate_passphrase(const string &passphrase);
|
||||||
@ -157,7 +168,7 @@ private:
|
|||||||
typedef pmap<string, string> Usernames;
|
typedef pmap<string, string> Usernames;
|
||||||
Usernames _usernames;
|
Usernames _usernames;
|
||||||
|
|
||||||
typedef map<string, PT(HTTPAuthorization) > Realms;
|
typedef pmap<string, PT(HTTPAuthorization) > Realms;
|
||||||
class Domain {
|
class Domain {
|
||||||
public:
|
public:
|
||||||
Realms _realms;
|
Realms _realms;
|
||||||
@ -165,6 +176,9 @@ private:
|
|||||||
typedef pmap<string, Domain> Domains;
|
typedef pmap<string, Domain> Domains;
|
||||||
Domains _proxy_domains, _www_domains;
|
Domains _proxy_domains, _www_domains;
|
||||||
|
|
||||||
|
typedef pset<HTTPCookie> Cookies;
|
||||||
|
Cookies _cookies;
|
||||||
|
|
||||||
Filename _client_certificate_filename;
|
Filename _client_certificate_filename;
|
||||||
string _client_certificate_pem;
|
string _client_certificate_pem;
|
||||||
string _client_certificate_passphrase;
|
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