TryComputeLength() защищенный абстрактный Метод

protected abstract TryComputeLength ( long &length ) : bool
length long
Результат bool
Пример #1
0
        public async ValueTask <HttpResponseMessage> SendAsync(HttpRequestMessage request,
                                                               CancellationToken cancellationToken)
        {
            if (request.Version.Major != 1 || request.Version.Minor != 1)
            {
                throw new PlatformNotSupportedException($"Only HTTP 1.1 supported -- request.Version was {request.Version}");
            }

            HttpContent requestContent = request.Content;

            // Add headers to define content transfer, if not present
            if (requestContent != null &&
                request.Headers.TransferEncodingChunked != true &&
                requestContent.Headers.ContentLength == null)
            {
                // We have content, but neither Transfer-Encoding or Content-Length is set.
                // TODO: Tests expect Transfer-Encoding here always.
                // This seems wrong to me; if we can compute the content length,
                // why not use it instead of falling back to Transfer-Encoding?
#if false
                if (requestContent.TryComputeLength(out contentLength))
                {
                    // We know the content length, so set the header
                    requestContent.Headers.ContentLength = contentLength;
                }
                else
#endif
                {
                    request.Headers.TransferEncodingChunked = true;
                }
            }

            // Add Host header, if not present
            if (request.Headers.Host == null)
            {
                Uri    uri        = request.RequestUri;
                string hostString = uri.Host;
                if (!uri.IsDefaultPort)
                {
                    hostString += ":" + uri.Port.ToString();
                }

                request.Headers.Host = hostString;
            }

            // Write request line
            await WriteStringAsync(request.Method.Method, cancellationToken).ConfigureAwait(false);
            await WriteCharAsync(' ', cancellationToken).ConfigureAwait(false);

            if (_usingProxy)
            {
                await WriteStringAsync(request.RequestUri.AbsoluteUri, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                await WriteStringAsync(request.RequestUri.PathAndQuery, cancellationToken).ConfigureAwait(false);
            }

            await WriteCharAsync(' ', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('H', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('T', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('T', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('P', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('/', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('1', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('.', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('1', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('\r', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('\n', cancellationToken).ConfigureAwait(false);

            // Write request headers
            await WriteHeadersAsync(request.Headers, cancellationToken).ConfigureAwait(false);

            if (requestContent == null)
            {
                // Write out Content-Length: 0 header to indicate no body,
                // unless this is a method that never has a body.
                if (request.Method != HttpMethod.Get &&
                    request.Method != HttpMethod.Head)
                {
                    await WriteStringAsync("Content-Length: 0\r\n", cancellationToken).ConfigureAwait(false);
                }
            }
            else
            {
                // Write content headers
                await WriteHeadersAsync(requestContent.Headers, cancellationToken).ConfigureAwait(false);
            }

            // CRLF for end of headers.
            await WriteCharAsync('\r', cancellationToken).ConfigureAwait(false);
            await WriteCharAsync('\n', cancellationToken).ConfigureAwait(false);

            // Write body, if any
            if (requestContent != null)
            {
                HttpContentWriteStream stream = (request.Headers.TransferEncodingChunked == true ?
                                                 (HttpContentWriteStream) new ChunkedEncodingWriteStream(this) :
                                                 (HttpContentWriteStream) new ContentLengthWriteStream(this));

                // TODO: CopyToAsync doesn't take a CancellationToken, how do we deal with Cancellation here?
                await request.Content.CopyToAsync(stream, _transportContext).ConfigureAwait(false);

                await stream.FinishAsync(cancellationToken).ConfigureAwait(false);
            }

            await FlushAsync(cancellationToken).ConfigureAwait(false);

            return(await ParseResponseAsync(request, cancellationToken).ConfigureAwait(false));
        }