private static void SetRequestHeaders(HttpWebRequest webRequest, HttpRequestMessage request) { WebHeaderCollection webRequestHeaders = webRequest.Headers; HttpRequestHeaders headers = request.Headers; // Most headers are just added directly to HWR's internal headers collection. But there are some exceptions // requiring different handling. // The following bool vars are used to skip string comparison when not required: E.g. if the 'Host' header // was not set, we don't need to compare every header in the collection with 'Host' to make sure we don't // add it to HWR's header collection. bool isHostSet = headers.Contains(HttpKnownHeaderNames.Host); bool isExpectSet = headers.Contains(HttpKnownHeaderNames.Expect); bool isTransferEncodingSet = headers.Contains(HttpKnownHeaderNames.TransferEncoding); bool isConnectionSet = headers.Contains(HttpKnownHeaderNames.Connection); if (isHostSet) { string host = headers.Host; if (host != null) { webRequest.Host = host; } } // The following headers (Expect, Transfer-Encoding, Connection) have both a collection property and a // bool property indicating a special value. Internally (in HttpHeaders) we don't distinguish between // "special" values and other values. So we must make sure that we add all but the special value to HWR. // E.g. the 'Transfer-Encoding: chunked' value must be set using HWR.SendChunked, whereas all other values // can be added to the 'Transfer-Encoding'. if (isExpectSet) { string expectHeader = headers.Expect.GetHeaderStringWithoutSpecial(); // Was at least one non-special value set? if (!String.IsNullOrEmpty(expectHeader) || !headers.Expect.IsSpecialValueSet) { webRequestHeaders.AddInternal(HttpKnownHeaderNames.Expect, expectHeader); } } if (isTransferEncodingSet) { string transferEncodingHeader = headers.TransferEncoding.GetHeaderStringWithoutSpecial(); // Was at least one non-special value set? if (!String.IsNullOrEmpty(transferEncodingHeader) || !headers.TransferEncoding.IsSpecialValueSet) { webRequestHeaders.AddInternal(HttpKnownHeaderNames.TransferEncoding, transferEncodingHeader); } } if (isConnectionSet) { string connectionHeader = headers.Connection.GetHeaderStringWithoutSpecial(); // Was at least one non-special value set? if (!String.IsNullOrEmpty(connectionHeader) || !headers.Connection.IsSpecialValueSet) { webRequestHeaders.AddInternal(HttpKnownHeaderNames.Connection, connectionHeader); } } foreach (var header in request.Headers.GetHeaderStrings()) { string headerName = header.Key; if ((isHostSet && AreEqual(HttpKnownHeaderNames.Host, headerName)) || (isExpectSet && AreEqual(HttpKnownHeaderNames.Expect, headerName)) || (isTransferEncodingSet && AreEqual(HttpKnownHeaderNames.TransferEncoding, headerName)) || (isConnectionSet && AreEqual(HttpKnownHeaderNames.Connection, headerName))) { continue; // Header was already added. } // Use AddInternal() to skip validation. webRequestHeaders.AddInternal(header.Key, header.Value); } }