status_t BNetworkCookieJar::AddCookie(BNetworkCookie* cookie) { if (cookie == NULL) return B_BAD_VALUE; HashString key(cookie->Domain()); BNetworkCookieList* list = fCookieHashMap->fHashMap.Get(key); if (list == NULL) { list = new(std::nothrow) BNetworkCookieList(); if (list == NULL || fCookieHashMap->fHashMap.Put(key, list) != B_OK) return B_NO_MEMORY; } for (int32 i = 0; i < list->CountItems(); i++) { BNetworkCookie* c = reinterpret_cast<BNetworkCookie*>(list->ItemAt(i)); if (c->Name() == cookie->Name() && c->Path() == cookie->Path()) { list->RemoveItem(i); break; } } if (cookie->ShouldDeleteNow()) delete cookie; else list->AddItem(cookie); return B_OK; }
uint32 BNetworkCookieJar::PurgeForExit() { int32 deleteCount = 0; BNetworkCookie* cookiePtr; for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) { if (cookiePtr->ShouldDeleteAtExit()) { delete it.Remove(); deleteCount++; } } return deleteCount; }
uint32 BNetworkCookieJar::DeleteOutdatedCookies() { int32 deleteCount = 0; BNetworkCookie* cookiePtr; for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) { if (cookiePtr->ShouldDeleteNow()) { delete it.Remove(); deleteCount++; } } return deleteCount; }
status_t BNetworkCookieJar::Archive(BMessage* into, bool deep) const { status_t error = BArchivable::Archive(into, deep); if (error == B_OK) { BNetworkCookie* cookiePtr; for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) { BMessage subArchive; error = cookiePtr->Archive(&subArchive, deep); if (error != B_OK) return error; error = into->AddMessage(kArchivedCookieMessageName, &subArchive); if (error != B_OK) return error; } } return error; }
void BNetworkCookieJar::_DoFlatten() const { fFlattened.Truncate(0); BNetworkCookie* cookiePtr; for (Iterator it = GetIterator(); (cookiePtr = it.Next()) != NULL;) { fFlattened << cookiePtr->Domain() << '\t' << "TRUE" << '\t' << cookiePtr->Path() << '\t' << (cookiePtr->Secure()?"TRUE":"FALSE") << '\t' << (int32)cookiePtr->ExpirationDate() << '\t' << cookiePtr->Name() << '\t' << cookiePtr->Value() << '\n'; } }
CookieRow(BColumnListView* list, const BNetworkCookie& cookie) : BRow(), fCookie(cookie) { list->AddRow(this); SetField(new BStringField(cookie.Name().String()), 0); SetField(new BStringField(cookie.Path().String()), 1); time_t expiration = cookie.ExpirationDate(); SetField(new BDateField(&expiration), 2); SetField(new BStringField(cookie.Value().String()), 3); BString flags; if (cookie.Secure()) flags = "https "; if (cookie.HttpOnly()) flags = "http "; if (cookie.IsHostOnly()) flags += "hostOnly"; SetField(new BStringField(flags.String()), 4); }
void BUrlProtocolHttp::_AddHeaders() { // HTTP 1.1 additional headers if (fHttpVersion == B_HTTP_11) { fOutputHeaders.AddHeader("Host", Url().Host()); fOutputHeaders.AddHeader("Accept", "*/*"); fOutputHeaders.AddHeader("Accept-Encoding", "chunked"); // Allow the remote server to send dynamic content by chunks // rather than waiting for the full content to be generated and // sending us data. fOutputHeaders.AddHeader("Connection", "close"); // Let the remote server close the connection after response since // we don't handle multiple request on a single connection } // Classic HTTP headers if (fOptUserAgent.CountChars() > 0) fOutputHeaders.AddHeader("User-Agent", fOptUserAgent.String()); if (fOptReferer.CountChars() > 0) fOutputHeaders.AddHeader("Referer", fOptReferer.String()); // Authentication if (fAuthentication.Method() != B_HTTP_AUTHENTICATION_NONE) { BString request; switch (fRequestMethod) { case B_HTTP_POST: request = "POST"; break; case B_HTTP_PUT: request = "PUT"; break; default: case B_HTTP_GET: request = "GET"; break; } fOutputHeaders.AddHeader("Authorization", fAuthentication.Authorization(fUrl, request)); } // Required headers for POST data if (fOptPostFields != NULL && fRequestMethod == B_HTTP_POST) { BString contentType; switch (fOptPostFields->GetFormType()) { case B_HTTP_FORM_MULTIPART: contentType << "multipart/form-data; boundary=" << fOptPostFields->GetMultipartBoundary() << ""; break; case B_HTTP_FORM_URL_ENCODED: contentType << "application/x-www-form-urlencoded"; break; } fOutputHeaders.AddHeader("Content-Type", contentType); fOutputHeaders.AddHeader("Content-Length", fOptPostFields->ContentLength()); } else if (fOptInputData != NULL && (fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT)) fOutputHeaders.AddHeader("Transfer-Encoding", "chunked"); // Request headers for (int32 headerIndex = 0; headerIndex < fRequestHeaders.CountHeaders(); headerIndex++) { BHttpHeader& optHeader = fRequestHeaders[headerIndex]; int32 replaceIndex = fOutputHeaders.HasHeader(optHeader.Name()); // Add or replace the current option header to the // output header list if (replaceIndex == -1) fOutputHeaders.AddHeader(optHeader.Name(), optHeader.Value()); else fOutputHeaders[replaceIndex].SetValue(optHeader.Value()); } // Optional headers specified by the user if (fOptHeaders != NULL) { for (int32 headerIndex = 0; headerIndex < fOptHeaders->CountHeaders(); headerIndex++) { BHttpHeader& optHeader = (*fOptHeaders)[headerIndex]; int32 replaceIndex = fOutputHeaders.HasHeader(optHeader.Name()); // Add or replace the current option header to the // output header list if (replaceIndex == -1) fOutputHeaders.AddHeader(optHeader.Name(), optHeader.Value()); else fOutputHeaders[replaceIndex].SetValue(optHeader.Value()); } } // Context cookies if (fOptSetCookies && (fContext != NULL)) { BNetworkCookie* cookie; for (BNetworkCookieJar::UrlIterator it(fContext->GetCookieJar().GetUrlIterator(fUrl)); (cookie = it.Next()) != NULL; ) fOutputHeaders.AddHeader("Cookie", cookie->RawCookie(false)); } // Write output headers to output stream for (int32 headerIndex = 0; headerIndex < fOutputHeaders.CountHeaders(); headerIndex++) _AddOutputBufferLine(fOutputHeaders.HeaderAt(headerIndex).Header()); }
void BHttpRequest::_SendHeaders() { // HTTP 1.1 additional headers if (fHttpVersion == B_HTTP_11) { fOutputHeaders.AddHeader("Host", Url().Host()); fOutputHeaders.AddHeader("Accept", "*/*"); fOutputHeaders.AddHeader("Accept-Encoding", "gzip,deflate"); // Allow the remote server to send dynamic content by chunks // rather than waiting for the full content to be generated and // sending us data. fOutputHeaders.AddHeader("Connection", "close"); // Let the remote server close the connection after response since // we don't handle multiple request on a single connection } // Classic HTTP headers if (fOptUserAgent.CountChars() > 0) fOutputHeaders.AddHeader("User-Agent", fOptUserAgent.String()); if (fOptReferer.CountChars() > 0) fOutputHeaders.AddHeader("Referer", fOptReferer.String()); // Authentication if (fContext != NULL) { BHttpAuthentication& authentication = fContext->GetAuthentication(fUrl); if (authentication.Method() != B_HTTP_AUTHENTICATION_NONE) { if (fOptUsername.Length() > 0) { authentication.SetUserName(fOptUsername); authentication.SetPassword(fOptPassword); } BString request(fRequestMethod); fOutputHeaders.AddHeader("Authorization", authentication.Authorization(fUrl, request)); } } // Required headers for POST data if (fOptPostFields != NULL && fRequestMethod == B_HTTP_POST) { BString contentType; switch (fOptPostFields->GetFormType()) { case B_HTTP_FORM_MULTIPART: contentType << "multipart/form-data; boundary=" << fOptPostFields->GetMultipartBoundary() << ""; break; case B_HTTP_FORM_URL_ENCODED: contentType << "application/x-www-form-urlencoded"; break; } fOutputHeaders.AddHeader("Content-Type", contentType); fOutputHeaders.AddHeader("Content-Length", fOptPostFields->ContentLength()); } else if (fOptInputData != NULL && (fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT)) { if (fOptInputDataSize >= 0) fOutputHeaders.AddHeader("Content-Length", fOptInputDataSize); else fOutputHeaders.AddHeader("Transfer-Encoding", "chunked"); } // Optional headers specified by the user if (fOptHeaders != NULL) { for (int32 headerIndex = 0; headerIndex < fOptHeaders->CountHeaders(); headerIndex++) { BHttpHeader& optHeader = (*fOptHeaders)[headerIndex]; int32 replaceIndex = fOutputHeaders.HasHeader(optHeader.Name()); // Add or replace the current option header to the // output header list if (replaceIndex == -1) fOutputHeaders.AddHeader(optHeader.Name(), optHeader.Value()); else fOutputHeaders[replaceIndex].SetValue(optHeader.Value()); } } // Context cookies if (fOptSetCookies && fContext != NULL) { BString cookieString; BNetworkCookieJar::UrlIterator iterator = fContext->GetCookieJar().GetUrlIterator(fUrl); BNetworkCookie* cookie = iterator.Next(); if (cookie != NULL) { while (true) { cookieString << cookie->RawCookie(false); cookie = iterator.Next(); if (cookie == NULL) break; cookieString << "; "; } fOutputHeaders.AddHeader("Cookie", cookieString); } } // Write output headers to output stream for (int32 headerIndex = 0; headerIndex < fOutputHeaders.CountHeaders(); headerIndex++) { const char* header = fOutputHeaders.HeaderAt(headerIndex).Header(); fSocket->Write(header, strlen(header)); fSocket->Write("\r\n", 2); _EmitDebug(B_URL_PROTOCOL_DEBUG_HEADER_OUT, "%s", header); } }
status_t BNetworkCookieJar::Unflatten(type_code, const void* buffer, ssize_t size) { BString flattenedCookies; flattenedCookies.SetTo(reinterpret_cast<const char*>(buffer), size); while (flattenedCookies.Length() > 0) { BNetworkCookie tempCookie; BString tempCookieLine; int32 endOfLine = flattenedCookies.FindFirst('\n', 0); if (endOfLine == -1) tempCookieLine = flattenedCookies; else { flattenedCookies.MoveInto(tempCookieLine, 0, endOfLine); flattenedCookies.Remove(0, 1); } if (tempCookieLine.Length() != 0 && tempCookieLine[0] != '#') { for (int32 field = 0; field < 7; field++) { BString tempString; int32 endOfField = tempCookieLine.FindFirst('\t', 0); if (endOfField == -1) tempString = tempCookieLine; else { tempCookieLine.MoveInto(tempString, 0, endOfField); tempCookieLine.Remove(0, 1); } switch (field) { case 0: tempCookie.SetDomain(tempString); break; case 1: // TODO: Useless field ATM break; case 2: tempCookie.SetPath(tempString); break; case 3: tempCookie.SetSecure(tempString == "TRUE"); break; case 4: tempCookie.SetExpirationDate(atoi(tempString)); break; case 5: tempCookie.SetName(tempString); break; case 6: tempCookie.SetValue(tempString); break; } // switch } // for loop AddCookie(tempCookie); } } return B_OK; }
void CookieTest::ExplodeTest() { struct Test { const char* cookieString; const char* url; struct { bool valid; const char* name; const char* value; const char* domain; const char* path; bool secure; bool httponly; bool session; BDateTime expire; } expected; }; Test tests[] = { // Cookie string URL // ------------- ------------- // Valid Name Value Domain Path Secure HttpOnly Session Expiration // --------- -------- --------- ----------------- --------- -------- -------- ------- ---------- // Normal cookies { "name=value", "http://www.example.com/path/path", { true, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } }, { "name=value; domain=example.com; path=/; secure", "http://www.example.com/path/path", { true, "name", "value", "example.com", "/" , true, false, true, BDateTime() } }, { "name=value; httponly; secure", "http://www.example.com/path/path", { true, "name", "value", "www.example.com", "/path", true, true, true, BDateTime() } }, { "name=value; expires=Wed, 20-Feb-2013 20:00:00 UTC", "http://www.example.com/path/path", { true, "name", "value", "www.example.com", "/path", false, false, false, BDateTime(BDate(2013, 2, 20), BTime(20, 0, 0, 0)) } }, // Valid cookie with bad form { "name= ; domain =example.com ;path=/; secure = yup ; blahblah ;)", "http://www.example.com/path/path", { true, "name", "", "example.com", "/" , true, false, true, BDateTime() } }, // Invalid path { "name=value; path=invalid", "http://www.example.com/path/path", { false, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } }, // Setting for other subdomain (invalid) { "name=value; domain=subdomain.example.com", "http://www.example.com/path/path", { false, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } }, // Various invalid cookies { "name", "http://www.example.com/path/path", { false, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } }, { "; domain=example.com", "http://www.example.com/path/path", { false, "name", "value", "www.example.com", "/path", false, false, true, BDateTime() } } }; BNetworkCookie cookie; for (uint32 i = 0; i < (sizeof(tests) / sizeof(Test)); i++) { NextSubTest(); BUrl url(tests[i].url); cookie.ParseCookieString(tests[i].cookieString, url); CPPUNIT_ASSERT(tests[i].expected.valid == cookie.IsValid()); if (!tests[i].expected.valid) continue; CPPUNIT_ASSERT_EQUAL(BString(tests[i].expected.name), cookie.Name()); CPPUNIT_ASSERT_EQUAL(BString(tests[i].expected.value), cookie.Value()); CPPUNIT_ASSERT_EQUAL(BString(tests[i].expected.domain), cookie.Domain()); CPPUNIT_ASSERT_EQUAL(BString(tests[i].expected.path), cookie.Path()); CPPUNIT_ASSERT(tests[i].expected.secure == cookie.Secure()); CPPUNIT_ASSERT(tests[i].expected.httponly == cookie.HttpOnly()); CPPUNIT_ASSERT(tests[i].expected.session == cookie.IsSessionCookie()); if (!cookie.IsSessionCookie()) CPPUNIT_ASSERT_EQUAL(tests[i].expected.expire.Time_t(), cookie.ExpirationDate()); } }
void CookieTest::PathMatchingTest() { const BUrl url("http://testsuites.opera.com/cookies/302/302.php"); const BUrl url1("http://testsuites.opera.com/cookies/302-5.php"); const BUrl url2("http://testsuites.opera.com/cookies/302/302-3.php"); const BUrl url3("http://testsuites.opera.com/cookies/302/sub/302-4.php"); const BUrl url4("http://testsuites.opera.com/cookies/302-2/302-6.php"); BNetworkCookie cookie; status_t result; BString bigData("302-24=1; Path=\"/cookies/302/"); for (int i = 0; i < 1500; i++) bigData << "abcdefghijklmnopqrstuvwxyz"; bigData << "\";"; struct Test { const char* cookieString; bool canSet; bool url1; bool url2; bool url3; bool url4; }; const Test tests[] = { { "302-01=1; Path=\"/\"", true, true, true, true, true }, { "302-02=1; Path=\"/cookies\"", true, true, true, true, true }, { "302-03=1; Path=\"/cookies/\"", true, true, true, true, true }, { "302-04=1; Path=\"/cookies/302\"", true, false, true, true, true }, { "302-05=1; Path=\"/cookies/302/\"", true, false, true, true, false }, { "302-06=1; Path=\"/cookies/302/.\"", false, false, false, false, false }, { "302-07=1; Path=\"/cookies/302/../302\"", false, false, false, false, false }, { "302-08=1; Path=\"/cookies/302/../302-2\"", false, false, false, false, false }, { "302-09=1; Path=\"/side\"", false, false, false, false, false }, { "302-10=1; Path=\"/cookies/302-2\"", true, false, false, false, true }, { "302-11=1; Path=\"/cookies/302-2/\"", true, false, false, false, true }, { "302-12=1; Path=\"sub\"", false, false, false, false, false }, { "302-13=1; Path=\"sub/\"", false, false, false, false, false }, { "302-14=1; Path=\".\"", false, false, false, false, false }, { "302-15=1; Path=\"/cookies/302/sub\"", true, false, false, true, false }, { "302-16=1; Path=\"/cookies/302/sub/\"", true, false, false, true, false }, { "302-17=1; Path=\"/cookies/302/sub/..\"", false, false, false, false, false }, { "302-18=1; Path=/", true, true, true, true, true }, { "302-19=1; Path=/ /", false, false, false, false, false }, { "302-20=1; Path=\"/", false, false, false, false, false }, { "302-21=1; Path=/\"", false, false, false, false, false }, { "302-22=1; Path=\\/", false, false, false, false, false }, { "302-23=1; Path=\n/", false, false, false, false, false }, { bigData, false, false, false, false, false }, }; for (unsigned int i = 0; i < sizeof(tests) / sizeof(Test); i++) { NextSubTest(); result = cookie.ParseCookieString(tests[i].cookieString, url); CPPUNIT_ASSERT_EQUAL_MESSAGE("Allowed to set cookie", tests[i].canSet, result == B_OK); CPPUNIT_ASSERT_EQUAL(tests[i].url1, cookie.IsValidForUrl(url1)); CPPUNIT_ASSERT_EQUAL(tests[i].url2, cookie.IsValidForUrl(url2)); CPPUNIT_ASSERT_EQUAL(tests[i].url3, cookie.IsValidForUrl(url3)); CPPUNIT_ASSERT_EQUAL(tests[i].url4, cookie.IsValidForUrl(url4)); } }
void CookieTest::ExpireParsingTest() { BUrl url("http://testsuites.opera.com/cookies/301.php"); BNetworkCookie cookie; status_t result; BString bigData("301-16=1; Expires=\""); for (int i = 0; i < 1500; i++) bigData << "abcdefghijklmnopqrstuvwxyz"; bigData << "\";"; struct Test { const char* cookieString; bool canParse; bool sessionOnly; bool expired; }; Test tests[] = { { "301-01=1; Expires=\"notAValidValue\";", true, true, false }, // Obviously invalid date { "301-02=1; Expires=\"Wed, 08-Nov-2035 01:04:33\";", true, false, false }, // Valid date { "301-03=1; Expires=\"Tue, 19-Jan-2038 03:14:06\";", true, false, false }, // Valid date, after year 2038 time_t overflow { "301-04=1; Expires=\"Fri, 13-Dec-1901 20:45:51\";", true, false, true }, // Valid date, in the past { "301-05=1; Expires=\"Thu, 33-Nov-2035 01:04:33\";", true, true, false }, // Invalid day { "301-06=1; Expires=\"Wed, 08-Siz-2035 01:04:33\";", true, true, false }, // Invalid month { "301-07=1; Expires=\"Wed, 08-Nov-9035 01:04:33\";", true, false, false }, // Very far in the future // NOTE: Opera testsuite considers it should be a session cookie. { "301-08=1; Expires=\"Wed, 08-Nov-2035 75:04:33\";", true, true, false }, // Invalid hour { "301-09=1; Expires=\"Wed, 08-Nov-2035 01:75:33\";", true, true, false }, // Invalid minute { "301-10=1; Expires=\"Wed, 08-Nov-2035 01:04:75\";", true, true, false }, // Invalid second { "301-11=1; Expires=\"XXX, 08-Nov-2035 01:04:33\";", true, true, false }, // Invalid weekday { "301-12=1; Expires=\"Thu, XX-Nov-2035 01:04:33\";", true, true, false }, // Non-digit day { "301-13=1; Expires=\"Thu, 08-Nov-XXXX 01:04:33\";", true, true, false }, // Non-digit year { "301-14=1; Expires=\"Thu, 08-Nov-2035 XX:XX:33\";", true, true, false }, // Non-digit hour and minute { "301-15=1; Expires=\"Thu, 08-Nov-2035 01:04:XX\";", true, true, false }, // Non-digit second { bigData.String(), true, true, false }, // Very long invalid string // NOTE: Opera doesn't register the cookie at all. { "301-17=1; Expires=\"Thu, 99999-Nov-2035 01:04:33\";", true, true, false }, // Day with many digits { "301-18=1; Expires=\"Thu, 25-Nov-99999 01:04:33\";", true, true, false }, // Year with many digits // NOTE: Opera tests 301-17 twice and misses this test. { "301-19=1; Expires=\"Thu, 25-Nov-2035 99999:04:33\";", true, true, false }, // Hour with many digits { "301-20=1; Expires=\"Thu, 25-Nov-2035 01:99999:33\";", true, true, false }, // Minute with many digits { "301-21=1; Expires=\"Thu, 25-Nov-2035 01:04:99999\";", true, true, false }, // Second with many digits { "301-22=1; Expires=\"99999999999999999999\";", true, true, false }, // Huge number { "301-23=1; Expires=\"Fri, 13-Dec-101 20:45:51\";", true, false, true }, // Very far in the past { "301-24=1; EXPiReS=\"Wed, 08-Nov-2035 01:04:33\";", true, false, false }, // Case insensitive key parsing { "301-25=1; Expires=Wed, 08-Nov-2035 01:04:33\";", true, true, false }, // Missing opening quote // NOTE: unlike Opera, we accept badly quoted values for cookie // attributes. This allows to handle unquoted values from the early // cookie spec properly. However, a date with a quote inside it // should not be accepted, so this will be a session cookie. { "301-26=1; Expires=\"Wed, 08-Nov-2035 01:04:33;", true, true, false }, // Missing closing quote { "301-27=1; Expires:\"Wed, 08-Nov-2035 01:04:33\";", true, true, false }, // Uses : instead of = // NOTE: unlike Opera, we allow this as a cookie with a strange // name and no value { "301-28=1; Expires;=\"Wed, 08-Nov-2035 01:04:33\";", true, true, false }, // Extra ; after name { "301-29=1; Expired=\"Wed, 08-Nov-2035 01:04:33\";", true, true, false }, // Expired instead of Expires { "301-30=1; Expires=\"Wed; 08-Nov-2035 01:04:33\";", true, true, false }, // ; in value { "301-31=1; Expires=\"Wed,\\r\\n 08-Nov-2035 01:04:33\";", true, true, false }, // escaped newline in value // NOTE: Only here for completeness. This is what the Opera // testsuite sends in test 31, but I suspect they were trying to // test the following case. { "301-31b=1; Expires=\"Wed,\r\n 08-Nov-2035 01:04:33\";", true, false, false }, // newline in value // NOTE: This can't really happen when we get cookies from HTTP // headers. It could happen when the cookie is set from meta html // tags or from JS. }; for (unsigned int i = 0; i < sizeof(tests) / sizeof(Test); i++) { NextSubTest(); result = cookie.ParseCookieString(tests[i].cookieString, url); CPPUNIT_ASSERT_EQUAL_MESSAGE("Cookie can be parsed", tests[i].canParse, result == B_OK); CPPUNIT_ASSERT_EQUAL_MESSAGE("Cookie is session only", tests[i].sessionOnly, cookie.IsSessionCookie()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Cookie has expired", tests[i].expired, cookie.ShouldDeleteNow()); } }
void stressTest(int32 domainNumber, int32 totalCookies, char** flat, ssize_t* size) { char **domains = new char*[domainNumber]; cout << "Creating random domains" << endl; srand(time(NULL)); for (int32 i = 0; i < domainNumber; i++) { int16 charNum = (rand() % 16) + 1; domains[i] = new char[charNum + 5]; // Random domain for (int32 c = 0; c < charNum; c++) domains[i][c] = (rand() % 26) + 'a'; domains[i][charNum] = '.'; // Random tld for (int32 c = 0; c < 3; c++) domains[i][charNum+1+c] = (rand() % 26) + 'a'; domains[i][charNum+4] = 0; } BNetworkCookieJar j; BStopWatch* watch = new BStopWatch("Cookie insertion"); for (int32 i = 0; i < totalCookies; i++) { BNetworkCookie c; int16 domain = (rand() % domainNumber); BString name("Foo"); name << i; c.SetName(name); c.SetValue("Bar"); c.SetDomain(domains[domain]); c.SetPath("/"); j.AddCookie(c); } delete watch; BNetworkCookie* c; int16 domain = (rand() % domainNumber); BString host("http://"); host << domains[domain] << "/"; watch = new BStopWatch("Cookie filtering"); BUrl url(host); int32 count = 0; for (BNetworkCookieJar::UrlIterator it(j.GetUrlIterator(url)); (c = it.Next()); ) { //for (BNetworkCookieJar::Iterator it(j.GetIterator()); c = it.Next(); ) { count++; } delete watch; cout << "Count for " << host << ": " << count << endl; cout << "Flat view of cookie jar is " << j.FlattenedSize() << " bytes large." << endl; *flat = new char[j.FlattenedSize()]; *size = j.FlattenedSize(); if (j.Flatten(*flat, j.FlattenedSize()) == B_OK) cout << "Flatten() success!" << endl; else cout << "Flatten() error!" << endl; delete[] domains; }
void explodeImplodeTest() { uint8 testIndex; BNetworkCookie cookie; for (testIndex = 0; testIndex < (sizeof(kTestExplode) / sizeof(ExplodeTest)); testIndex++) { cookie.ParseCookieString(kTestExplode[testIndex].cookieString); ASSERT(testIndex, BString(kTestExplode[testIndex].expected.name) == BString(cookie.Name())); ASSERT(testIndex, BString(kTestExplode[testIndex].expected.value) == BString(cookie.Value())); ASSERT(testIndex, BString(kTestExplode[testIndex].expected.domain) == BString(cookie.Domain())); ASSERT(testIndex, BString(kTestExplode[testIndex].expected.path) == BString(cookie.Path())); ASSERT(testIndex, kTestExplode[testIndex].expected.secure == cookie.Secure()); ASSERT(testIndex, kTestExplode[testIndex].expected.discard == cookie.Discard()); ASSERT(testIndex, kTestExplode[testIndex].expected.session == cookie.IsSessionCookie()); if (!cookie.IsSessionCookie()) ASSERT(testIndex, kTestExplode[testIndex].expected.maxAge == cookie.MaxAge()); } }