Skip to content

Commit

Permalink
enh(Net): Poco::Net::HTTPResponse: add replaceCookie() and removeCook…
Browse files Browse the repository at this point in the history
…ie() #4825
  • Loading branch information
obiltschnig committed Dec 19, 2024
1 parent 3f76ad6 commit 854d8c8
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 30 deletions.
9 changes: 9 additions & 0 deletions Net/include/Poco/Net/HTTPResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,15 @@ class Net_API HTTPResponse: public HTTPMessage
/// Adds the cookie to the response by
/// adding a Set-Cookie header.

void removeCookie(const std::string& cookieName);
/// Removes the Set-Cookie header for the cookie with the given name,
/// if the header is present. Otherwise does nothing.

void replaceCookie(const HTTPCookie& cookie);
/// Replaces a Set-Cookie header for the given cookie with the
/// updated cookie, or adds a new Set-Cookie header of none
/// is present for the given cookie.

void getCookies(std::vector<HTTPCookie>& cookies) const;
/// Returns a vector with all the cookies
/// set in the response header.
Expand Down
72 changes: 70 additions & 2 deletions Net/include/Poco/Net/NameValueCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,26 @@ class Net_API NameValueCollection
/// Returns an iterator pointing to the first name-value pair
/// with the given name.

Iterator find(const std::string& name);
/// Returns an iterator pointing to the first name-value pair
/// with the given name.

ConstIterator begin() const;
/// Returns an iterator pointing to the begin of
/// the name-value pair collection.

Iterator begin();
/// Returns an iterator pointing to the begin of
/// the name-value pair collection.

ConstIterator end() const;
/// Returns an iterator pointing to the end of
/// the name-value pair collection.

Iterator end();
/// Returns an iterator pointing to the end of
/// the name-value pair collection.

bool empty() const;
/// Returns true iff the header does not have any content.

Expand All @@ -109,10 +121,18 @@ class Net_API NameValueCollection
void erase(const std::string& name);
/// Removes all name-value pairs with the given name.

void erase(Iterator it);
/// Removes the name-value pair referenced by the given iterator.

void secureErase(const std::string& name);
/// Securely erases all name-value pairs with the given name
/// Securely erases all name-value pairs with the given name,
/// by first overwriting the value with zeroes before
/// removing the value.

void secureErase(Iterator it);
/// Securely erases the name-value pair referenced by the given iterator,
/// by first overwriting the value with zeroes before
/// removing it.
/// removing the value.

void clear();
/// Removes all name-value pairs and their values.
Expand All @@ -135,6 +155,54 @@ inline void swap(NameValueCollection& nvc1, NameValueCollection& nvc2) noexcept
}


inline NameValueCollection::ConstIterator NameValueCollection::find(const std::string& name) const
{
return _map.find(name);
}


inline NameValueCollection::Iterator NameValueCollection::find(const std::string& name)
{
return _map.find(name);
}


inline NameValueCollection::ConstIterator NameValueCollection::begin() const
{
return _map.begin();
}


inline NameValueCollection::Iterator NameValueCollection::begin()
{
return _map.begin();
}


inline NameValueCollection::ConstIterator NameValueCollection::end() const
{
return _map.end();
}


inline NameValueCollection::Iterator NameValueCollection::end()
{
return _map.end();
}


inline bool NameValueCollection::empty() const
{
return _map.empty();
}


inline std::size_t NameValueCollection::size() const
{
return _map.size();
}


} } // namespace Poco::Net


Expand Down
34 changes: 34 additions & 0 deletions Net/src/HTTPResponse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,40 @@ void HTTPResponse::addCookie(const HTTPCookie& cookie)
}


void HTTPResponse::removeCookie(const std::string& cookieName)
{
NameValueCollection::Iterator it = find(SET_COOKIE);
while (it != end() && Poco::icompare(it->first, SET_COOKIE) == 0)
{
const std::string& hv = it->second;
if (hv.size() > cookieName.size() && hv[cookieName.size()] == '=' && hv.compare(0, cookieName.size(), cookieName) == 0)
{
erase(it);
break;
}
++it;
}
}


