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); } }