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;
}
示例#2
0
status_t
BNetworkCookieJar::AddCookies(const BNetworkCookieList& cookies)
{
	for (int32 i = 0; i < cookies.CountItems(); i++) {
		const BNetworkCookie* cookiePtr = cookies.ItemAt(i);

		// Using AddCookie by reference in order to avoid multiple
		// cookie jar share the same cookie pointers
		status_t result = AddCookie(*cookiePtr);
		if (result != B_OK)
			return result;
	}

	return B_OK;
}
示例#3
0
BNetworkCookieJar::~BNetworkCookieJar()
{
	for (Iterator it = GetIterator(); it.Next() != NULL;) {
		delete it.Remove();
	}

	fCookieHashMap->Lock();

	PrivateHashMap::Iterator it = fCookieHashMap->GetIterator();
	while(it.HasNext()) {
		BNetworkCookieList* list = *it.NextValue();
		it.Remove();
		list->LockForWriting();
		delete list;
	}

	delete fCookieHashMap;
}
示例#4
0
status_t
BNetworkCookieJar::AddCookie(BNetworkCookie* cookie)
{
	if (fCookieHashMap == NULL)
		return B_NO_MEMORY;

	if (cookie == NULL || !cookie->IsValid())
		return B_BAD_VALUE;

	HashString key(cookie->Domain());

	if (!fCookieHashMap->Lock())
		return B_ERROR;

	// Get the cookies for the requested domain, or create a new list if there
	// isn't one yet.
	BNetworkCookieList* list = fCookieHashMap->Get(key);
	if (list == NULL) {
		list = new(std::nothrow) BNetworkCookieList();

		if (list == NULL) {
			fCookieHashMap->Unlock();
			return B_NO_MEMORY;
		}

		if (fCookieHashMap->Put(key, list) != B_OK) {
			fCookieHashMap->Unlock();
			delete list;
			return B_NO_MEMORY;
		}
	}

	if (list->LockForWriting() != B_OK) {
		fCookieHashMap->Unlock();
		return B_ERROR;
	}

	fCookieHashMap->Unlock();

	// Remove any cookie with the same key as the one we're trying to add (it
	// replaces/updates them)
	for (int32 i = 0; i < list->CountItems(); i++) {
		const BNetworkCookie* c = list->ItemAt(i);

		if (c->Name() == cookie->Name() && c->Path() == cookie->Path()) {
			list->RemoveItemAt(i);
			break;
		}
	}

	// If the cookie has an expiration date in the past, stop here: we
	// effectively deleted a cookie.
	if (cookie->ShouldDeleteNow()) {
		TRACE("Remove cookie: %s\n", cookie->RawCookie(true).String());
		delete cookie;
	} else {
		// Make sure the cookie has cached the raw string and expiration date
		// string, so it is now actually immutable. This way we can safely
		// read the cookie data from multiple threads without any locking.
		const BString& raw = cookie->RawCookie(true);
		(void)raw;

		TRACE("Add cookie: %s\n", raw.String());

		// Keep the list sorted by path length (longest first). This makes sure
		// that cookies for most specific paths are returned first when
		// iterating the cookie jar.
		int32 i;
		for (i = 0; i < list->CountItems(); i++) {
			const BNetworkCookie* current = list->ItemAt(i);
			if (current->Path().Length() < cookie->Path().Length())
				break;
		}
		list->AddItem(cookie, i);
	}

	list->Unlock();

	return B_OK;
}