void HTTPResponse::replaceCookie(const HTTPCookie& cookie)
{
const std::string& cookieName = cookie.getName();
NameValueCollection::Iterator it = find(SET_COOKIE);
while (it != end() && Poco::icompare(it->first, SET_COOKIE) == 0)
{
const std::string& hv = it->second;
if (hv.size() > cookieName.size() && hv[cookieName.size()] == '=' && hv.compare(0, cookieName.size(), cookieName) == 0)
{
it->second = cookie.toString();
return;
}
++it;
}
add(SET_COOKIE, cookie.toString());
}


void HTTPResponse::getCookies(std::vector<HTTPCookie>& cookies) const
{
cookies.clear();
Expand Down
40 changes: 12 additions & 28 deletions Net/src/NameValueCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "Poco/Net/NameValueCollection.h"
#include "Poco/Exception.h"
#include "Poco/String.h"
#include <algorithm>


Expand Down Expand Up @@ -121,39 +122,15 @@ bool NameValueCollection::has(const std::string& name) const
}


NameValueCollection::ConstIterator NameValueCollection::find(const std::string& name) const
{
return _map.find(name);
}


NameValueCollection::ConstIterator NameValueCollection::begin() const
{
return _map.begin();
}


NameValueCollection::ConstIterator NameValueCollection::end() const
{
return _map.end();
}


bool NameValueCollection::empty() const
{
return _map.empty();
}


std::size_t NameValueCollection::size() const
void NameValueCollection::erase(const std::string& name)
{
return _map.size();
_map.erase(name);
}


void NameValueCollection::erase(const std::string& name)
void NameValueCollection::erase(Iterator it)
{
_map.erase(name);
_map.erase(it);
}


Expand All @@ -169,6 +146,13 @@ void NameValueCollection::secureErase(const std::string& name)
}


void NameValueCollection::secureErase(Iterator it)
{
Poco::secureClear(it->second);
_map.erase(it);
}


void NameValueCollection::clear()
{
_map.clear();
Expand Down
43 changes: 43 additions & 0 deletions Net/testsuite/src/HTTPResponseTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,47 @@ void HTTPResponseTest::testCookies()
}


void HTTPResponseTest::testReplaceCookie()
{
HTTPResponse response;
HTTPCookie cookie1("cookie1", "value1");
response.replaceCookie(cookie1); // cookie does not exist, will add cookie
std::vector<HTTPCookie> cookies;
response.getCookies(cookies);
assertTrue (cookies.size() == 1);
assertTrue (cookie1.getName() == cookies[0].getName());
assertTrue (cookie1.getValue() == cookies[0].getValue());

HTTPCookie cookie1new("cookie1", "value2");
response.replaceCookie(cookie1new);
cookies.clear();
response.getCookies(cookies);
assertTrue (cookies.size() == 1);
assertTrue (cookie1new.getName() == cookies[0].getName());
assertTrue (cookie1new.getValue() == cookies[0].getValue());
}


void HTTPResponseTest::testRemoveCookie()
{
HTTPResponse response;
HTTPCookie cookie1("cookie1", "value1");
response.addCookie(cookie1);
std::vector<HTTPCookie> cookies;
response.getCookies(cookies);
assertTrue (cookies.size() == 1);
assertTrue (cookie1.getName() == cookies[0].getName());
assertTrue (cookie1.getValue() == cookies[0].getValue());

response.removeCookie("cookie1");
cookies.clear();
response.getCookies(cookies);
assertTrue (cookies.size() == 0);

response.removeCookie("cookie2"); // should do nothing
}


void HTTPResponseTest::setUp()
{
}
Expand All @@ -224,6 +265,8 @@ CppUnit::Test* HTTPResponseTest::suite()
CppUnit_addTest(pSuite, HTTPResponseTest, testInvalid2);
CppUnit_addTest(pSuite, HTTPResponseTest, testInvalid3);
CppUnit_addTest(pSuite, HTTPResponseTest, testCookies);
CppUnit_addTest(pSuite, HTTPResponseTest, testReplaceCookie);
CppUnit_addTest(pSuite, HTTPResponseTest, testRemoveCookie);

return pSuite;
}
2 changes: 2 additions & 0 deletions Net/testsuite/src/HTTPResponseTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class HTTPResponseTest: public CppUnit::TestCase
void testInvalid2();
void testInvalid3();
void testCookies();
void testReplaceCookie();
void testRemoveCookie();

void setUp();
void tearDown();
Expand Down

0 comments on commit 854d8c8

Please sign in to comment.