private async Task WriteRequestAsync(Connection connection) { this.UpdateHeaders(); if (_httpWriteMode != HttpWriteMode.None) { if (_httpWriteMode == HttpWriteMode.Chunked) { _headers.AddInternal(HttpHeaderNames.TransferEncoding, ChunkedHeader); } else { if (_contentLength >= 0L) { _headers.SetInternal(HttpHeaderNames.ContentLength, _contentLength.ToString()); } } //100-continue ?? } //Accept-Encoding header var acceptEncodingValues = this.Accept ?? string.Empty; if ((_automaticDecompression & DecompressionMethods.GZip) != DecompressionMethods.None && acceptEncodingValues.IndexOf(GZipHeader, StringComparison.OrdinalIgnoreCase) < 0) { if ((_automaticDecompression & DecompressionMethods.Deflate) != 0 && acceptEncodingValues.IndexOf(DeflateHeader, StringComparison.OrdinalIgnoreCase) < 0) { _headers.AddInternal(HttpHeaderNames.AcceptEncoding, GZipHeader + ", " + DeflateHeader); } else { _headers.AddInternal(HttpHeaderNames.AcceptEncoding, GZipHeader); } } else { if ((_automaticDecompression & DecompressionMethods.Deflate) != DecompressionMethods.None && acceptEncodingValues.IndexOf("deflate", StringComparison.OrdinalIgnoreCase) < 0) { _headers.AddInternal(HttpHeaderNames.AcceptEncoding, DeflateHeader); } } if (_keepAlive) { _headers.SetInternal(HttpHeaderNames.Connection, "Keep-Alive"); } else { _headers.SetInternal(HttpHeaderNames.Connection, "Close"); } var requestHeadersString = _headers.ToString(); string requestLine = null; if (this.UsesProxySemantics) { requestLine = this.GenerateProxyRequestLine(); } else { requestLine = this.GenerateRequestLine(); } // Request-Line = Method SP Request-URI SP HTTP-Version CRLF // i.e. GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1\r\n var writeBytesCount = requestHeadersString.Length + requestLine.Length + RequestLineConstantSize; byte[] writeBuffer = null; var usePooledBuffer = false; var offset = 0; if (connection.Buffer.Length >= writeBytesCount) { writeBuffer = connection.Buffer.Array; offset = connection.Buffer.Offset; usePooledBuffer = true; } else { writeBuffer = new byte[writeBytesCount]; } offset += Encoding.ASCII.GetBytes(requestLine, 0, requestLine.Length, writeBuffer, offset); Buffer.BlockCopy(HttpBytes, 0, writeBuffer, offset, HttpBytes.Length); offset += HttpBytes.Length; writeBuffer[offset++] = (byte)(_version == HttpVersion.HTTP20 ? '2' : '1'); writeBuffer[offset++] = (byte)'.'; writeBuffer[offset++] = (byte)(_version == HttpVersion.HTTP20 ? '0' : '1'); writeBuffer[offset++] = (byte)'\r'; writeBuffer[offset++] = (byte)'\n'; Encoding.UTF8.GetBytes(requestHeadersString, 0, requestHeadersString.Length, writeBuffer, offset); offset += requestHeadersString.Length; //transfer data var beginReadIndex = 0; var leftWriteBytes = writeBytesCount; while (leftWriteBytes > 0) { var count = Math.Min(writeBytesCount - beginReadIndex, connection.Buffer.Length); if (!usePooledBuffer) { Buffer.BlockCopy(writeBuffer, beginReadIndex, connection.Buffer.Array, connection.Buffer.Offset, count); } var writeBytes = await connection.WritePooledBufferAsync(connection.Buffer.Offset + beginReadIndex, count); leftWriteBytes -= writeBytes; beginReadIndex += writeBytes; } if (_method.AllowRequestContent && _submitContent != null) { using (_submitContent) { await _submitContent.CopyToAsync(new ConnectStream(connection, this)); _submitContent = null; } } }