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());
}
Пример #2
0
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);
	}
}