void CookieTest::OrderTest() { BNetworkCookieJar jar; status_t result; BUrl url("http://testsuites.opera.com/cookies/016.php"); result = jar.AddCookie("016-01=1", url); CPPUNIT_ASSERT(result == B_OK); url.SetUrlString("http://testsuites.opera.com/cookies/016/016-1.php"); result = jar.AddCookie("016-02=1", url); CPPUNIT_ASSERT(result == B_OK); url.SetUrlString("http://testsuites.opera.com/cookies/016/016-2.php"); BNetworkCookieJar::UrlIterator it = jar.GetUrlIterator(url); int count = 0; // Check that the cookie with the most specific path is sent first while (it.HasNext()) { const BNetworkCookie* cookie = it.Next(); switch(count) { case 0: CPPUNIT_ASSERT_EQUAL(BString("016-02"), cookie->Name()); break; case 1: CPPUNIT_ASSERT_EQUAL(BString("016-01"), cookie->Name()); break; } count++; } CPPUNIT_ASSERT_EQUAL(2, count); }
void CookieTest::OverwriteTest() { BNetworkCookieJar jar; status_t result; BUrl url("http://testsuites.opera.com/cookies/015/015.php"); result = jar.AddCookie("015-01=1", url); CPPUNIT_ASSERT(result == B_OK); url.SetUrlString("http://testsuites.opera.com/cookies/015-1.php"); result = jar.AddCookie("015-01=1", url); result = jar.AddCookie("015-02=1", url); CPPUNIT_ASSERT(result == B_OK); url.SetUrlString("http://testsuites.opera.com/cookies/015/015-2.php"); result = jar.AddCookie("015-01=1", url); result = jar.AddCookie("015-02=1", url); CPPUNIT_ASSERT(result == B_OK); url.SetUrlString("http://testsuites.opera.com/cookies/015/015-3.php"); BNetworkCookieJar::UrlIterator it = jar.GetUrlIterator(url); int count = 0; while (it.HasNext()) { it.Next(); count++; } CPPUNIT_ASSERT_EQUAL(4, count); }
const BNetworkCookie* CookieTest::_GetCookie(BNetworkCookieJar& jar, const BUrl& url, const char* name) { BNetworkCookieJar::UrlIterator it = jar.GetUrlIterator(url); const BNetworkCookie* result = NULL; while (it.HasNext()) { const BNetworkCookie* cookie = it.Next(); if (cookie->Name() == name) { // Make sure the cookie is found only once. CPPUNIT_ASSERT(result == NULL); result = cookie; } } return result; }
void BHttpRequest::_SendHeaders() { BHttpHeaders outputHeaders; // HTTP 1.1 additional headers if (fHttpVersion == B_HTTP_11) { BString host = Url().Host(); if (Url().HasPort() && !_IsDefaultPort()) host << ':' << Url().Port(); outputHeaders.AddHeader("Host", host); outputHeaders.AddHeader("Accept", "*/*"); outputHeaders.AddHeader("Accept-Encoding", "gzip"); // Allows the server to compress data using the "gzip" format. // "deflate" is not supported, because there are two interpretations // of what it means (the RFC and Microsoft products), and we don't // want to handle this. Very few websites support only deflate, // and most of them will send gzip, or at worst, uncompressed data. outputHeaders.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) outputHeaders.AddHeader("User-Agent", fOptUserAgent.String()); if (fOptReferer.CountChars() > 0) outputHeaders.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); outputHeaders.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; } outputHeaders.AddHeader("Content-Type", contentType); outputHeaders.AddHeader("Content-Length", fOptPostFields->ContentLength()); } else if (fOptInputData != NULL && (fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT)) { if (fOptInputDataSize >= 0) outputHeaders.AddHeader("Content-Length", fOptInputDataSize); else outputHeaders.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 = outputHeaders.HasHeader(optHeader.Name()); // Add or replace the current option header to the // output header list if (replaceIndex == -1) outputHeaders.AddHeader(optHeader.Name(), optHeader.Value()); else outputHeaders[replaceIndex].SetValue(optHeader.Value()); } } // Context cookies if (fOptSetCookies && fContext != NULL) { BString cookieString; BNetworkCookieJar::UrlIterator iterator = fContext->GetCookieJar().GetUrlIterator(fUrl); const BNetworkCookie* cookie = iterator.Next(); if (cookie != NULL) { while (true) { cookieString << cookie->RawCookie(false); cookie = iterator.Next(); if (cookie == NULL) break; cookieString << "; "; } outputHeaders.AddHeader("Cookie", cookieString); } } // Write output headers to output stream BString headerData; for (int32 headerIndex = 0; headerIndex < outputHeaders.CountHeaders(); headerIndex++) { const char* header = outputHeaders.HeaderAt(headerIndex).Header(); headerData << header; headerData << "\r\n"; _EmitDebug(B_URL_PROTOCOL_DEBUG_HEADER_OUT, "%s", header); } fSocket->Write(headerData.String(), headerData.Length()); }
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); } }
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"); // 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()); }