├── .DS_Store
├── LICENSE
├── README.md
├── assembly
├── unix-arm64
│ └── System.Net.Http.dll
├── unix-x64
│ └── System.Net.Http.dll
└── windows-x64
│ └── System.Net.Http.dll
├── docker
├── .DS_Store
├── unix-arm64
│ ├── Dockerfile
│ └── System.Net.Http.dll
├── unix-x64
│ ├── Dockerfile
│ └── System.Net.Http.dll
└── windows-x64
│ ├── Dockerfile
│ └── System.Net.Http.dll
└── src
└── System.Net.Http
├── .vs
└── System.Net.Http
│ ├── DesignTimeBuild
│ └── .dtbcache
│ └── v16
│ ├── .suo
│ └── Server
│ └── sqlite3
│ ├── db.lock
│ └── storage.ide
├── ConsoleApp1
├── ConsoleApp1.csproj
└── Program.cs
├── Directory.Build.props
├── System.Net.Http.sln
├── TestBypassSSL
├── Program.cs
└── TestBypassSSL.csproj
├── ref
├── Configurations.props
├── System.Net.Http.cs
└── System.Net.Http.csproj
├── src
├── Configurations.props
├── HttpDiagnosticsGuide.md
├── ILLinkTrim.xml
├── MatchingRefApiCompatBaseline.uap.txt
├── Resources
│ └── Strings.resx
├── System.Net.Http.csproj
├── System
│ └── Net
│ │ └── Http
│ │ ├── ByteArrayContent.cs
│ │ ├── ByteArrayHelpers.cs
│ │ ├── ClientCertificateOption.cs
│ │ ├── CurlHandler
│ │ ├── CurlException.cs
│ │ ├── CurlHandler.ClientCertificateProvider.cs
│ │ ├── CurlHandler.CurlResponseMessage.cs
│ │ ├── CurlHandler.EasyRequest.cs
│ │ ├── CurlHandler.MultiAgent.cs
│ │ ├── CurlHandler.SslProvider.Linux.cs
│ │ ├── CurlHandler.SslProvider.OSX.cs
│ │ ├── CurlHandler.cs
│ │ └── CurlResponseHeaderReader.cs
│ │ ├── DelegatingHandler.cs
│ │ ├── DiagnosticsHandler.cs
│ │ ├── DiagnosticsHandlerLoggingStrings.cs
│ │ ├── FormUrlEncodedContent.cs
│ │ ├── Headers
│ │ ├── AuthenticationHeaderValue.cs
│ │ ├── BaseHeaderParser.cs
│ │ ├── ByteArrayHeaderParser.cs
│ │ ├── CacheControlHeaderParser.cs
│ │ ├── CacheControlHeaderValue.cs
│ │ ├── ContentDispositionHeaderValue.cs
│ │ ├── ContentRangeHeaderValue.cs
│ │ ├── DateHeaderParser.cs
│ │ ├── EntityTagHeaderValue.cs
│ │ ├── GenericHeaderParser.cs
│ │ ├── HeaderDescriptor.cs
│ │ ├── HeaderUtilities.cs
│ │ ├── HttpContentHeaders.cs
│ │ ├── HttpGeneralHeaders.cs
│ │ ├── HttpHeaderParser.cs
│ │ ├── HttpHeaderType.cs
│ │ ├── HttpHeaderValueCollection.cs
│ │ ├── HttpHeaders.cs
│ │ ├── HttpRequestHeaders.cs
│ │ ├── HttpResponseHeaders.cs
│ │ ├── Int32NumberHeaderParser.cs
│ │ ├── Int64NumberHeaderParser.cs
│ │ ├── KnownHeader.cs
│ │ ├── KnownHeaders.cs
│ │ ├── MediaTypeHeaderParser.cs
│ │ ├── MediaTypeHeaderValue.cs
│ │ ├── MediaTypeWithQualityHeaderValue.cs
│ │ ├── NameValueHeaderValue.cs
│ │ ├── NameValueWithParametersHeaderValue.cs
│ │ ├── ObjectCollection.cs
│ │ ├── ProductHeaderValue.cs
│ │ ├── ProductInfoHeaderParser.cs
│ │ ├── ProductInfoHeaderValue.cs
│ │ ├── RangeConditionHeaderValue.cs
│ │ ├── RangeHeaderValue.cs
│ │ ├── RangeItemHeaderValue.cs
│ │ ├── RetryConditionHeaderValue.cs
│ │ ├── StringWithQualityHeaderValue.cs
│ │ ├── TimeSpanHeaderParser.cs
│ │ ├── TransferCodingHeaderParser.cs
│ │ ├── TransferCodingHeaderValue.cs
│ │ ├── TransferCodingWithQualityHeaderValue.cs
│ │ ├── UriHeaderParser.cs
│ │ ├── ViaHeaderValue.cs
│ │ └── WarningHeaderValue.cs
│ │ ├── HttpClient.cs
│ │ ├── HttpClientHandler.Core.cs
│ │ ├── HttpClientHandler.Unix.cs
│ │ ├── HttpClientHandler.Windows.cs
│ │ ├── HttpClientHandler.cs
│ │ ├── HttpClientHandler.netcoreapp.cs
│ │ ├── HttpCompletionOption.cs
│ │ ├── HttpContent.cs
│ │ ├── HttpMessageHandler.cs
│ │ ├── HttpMessageInvoker.cs
│ │ ├── HttpMethod.cs
│ │ ├── HttpParseResult.cs
│ │ ├── HttpRequestException.cs
│ │ ├── HttpRequestMessage.cs
│ │ ├── HttpResponseMessage.cs
│ │ ├── HttpRuleParser.cs
│ │ ├── HttpUtilities.cs
│ │ ├── MessageProcessingHandler.cs
│ │ ├── MultipartContent.cs
│ │ ├── MultipartFormDataContent.cs
│ │ ├── NetEventSource.Http.cs
│ │ ├── ReadOnlyMemoryContent.cs
│ │ ├── SocketsHttpHandler
│ │ ├── ArrayBuffer.cs
│ │ ├── AuthenticationHelper.Digest.cs
│ │ ├── AuthenticationHelper.NtAuth.cs
│ │ ├── AuthenticationHelper.cs
│ │ ├── CancellationHelper.cs
│ │ ├── ChunkedEncodingReadStream.cs
│ │ ├── ChunkedEncodingWriteStream.cs
│ │ ├── ConnectHelper.cs
│ │ ├── ConnectionCloseReadStream.cs
│ │ ├── ContentLengthReadStream.cs
│ │ ├── ContentLengthWriteStream.cs
│ │ ├── CookieHelper.cs
│ │ ├── CreditManager.cs
│ │ ├── DecompressionHandler.cs
│ │ ├── EmptyReadStream.cs
│ │ ├── ExposedSocketNetworkStream.cs
│ │ ├── HPack
│ │ │ ├── DynamicTable.cs
│ │ │ ├── HPackDecoder.cs
│ │ │ ├── HPackDecodingException.cs
│ │ │ ├── HPackEncoder.cs
│ │ │ ├── HeaderField.cs
│ │ │ ├── Huffman.cs
│ │ │ ├── HuffmanDecodingException.cs
│ │ │ ├── IntegerDecoder.cs
│ │ │ ├── IntegerEncoder.cs
│ │ │ └── StaticTable.cs
│ │ ├── Http2Connection.cs
│ │ ├── Http2ConnectionException.cs
│ │ ├── Http2ProtocolErrorCode.cs
│ │ ├── Http2ProtocolException.cs
│ │ ├── Http2Stream.cs
│ │ ├── Http2StreamException.cs
│ │ ├── HttpAuthenticatedConnectionHandler.cs
│ │ ├── HttpBaseStream.cs
│ │ ├── HttpConnection.cs
│ │ ├── HttpConnectionBase.cs
│ │ ├── HttpConnectionHandler.cs
│ │ ├── HttpConnectionKind.cs
│ │ ├── HttpConnectionPool.cs
│ │ ├── HttpConnectionPoolManager.cs
│ │ ├── HttpConnectionResponseContent.cs
│ │ ├── HttpConnectionSettings.cs
│ │ ├── HttpContentReadStream.cs
│ │ ├── HttpContentStream.cs
│ │ ├── HttpContentWriteStream.cs
│ │ ├── HttpEnvironmentProxy.Unix.cs
│ │ ├── HttpEnvironmentProxy.Windows.cs
│ │ ├── HttpEnvironmentProxy.cs
│ │ ├── HttpNoProxy.cs
│ │ ├── HttpWindowsProxy.cs
│ │ ├── IHttpTrace.cs
│ │ ├── MacProxy.cs
│ │ ├── RawConnectionStream.cs
│ │ ├── RedirectHandler.cs
│ │ ├── SocketsHttpHandler.cs
│ │ ├── SystemProxyInfo.OSX.cs
│ │ ├── SystemProxyInfo.Unix.cs
│ │ ├── SystemProxyInfo.Windows.cs
│ │ ├── SystemProxyInfo.cs
│ │ ├── SystemProxyInfo.uap.cs
│ │ └── TaskCompletionSourceWithCancellation.cs
│ │ ├── StreamContent.cs
│ │ ├── StreamToStreamCopy.cs
│ │ └── StringContent.cs
└── uap
│ └── System
│ └── Net
│ ├── CookieHelper.cs
│ ├── HttpClientHandler.cs
│ ├── HttpHandlerToFilter.cs
│ ├── cookie.cs
│ └── cookieexception.cs
└── tests
├── FunctionalTests
├── ByteArrayContentTest.cs
├── ByteAtATimeContent.cs
├── ChannelBindingAwareContent.cs
├── Configurations.props
├── CustomContent.cs
├── CustomContent.netcore.cs
├── DefaultCredentialsTest.cs
├── DelegatingHandlerTest.cs
├── DiagnosticsTests.cs
├── DribbleStream.cs
├── FakeDiagnosticSourceListenerObserver.cs
├── FormUrlEncodedContentTest.cs
├── HPackTest.cs
├── HttpClient.SelectedSitesTest.cs
├── HttpClientEKUTest.cs
├── HttpClientHandlerTest.AcceptAllCerts.cs
├── HttpClientHandlerTest.Asynchrony.cs
├── HttpClientHandlerTest.Authentication.cs
├── HttpClientHandlerTest.AutoRedirect.cs
├── HttpClientHandlerTest.Cancellation.cs
├── HttpClientHandlerTest.ClientCertificates.cs
├── HttpClientHandlerTest.Cookies.cs
├── HttpClientHandlerTest.Decompression.cs
├── HttpClientHandlerTest.DefaultProxyCredentials.cs
├── HttpClientHandlerTest.Finalization.cs
├── HttpClientHandlerTest.Headers.cs
├── HttpClientHandlerTest.Http1.cs
├── HttpClientHandlerTest.Http2.cs
├── HttpClientHandlerTest.MaxConnectionsPerServer.cs
├── HttpClientHandlerTest.MaxResponseHeadersLength.cs
├── HttpClientHandlerTest.Proxy.cs
├── HttpClientHandlerTest.ResponseDrain.cs
├── HttpClientHandlerTest.ServerCertificates.Unix.cs
├── HttpClientHandlerTest.ServerCertificates.Windows.cs
├── HttpClientHandlerTest.ServerCertificates.cs
├── HttpClientHandlerTest.SslProtocols.Unix.cs
├── HttpClientHandlerTest.SslProtocols.Windows.cs
├── HttpClientHandlerTest.SslProtocols.cs
├── HttpClientHandlerTest.cs
├── HttpClientHandlerTestBase.cs
├── HttpClientMiniStressTest.cs
├── HttpClientTest.cs
├── HttpClientTest.netcoreapp.cs
├── HttpContentTest.cs
├── HttpMessageInvokerTest.cs
├── HttpMethodTest.cs
├── HttpMethodTest.netcoreapp.cs
├── HttpProtocolTests.cs
├── HttpRequestMessageTest.cs
├── HttpResponseMessageTest.cs
├── HttpRetryProtocolTests.cs
├── IdnaProtocolTests.cs
├── MessageProcessingHandlerTest.cs
├── MultiInterfaceNonRewindableReadOnlyStream.cs
├── MultiInterfaceReadOnlyStream.cs
├── MultiInterfaceStreamContent.cs
├── MultipartContentTest.cs
├── MultipartFormDataContentTest.cs
├── NtAuthTests.cs
├── PlatformHandlerTest.cs
├── PostScenarioTest.cs
├── PostScenarioUWPTest.cs
├── Properties
│ └── launchSettings.json
├── ReadOnlyMemoryContentTest.cs
├── RepeatedFlushContent.cs
├── ResponseStreamTest.cs
├── SchSendAuxRecordHttpTest.cs
├── SelectedSitesTest.txt
├── SocketsHttpHandlerTest.cs
├── StreamContentTest.cs
├── StringContentTest.cs
├── SyncBlockingContent.cs
├── System.Net.Http.Functional.Tests.csproj
├── TestHelper.cs
├── ThrowingContent.cs
├── Watchdog.cs
├── XUnitAssemblyAttributes.cs
└── prerequisites
│ ├── ShowIdentity.ashx
│ ├── Web.config
│ └── readme.txt
├── StressTests
└── HttpStress
│ ├── Directory.Build.props
│ ├── Directory.Build.targets
│ ├── HttpStress.csproj
│ ├── HttpStress.sln
│ └── Program.cs
└── UnitTests
├── Configurations.props
├── DigestAuthenticationTests.cs
├── Fakes
├── HttpClientHandler.cs
└── MacProxy.cs
├── HPack
├── HPackDecoderTest.cs
├── HPackIntegerTest.cs
├── HPackRoundtripTests.cs
└── HuffmanDecodingTests.cs
├── Headers
├── AuthenticationHeaderValueTest.cs
├── ByteArrayHeaderParserTest.cs
├── CacheControlHeaderParserTest.cs
├── CacheControlHeaderValueTest.cs
├── ContentDispositionHeaderValueTest.cs
├── ContentRangeHeaderValueTest.cs
├── CurlResponseHeaderReaderTest.cs
├── DateHeaderParserTest.cs
├── EntityTagHeaderValueTest.cs
├── GenericHeaderParserTest
│ ├── AuthenticationParserTest.cs
│ ├── ContentRangeParserTest.cs
│ ├── EntityTagParserTest.cs
│ ├── HostParserTest.cs
│ ├── MailAddressParserTest.cs
│ ├── NameValueParserTest.cs
│ ├── NameValueWithParametersParserTest.cs
│ ├── ProductParserTest.cs
│ ├── RangeConditionParserTest.cs
│ ├── RangeParserTest.cs
│ ├── RetryConditionParserTest.cs
│ ├── StringWithQualityParserTest.cs
│ ├── TokenListParserTest.cs
│ ├── ViaParserTest.cs
│ └── WarningParserTest.cs
├── HeaderUtilitiesTest.cs
├── HttpContentHeadersTest.cs
├── HttpHeaderValueCollectionTest.cs
├── HttpHeadersTest.cs
├── HttpRequestHeadersTest.cs
├── HttpResponseHeadersTest.cs
├── Int32NumberHeaderParserTest.cs
├── Int64NumberHeaderParserTest.cs
├── MediaTypeHeaderParserTest.cs
├── MediaTypeHeaderValueTest.cs
├── MediaTypeWithQualityHeaderValueTest.cs
├── NameValueHeaderValueTest.cs
├── NameValueWithParametersHeaderValueTest.cs
├── ObjectCollectionTest.cs
├── ProductHeaderValueTest.cs
├── ProductInfoHeaderParserTest.cs
├── ProductInfoHeaderValueTest.cs
├── RangeConditionHeaderValueTest.cs
├── RangeHeaderValueTest.cs
├── RangeItemHeaderValueTest.cs
├── RetryConditionHeaderValueTest.cs
├── StringWithQualityHeaderValueTest.cs
├── TimeSpanHeaderParserTest.cs
├── TransferCodingHeaderParserTest.cs
├── TransferCodingHeaderValueTest.cs
├── TransferCodingWithQualityHeaderValueTest.cs
├── UriHeaderParserTest.cs
├── ViaHeaderValueTest.cs
└── WarningHeaderValueTest.cs
├── HttpContentTest.cs
├── HttpEnvironmentProxyTest.cs
├── HttpRuleParserTest.cs
├── HttpWindowsProxyTest.cs
├── MockContent.cs
├── Properties
└── launchSettings.json
├── StreamToStreamCopyTest.cs
├── System.Net.Http.Unit.Tests.csproj
└── SystemProxyInfoTest.cs
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/.DS_Store
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Yukino
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EmbyCracked
2 |
3 | ## Feature
4 | + 破解 Emby 高级版验证
5 | + 修改了默认插件源,加速中国用户下载插件
6 | + docker 一键安装
7 |
8 | ## Usage
9 |
10 | ### 手动替换
11 | + **注意**:如果以前使用其他破解方案,必须将系统的 hosts 的 mb3admin.com www.mb3admin.com 条目删除,否则破解不会生效
12 | + 将 [破解程序集](https://github.com/YukiCoco/EmbyCrack/tree/master/assembly) 替换原有文件即完成破解,原有文件路径为 `system/System.Net.Http.dll`
13 | + 客户端使用:
14 | + 浏览器:安装 [URLRedirector]() 插件,将 `https://mb3admin.com` 替换为 `http://crackemby.neko.re`
15 | + Android & Android TV:直接使用破解版,自己找找就有了
16 | + 详细使用方法移步[这里](https://neko.re/archives/128.html)
17 |
18 | ### 使用 Docker
19 | + `yukinococo/emby_crack:unix-x64`(Unix)
20 | + `yukinococo/emby_crack:windows-x64` (Windows)
21 |
--------------------------------------------------------------------------------
/assembly/unix-arm64/System.Net.Http.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/assembly/unix-arm64/System.Net.Http.dll
--------------------------------------------------------------------------------
/assembly/unix-x64/System.Net.Http.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/assembly/unix-x64/System.Net.Http.dll
--------------------------------------------------------------------------------
/assembly/windows-x64/System.Net.Http.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/assembly/windows-x64/System.Net.Http.dll
--------------------------------------------------------------------------------
/docker/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/docker/.DS_Store
--------------------------------------------------------------------------------
/docker/unix-arm64/Dockerfile:
--------------------------------------------------------------------------------
1 | # Emby Server
2 | FROM emby/embyserver
3 | COPY ./System.Net.Http.dll /system/
--------------------------------------------------------------------------------
/docker/unix-arm64/System.Net.Http.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/docker/unix-arm64/System.Net.Http.dll
--------------------------------------------------------------------------------
/docker/unix-x64/Dockerfile:
--------------------------------------------------------------------------------
1 | # Emby Server
2 | FROM emby/embyserver
3 | COPY ./System.Net.Http.dll /system/
--------------------------------------------------------------------------------
/docker/unix-x64/System.Net.Http.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/docker/unix-x64/System.Net.Http.dll
--------------------------------------------------------------------------------
/docker/windows-x64/Dockerfile:
--------------------------------------------------------------------------------
1 | # Emby Server
2 | FROM emby/embyserver
3 | COPY ./System.Net.Http.dll /system/
--------------------------------------------------------------------------------
/docker/windows-x64/System.Net.Http.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/docker/windows-x64/System.Net.Http.dll
--------------------------------------------------------------------------------
/src/System.Net.Http/.vs/System.Net.Http/DesignTimeBuild/.dtbcache:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/src/System.Net.Http/.vs/System.Net.Http/DesignTimeBuild/.dtbcache
--------------------------------------------------------------------------------
/src/System.Net.Http/.vs/System.Net.Http/v16/.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/src/System.Net.Http/.vs/System.Net.Http/v16/.suo
--------------------------------------------------------------------------------
/src/System.Net.Http/.vs/System.Net.Http/v16/Server/sqlite3/db.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/src/System.Net.Http/.vs/System.Net.Http/v16/Server/sqlite3/db.lock
--------------------------------------------------------------------------------
/src/System.Net.Http/.vs/System.Net.Http/v16/Server/sqlite3/storage.ide:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ultranijia/EmbyCrack/edb5e2b0319e750b75fd028e30e904d21135b002/src/System.Net.Http/.vs/System.Net.Http/v16/Server/sqlite3/storage.ide
--------------------------------------------------------------------------------
/src/System.Net.Http/ConsoleApp1/ConsoleApp1.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/System.Net.Http/ConsoleApp1/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ConsoleApp1
4 | {
5 | class Program
6 | {
7 | static void Main(string[] args)
8 | {
9 | Console.WriteLine("Hello World!");
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/System.Net.Http/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.2.2.0
5 | Microsoft
6 | true
7 | true
8 |
9 |
--------------------------------------------------------------------------------
/src/System.Net.Http/TestBypassSSL/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 |
4 | namespace TestBypassSSL
5 | {
6 | class Program
7 | {
8 | static void Main(string[] args)
9 | {
10 | //Console.WriteLine("Hello World!");
11 | HttpClient httpClient = new HttpClient();
12 | var result = httpClient.GetAsync("https://mb3admin.com/").Result;
13 | Console.WriteLine(result.Content.ReadAsStringAsync().Result);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/System.Net.Http/TestBypassSSL/TestBypassSSL.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/System.Net.Http/ref/Configurations.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp;
5 | uap;
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/System.Net.Http/ref/System.Net.Http.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {132BF813-FC40-4D39-8B6F-E55D7633F0ED}
4 | netcoreapp-Debug;netcoreapp-Release;uap-Debug;uap-Release
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/Configurations.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | uap-Windows_NT;
5 | netcoreapp-OSX;
6 | netcoreapp-Unix;
7 | netcoreapp-Windows_NT;
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/ILLinkTrim.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/MatchingRefApiCompatBaseline.uap.txt:
--------------------------------------------------------------------------------
1 | Compat issues with assembly System.Net.Http:
2 | TypesMustExist : Type 'System.Net.Internal.Cookie' does not exist in the reference but it does exist in the implementation.
3 | TypesMustExist : Type 'System.Net.Internal.CookieException' does not exist in the reference but it does exist in the implementation.
4 | Total Issues: 2
5 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/ByteArrayContent.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.IO;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 |
10 | namespace System.Net.Http
11 | {
12 | public class ByteArrayContent : HttpContent
13 | {
14 | private readonly byte[] _content;
15 | private readonly int _offset;
16 | private readonly int _count;
17 |
18 | public ByteArrayContent(byte[] content)
19 | {
20 | if (content == null)
21 | {
22 | throw new ArgumentNullException(nameof(content));
23 | }
24 |
25 | _content = content;
26 | _offset = 0;
27 | _count = content.Length;
28 |
29 | SetBuffer(_content, _offset, _count);
30 | }
31 |
32 | public ByteArrayContent(byte[] content, int offset, int count)
33 | {
34 | if (content == null)
35 | {
36 | throw new ArgumentNullException(nameof(content));
37 | }
38 | if ((offset < 0) || (offset > content.Length))
39 | {
40 | throw new ArgumentOutOfRangeException(nameof(offset));
41 | }
42 | if ((count < 0) || (count > (content.Length - offset)))
43 | {
44 | throw new ArgumentOutOfRangeException(nameof(count));
45 | }
46 |
47 | _content = content;
48 | _offset = offset;
49 | _count = count;
50 |
51 | SetBuffer(_content, _offset, _count);
52 | }
53 |
54 | protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) =>
55 | SerializeToStreamAsyncCore(stream, default);
56 |
57 | internal override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) =>
58 | // Only skip the original protected virtual SerializeToStreamAsync if this
59 | // isn't a derived type that may have overridden the behavior.
60 | GetType() == typeof(ByteArrayContent) ? SerializeToStreamAsyncCore(stream, cancellationToken) :
61 | base.SerializeToStreamAsync(stream, context, cancellationToken);
62 |
63 | private protected Task SerializeToStreamAsyncCore(Stream stream, CancellationToken cancellationToken) =>
64 | stream.WriteAsync(_content, _offset, _count, cancellationToken);
65 |
66 | protected internal override bool TryComputeLength(out long length)
67 | {
68 | length = _count;
69 | return true;
70 | }
71 |
72 | protected override Task CreateContentReadStreamAsync() =>
73 | Task.FromResult(CreateMemoryStreamForByteArray());
74 |
75 | internal override Stream TryCreateContentReadStream() =>
76 | GetType() == typeof(ByteArrayContent) ? CreateMemoryStreamForByteArray() : // type check ensures we use possible derived type's CreateContentReadStreamAsync override
77 | null;
78 |
79 | internal MemoryStream CreateMemoryStreamForByteArray() => new MemoryStream(_content, _offset, _count, writable: false);
80 |
81 | internal override bool AllowDuplex => false;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/ByteArrayHelpers.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace System
8 | {
9 | internal static class ByteArrayHelpers
10 | {
11 | internal static bool EqualsOrdinalAsciiIgnoreCase(string left, ReadOnlySpan right)
12 | {
13 | Debug.Assert(left != null, "Expected non-null string");
14 |
15 | if (left.Length != right.Length)
16 | {
17 | return false;
18 | }
19 |
20 | for (int i = 0; i < left.Length; i++)
21 | {
22 | uint charA = left[i];
23 | uint charB = right[i];
24 |
25 | unchecked
26 | {
27 | // We're only interested in ASCII characters here.
28 | if ((charA - 'a') <= ('z' - 'a'))
29 | charA -= ('a' - 'A');
30 | if ((charB - 'a') <= ('z' - 'a'))
31 | charB -= ('a' - 'A');
32 | }
33 |
34 | if (charA != charB)
35 | {
36 | return false;
37 | }
38 | }
39 |
40 | return true;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/ClientCertificateOption.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | public enum ClientCertificateOption
8 | {
9 | Manual = 0,
10 | Automatic,
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/CurlHandler/CurlException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Runtime.InteropServices;
6 |
7 | namespace System.Net.Http
8 | {
9 | internal sealed class CurlException : Exception
10 | {
11 | internal CurlException(int error, string message) : base(message)
12 | {
13 | HResult = error;
14 | }
15 |
16 | internal CurlException(int error, Exception innerException) : base(GetCurlErrorString(error, isMulti:false), innerException)
17 | {
18 | HResult = error;
19 | }
20 |
21 | internal CurlException(int error, bool isMulti) : this(error, GetCurlErrorString(error, isMulti))
22 | {
23 | }
24 |
25 | internal static string GetCurlErrorString(int code, bool isMulti)
26 | {
27 | IntPtr ptr = isMulti ? Interop.Http.MultiGetErrorString(code) : Interop.Http.EasyGetErrorString(code);
28 | return Marshal.PtrToStringAnsi(ptr);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/DelegatingHandler.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace System.Net.Http
12 | {
13 | public abstract class DelegatingHandler : HttpMessageHandler
14 | {
15 | private HttpMessageHandler _innerHandler;
16 | private volatile bool _operationStarted = false;
17 | private volatile bool _disposed = false;
18 |
19 | public HttpMessageHandler InnerHandler
20 | {
21 | get
22 | {
23 | return _innerHandler;
24 | }
25 | set
26 | {
27 | if (value == null)
28 | {
29 | throw new ArgumentNullException(nameof(value));
30 | }
31 | CheckDisposedOrStarted();
32 |
33 | if (NetEventSource.IsEnabled) NetEventSource.Associate(this, value);
34 | _innerHandler = value;
35 | }
36 | }
37 |
38 | protected DelegatingHandler()
39 | {
40 | }
41 |
42 | protected DelegatingHandler(HttpMessageHandler innerHandler)
43 | {
44 | InnerHandler = innerHandler;
45 | }
46 |
47 | protected internal override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
48 | {
49 | if (request == null)
50 | {
51 | throw new ArgumentNullException(nameof(request), SR.net_http_handler_norequest);
52 | }
53 | SetOperationStarted();
54 | return _innerHandler.SendAsync(request, cancellationToken);
55 | }
56 |
57 | protected override void Dispose(bool disposing)
58 | {
59 | if (disposing && !_disposed)
60 | {
61 | _disposed = true;
62 | if (_innerHandler != null)
63 | {
64 | _innerHandler.Dispose();
65 | }
66 | }
67 |
68 | base.Dispose(disposing);
69 | }
70 |
71 | private void CheckDisposed()
72 | {
73 | if (_disposed)
74 | {
75 | throw new ObjectDisposedException(GetType().ToString());
76 | }
77 | }
78 |
79 | private void CheckDisposedOrStarted()
80 | {
81 | CheckDisposed();
82 | if (_operationStarted)
83 | {
84 | throw new InvalidOperationException(SR.net_http_operation_started);
85 | }
86 | }
87 |
88 | private void SetOperationStarted()
89 | {
90 | CheckDisposed();
91 | if (_innerHandler == null)
92 | {
93 | throw new InvalidOperationException(SR.net_http_handler_not_assigned);
94 | }
95 | // This method flags the handler instances as "active". I.e. we executed at least one request (or are
96 | // in the process of doing so). This information is used to lock-down all property setters. Once a
97 | // Send/SendAsync operation started, no property can be changed.
98 | if (!_operationStarted)
99 | {
100 | _operationStarted = true;
101 | }
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/DiagnosticsHandlerLoggingStrings.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | ///
8 | /// Defines names of DiagnosticListener and Write events for WinHttpHandler, CurlHandler, and HttpHandlerToFilter.
9 | ///
10 | internal static class DiagnosticsHandlerLoggingStrings
11 | {
12 | public const string DiagnosticListenerName = "HttpHandlerDiagnosticListener";
13 | public const string RequestWriteNameDeprecated = "System.Net.Http.Request";
14 | public const string ResponseWriteNameDeprecated = "System.Net.Http.Response";
15 |
16 | public const string ExceptionEventName = "System.Net.Http.Exception";
17 | public const string ActivityName = "System.Net.Http.HttpRequestOut";
18 | public const string ActivityStartName = "System.Net.Http.HttpRequestOut.Start";
19 |
20 | public const string RequestIdHeaderName = "Request-Id";
21 | public const string CorrelationContextHeaderName = "Correlation-Context";
22 |
23 | public const string TraceParentHeaderName = "traceparent";
24 | public const string TraceStateHeaderName = "tracestate";
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/FormUrlEncodedContent.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Net.Http.Headers;
8 | using System.Text;
9 | using System.Threading;
10 | using System.Threading.Tasks;
11 |
12 | namespace System.Net.Http
13 | {
14 | public class FormUrlEncodedContent : ByteArrayContent
15 | {
16 | public FormUrlEncodedContent(IEnumerable> nameValueCollection)
17 | : base(GetContentByteArray(nameValueCollection))
18 | {
19 | Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
20 | }
21 |
22 | private static byte[] GetContentByteArray(IEnumerable> nameValueCollection)
23 | {
24 | if (nameValueCollection == null)
25 | {
26 | throw new ArgumentNullException(nameof(nameValueCollection));
27 | }
28 |
29 | // Encode and concatenate data
30 | StringBuilder builder = new StringBuilder();
31 | foreach (KeyValuePair pair in nameValueCollection)
32 | {
33 | if (builder.Length > 0)
34 | {
35 | builder.Append('&');
36 | }
37 |
38 | builder.Append(Encode(pair.Key));
39 | builder.Append('=');
40 | builder.Append(Encode(pair.Value));
41 | }
42 |
43 | return HttpRuleParser.DefaultHttpEncoding.GetBytes(builder.ToString());
44 | }
45 |
46 | private static string Encode(string data)
47 | {
48 | if (string.IsNullOrEmpty(data))
49 | {
50 | return string.Empty;
51 | }
52 | // Escape spaces as '+'.
53 | return Uri.EscapeDataString(data).Replace("%20", "+");
54 | }
55 |
56 | internal override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) =>
57 | // Only skip the original protected virtual SerializeToStreamAsync if this
58 | // isn't a derived type that may have overridden the behavior.
59 | GetType() == typeof(FormUrlEncodedContent) ? SerializeToStreamAsyncCore(stream, cancellationToken) :
60 | base.SerializeToStreamAsync(stream, context, cancellationToken);
61 |
62 | internal override Stream TryCreateContentReadStream() =>
63 | GetType() == typeof(FormUrlEncodedContent) ? CreateMemoryStreamForByteArray() : // type check ensures we use possible derived type's CreateContentReadStreamAsync override
64 | null;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/BaseHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace System.Net.Http.Headers
8 | {
9 | internal abstract class BaseHeaderParser : HttpHeaderParser
10 | {
11 | protected BaseHeaderParser(bool supportsMultipleValues)
12 | : base(supportsMultipleValues)
13 | {
14 | }
15 |
16 | protected abstract int GetParsedValueLength(string value, int startIndex, object storeValue,
17 | out object parsedValue);
18 |
19 | public sealed override bool TryParseValue(string value, object storeValue, ref int index,
20 | out object parsedValue)
21 | {
22 | parsedValue = null;
23 |
24 | // If multiple values are supported (i.e. list of values), then accept an empty string: The header may
25 | // be added multiple times to the request/response message. E.g.
26 | // Accept: text/xml; q=1
27 | // Accept:
28 | // Accept: text/plain; q=0.2
29 | if (string.IsNullOrEmpty(value) || (index == value.Length))
30 | {
31 | return SupportsMultipleValues;
32 | }
33 |
34 | bool separatorFound = false;
35 | int current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(value, index, SupportsMultipleValues,
36 | out separatorFound);
37 |
38 | if (separatorFound && !SupportsMultipleValues)
39 | {
40 | return false; // leading separators not allowed if we don't support multiple values.
41 | }
42 |
43 | if (current == value.Length)
44 | {
45 | if (SupportsMultipleValues)
46 | {
47 | index = current;
48 | }
49 | return SupportsMultipleValues;
50 | }
51 |
52 | object result = null;
53 | int length = GetParsedValueLength(value, current, storeValue, out result);
54 |
55 | if (length == 0)
56 | {
57 | return false;
58 | }
59 |
60 | current = current + length;
61 | current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(value, current, SupportsMultipleValues,
62 | out separatorFound);
63 |
64 | // If we support multiple values and we've not reached the end of the string, then we must have a separator.
65 | if ((separatorFound && !SupportsMultipleValues) || (!separatorFound && (current < value.Length)))
66 | {
67 | return false;
68 | }
69 |
70 | index = current;
71 | parsedValue = result;
72 | return true;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/ByteArrayHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace System.Net.Http.Headers
8 | {
9 | // Don't derive from BaseHeaderParser since parsing the Base64 string is delegated to Convert.FromBase64String()
10 | // which will remove leading, trailing, and whitespace in the middle of the string.
11 | internal class ByteArrayHeaderParser : HttpHeaderParser
12 | {
13 | internal static readonly ByteArrayHeaderParser Parser = new ByteArrayHeaderParser();
14 |
15 | private ByteArrayHeaderParser()
16 | : base(false)
17 | {
18 | }
19 |
20 | public override string ToString(object value)
21 | {
22 | Debug.Assert(value is byte[]);
23 |
24 | return Convert.ToBase64String((byte[])value);
25 | }
26 |
27 | public override bool TryParseValue(string value, object storeValue, ref int index, out object parsedValue)
28 | {
29 | parsedValue = null;
30 |
31 | // Some headers support empty/null values. This one doesn't.
32 | if (string.IsNullOrEmpty(value) || (index == value.Length))
33 | {
34 | return false;
35 | }
36 |
37 | string base64String = value;
38 | if (index > 0)
39 | {
40 | base64String = value.Substring(index);
41 | }
42 |
43 | // Try convert the string (we assume it's a valid Base64 string) to byte[].
44 | try
45 | {
46 | parsedValue = Convert.FromBase64String(base64String);
47 | index = value.Length;
48 | return true;
49 | }
50 | catch (FormatException e)
51 | {
52 | if (NetEventSource.IsEnabled) NetEventSource.Error(this, SR.Format(SR.net_http_parser_invalid_base64_string, base64String, e.Message));
53 | }
54 |
55 | return false;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace System.Net.Http.Headers
8 | {
9 | internal class CacheControlHeaderParser : BaseHeaderParser
10 | {
11 | internal static readonly CacheControlHeaderParser Parser = new CacheControlHeaderParser();
12 |
13 | // The Cache-Control header is special: It is a header supporting a list of values, but we represent the list
14 | // as _one_ instance of CacheControlHeaderValue. I.e we set 'SupportsMultipleValues' to 'true' since it is
15 | // OK to have multiple Cache-Control headers in a request/response message. However, after parsing all
16 | // Cache-Control headers, only one instance of CacheControlHeaderValue is created (if all headers contain valid
17 | // values, otherwise we may have multiple strings containing the invalid values).
18 | private CacheControlHeaderParser()
19 | : base(true)
20 | {
21 | }
22 |
23 | protected override int GetParsedValueLength(string value, int startIndex, object storeValue,
24 | out object parsedValue)
25 | {
26 | CacheControlHeaderValue temp = storeValue as CacheControlHeaderValue;
27 | Debug.Assert(storeValue == null || temp != null, "'storeValue' is not of type CacheControlHeaderValue");
28 |
29 | int resultLength = CacheControlHeaderValue.GetCacheControlLength(value, startIndex, temp, out temp);
30 |
31 | parsedValue = temp;
32 | return resultLength;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/DateHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace System.Net.Http.Headers
8 | {
9 | // Don't derive from BaseHeaderParser since parsing is delegated to DateTimeOffset.TryParseExact()
10 | // which will remove leading, trailing, and whitespace in the middle of the string.
11 | internal class DateHeaderParser : HttpHeaderParser
12 | {
13 | internal static readonly DateHeaderParser Parser = new DateHeaderParser();
14 |
15 | private DateHeaderParser()
16 | : base(false)
17 | {
18 | }
19 |
20 | public override string ToString(object value)
21 | {
22 | Debug.Assert(value is DateTimeOffset);
23 |
24 | return HttpDateParser.DateToString((DateTimeOffset)value);
25 | }
26 |
27 | public override bool TryParseValue(string value, object storeValue, ref int index, out object parsedValue)
28 | {
29 | parsedValue = null;
30 |
31 | // Some headers support empty/null values. This one doesn't.
32 | if (string.IsNullOrEmpty(value) || (index == value.Length))
33 | {
34 | return false;
35 | }
36 |
37 | ReadOnlySpan dateString = value;
38 | if (index > 0)
39 | {
40 | dateString = value.AsSpan(index);
41 | }
42 |
43 | DateTimeOffset date;
44 | if (!HttpDateParser.TryStringToDate(dateString, out date))
45 | {
46 | return false;
47 | }
48 |
49 | index = value.Length;
50 | parsedValue = date;
51 | return true;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/HttpHeaderType.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http.Headers
6 | {
7 | [Flags]
8 | internal enum HttpHeaderType : byte
9 | {
10 | General = 0b1,
11 | Request = 0b10,
12 | Response = 0b100,
13 | Content = 0b1000,
14 | Custom = 0b10000,
15 |
16 | All = 0b11111,
17 | None = 0
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/Int32NumberHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.Globalization;
7 |
8 | namespace System.Net.Http.Headers
9 | {
10 | internal class Int32NumberHeaderParser : BaseHeaderParser
11 | {
12 | // Note that we don't need a custom comparer even though we have a value type that gets boxed (comparing two
13 | // equal boxed value types returns 'false' since the object instances used for boxing the two values are
14 | // different). The reason is that the comparer is only used by HttpHeaders when comparing values in a collection.
15 | // Value types are never used in collections (in fact HttpHeaderValueCollection expects T to be a reference
16 | // type).
17 |
18 | internal static readonly Int32NumberHeaderParser Parser = new Int32NumberHeaderParser();
19 |
20 | private Int32NumberHeaderParser()
21 | : base(false)
22 | {
23 | }
24 |
25 | public override string ToString(object value)
26 | {
27 | Debug.Assert(value is int);
28 |
29 | return ((int)value).ToString(NumberFormatInfo.InvariantInfo);
30 | }
31 |
32 | protected override int GetParsedValueLength(string value, int startIndex, object storeValue,
33 | out object parsedValue)
34 | {
35 | parsedValue = null;
36 |
37 | int numberLength = HttpRuleParser.GetNumberLength(value, startIndex, false);
38 |
39 | if ((numberLength == 0) || (numberLength > HttpRuleParser.MaxInt32Digits))
40 | {
41 | return 0;
42 | }
43 |
44 | int result = 0;
45 | if (!HeaderUtilities.TryParseInt32(value, startIndex, numberLength, out result))
46 | {
47 | return 0;
48 | }
49 |
50 | parsedValue = result;
51 | return numberLength;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/Int64NumberHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.Globalization;
7 |
8 | namespace System.Net.Http.Headers
9 | {
10 | internal class Int64NumberHeaderParser : BaseHeaderParser
11 | {
12 | // Note that we don't need a custom comparer even though we have a value type that gets boxed (comparing two
13 | // equal boxed value types returns 'false' since the object instances used for boxing the two values are
14 | // different). The reason is that the comparer is only used by HttpHeaders when comparing values in a collection.
15 | // Value types are never used in collections (in fact HttpHeaderValueCollection expects T to be a reference
16 | // type).
17 |
18 | internal static readonly Int64NumberHeaderParser Parser = new Int64NumberHeaderParser();
19 |
20 | private Int64NumberHeaderParser()
21 | : base(false)
22 | {
23 | }
24 |
25 | public override string ToString(object value)
26 | {
27 | Debug.Assert(value is long);
28 |
29 | return ((long)value).ToString(NumberFormatInfo.InvariantInfo);
30 | }
31 |
32 | protected override int GetParsedValueLength(string value, int startIndex, object storeValue,
33 | out object parsedValue)
34 | {
35 | parsedValue = null;
36 |
37 | int numberLength = HttpRuleParser.GetNumberLength(value, startIndex, false);
38 |
39 | if ((numberLength == 0) || (numberLength > HttpRuleParser.MaxInt64Digits))
40 | {
41 | return 0;
42 | }
43 |
44 | long result = 0;
45 | if (!HeaderUtilities.TryParseInt64(value, startIndex, numberLength, out result))
46 | {
47 | return 0;
48 | }
49 |
50 | parsedValue = result;
51 | return numberLength;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/KnownHeader.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.Net.Http.HPack;
7 | using System.Text;
8 |
9 | namespace System.Net.Http.Headers
10 | {
11 | internal sealed class KnownHeader
12 | {
13 | public KnownHeader(string name, int? http2StaticTableIndex = null) :
14 | this(name, HttpHeaderType.Custom, parser: null, knownValues: null, http2StaticTableIndex)
15 | {
16 | Debug.Assert(!string.IsNullOrEmpty(name));
17 | Debug.Assert(HttpRuleParser.GetTokenLength(name, 0) == name.Length);
18 | }
19 |
20 | public KnownHeader(string name, HttpHeaderType headerType, HttpHeaderParser parser, string[] knownValues = null, int? http2StaticTableIndex = null)
21 | {
22 | Debug.Assert(!string.IsNullOrEmpty(name));
23 | Debug.Assert(HttpRuleParser.GetTokenLength(name, 0) == name.Length);
24 | Debug.Assert((headerType == HttpHeaderType.Custom) == (parser == null));
25 | Debug.Assert(knownValues == null || headerType != HttpHeaderType.Custom);
26 |
27 | Name = name;
28 | HeaderType = headerType;
29 | Parser = parser;
30 | KnownValues = knownValues;
31 |
32 | Http2EncodedName = http2StaticTableIndex.HasValue ?
33 | HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingToAllocatedArray(http2StaticTableIndex.GetValueOrDefault()) :
34 | HPackEncoder.EncodeLiteralHeaderFieldWithoutIndexingNewNameToAllocatedArray(name);
35 |
36 | var asciiBytesWithColonSpace = new byte[name.Length + 2]; // + 2 for ':' and ' '
37 | int asciiBytes = Encoding.ASCII.GetBytes(name, asciiBytesWithColonSpace);
38 | Debug.Assert(asciiBytes == name.Length);
39 | asciiBytesWithColonSpace[asciiBytesWithColonSpace.Length - 2] = (byte)':';
40 | asciiBytesWithColonSpace[asciiBytesWithColonSpace.Length - 1] = (byte)' ';
41 | AsciiBytesWithColonSpace = asciiBytesWithColonSpace;
42 | }
43 |
44 | public string Name { get; }
45 | public HttpHeaderParser Parser { get; }
46 | public HttpHeaderType HeaderType { get; }
47 | public string[] KnownValues { get; }
48 | public byte[] AsciiBytesWithColonSpace { get; }
49 | public HeaderDescriptor Descriptor => new HeaderDescriptor(this);
50 | public byte[] Http2EncodedName { get; }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace System.Net.Http.Headers
8 | {
9 | internal class MediaTypeHeaderParser : BaseHeaderParser
10 | {
11 | private bool _supportsMultipleValues;
12 | private Func _mediaTypeCreator;
13 |
14 | internal static readonly MediaTypeHeaderParser SingleValueParser = new MediaTypeHeaderParser(false,
15 | CreateMediaType);
16 | internal static readonly MediaTypeHeaderParser SingleValueWithQualityParser = new MediaTypeHeaderParser(false,
17 | CreateMediaTypeWithQuality);
18 | internal static readonly MediaTypeHeaderParser MultipleValuesParser = new MediaTypeHeaderParser(true,
19 | CreateMediaTypeWithQuality);
20 |
21 | private MediaTypeHeaderParser(bool supportsMultipleValues, Func mediaTypeCreator)
22 | : base(supportsMultipleValues)
23 | {
24 | Debug.Assert(mediaTypeCreator != null);
25 |
26 | _supportsMultipleValues = supportsMultipleValues;
27 | _mediaTypeCreator = mediaTypeCreator;
28 | }
29 |
30 | protected override int GetParsedValueLength(string value, int startIndex, object storeValue,
31 | out object parsedValue)
32 | {
33 | MediaTypeHeaderValue temp = null;
34 | int resultLength = MediaTypeHeaderValue.GetMediaTypeLength(value, startIndex, _mediaTypeCreator, out temp);
35 |
36 | parsedValue = temp;
37 | return resultLength;
38 | }
39 |
40 | private static MediaTypeHeaderValue CreateMediaType()
41 | {
42 | return new MediaTypeHeaderValue();
43 | }
44 |
45 | private static MediaTypeHeaderValue CreateMediaTypeWithQuality()
46 | {
47 | return new MediaTypeWithQualityHeaderValue();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/MediaTypeWithQualityHeaderValue.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace System.Net.Http.Headers
8 | {
9 | public sealed class MediaTypeWithQualityHeaderValue : MediaTypeHeaderValue, ICloneable
10 | {
11 | public double? Quality
12 | {
13 | get { return HeaderUtilities.GetQuality((ObjectCollection)Parameters); }
14 | set { HeaderUtilities.SetQuality((ObjectCollection)Parameters, value); }
15 | }
16 |
17 | internal MediaTypeWithQualityHeaderValue()
18 | : base()
19 | {
20 | // Used by the parser to create a new instance of this type.
21 | }
22 |
23 | public MediaTypeWithQualityHeaderValue(string mediaType)
24 | : base(mediaType)
25 | {
26 | }
27 |
28 | public MediaTypeWithQualityHeaderValue(string mediaType, double quality)
29 | : base(mediaType)
30 | {
31 | Quality = quality;
32 | }
33 |
34 | private MediaTypeWithQualityHeaderValue(MediaTypeWithQualityHeaderValue source)
35 | : base(source)
36 | {
37 | // No additional members to initialize here. This constructor is used by Clone().
38 | }
39 |
40 | object ICloneable.Clone()
41 | {
42 | return new MediaTypeWithQualityHeaderValue(this);
43 | }
44 |
45 | public static new MediaTypeWithQualityHeaderValue Parse(string input)
46 | {
47 | int index = 0;
48 | return (MediaTypeWithQualityHeaderValue)MediaTypeHeaderParser.SingleValueWithQualityParser.ParseValue(
49 | input, null, ref index);
50 | }
51 |
52 | public static bool TryParse(string input, out MediaTypeWithQualityHeaderValue parsedValue)
53 | {
54 | int index = 0;
55 | object output;
56 | parsedValue = null;
57 |
58 | if (MediaTypeHeaderParser.SingleValueWithQualityParser.TryParseValue(input, null, ref index, out output))
59 | {
60 | parsedValue = (MediaTypeWithQualityHeaderValue)output;
61 | return true;
62 | }
63 | return false;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/ObjectCollection.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Collections.ObjectModel;
7 | using System.Diagnostics;
8 |
9 | namespace System.Net.Http.Headers
10 | {
11 | // We need to prevent 'null' values in the collection. Since List allows them, we will create
12 | // a custom collection class. It is less efficient than List but only used for small collections.
13 | internal sealed class ObjectCollection : Collection where T : class
14 | {
15 | private static readonly Action s_defaultValidator = CheckNotNull;
16 |
17 | private readonly Action _validator;
18 |
19 | public ObjectCollection()
20 | : this(s_defaultValidator)
21 | {
22 | }
23 |
24 | public ObjectCollection(Action validator)
25 | : base(new List())
26 | {
27 | Debug.Assert(validator != null, $"{nameof(validator)} must not be null.");
28 | _validator = validator;
29 | }
30 |
31 | // This is only used internally to enumerate the collection
32 | // without the enumerator allocation.
33 | new public List.Enumerator GetEnumerator()
34 | {
35 | return ((List)Items).GetEnumerator();
36 | }
37 |
38 | protected override void InsertItem(int index, T item)
39 | {
40 | _validator(item);
41 | base.InsertItem(index, item);
42 | }
43 |
44 | protected override void SetItem(int index, T item)
45 | {
46 | _validator(item);
47 | base.SetItem(index, item);
48 | }
49 |
50 | private static void CheckNotNull(T item)
51 | {
52 | // Null values cannot be added to the collection.
53 | if (item == null)
54 | {
55 | throw new ArgumentNullException(nameof(item));
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace System.Net.Http.Headers
8 | {
9 | // Don't derive from BaseHeaderParser since empty values are not supported. After a ' ' separator a valid value
10 | // must follow. Also leading separators are not allowed.
11 | internal class ProductInfoHeaderParser : HttpHeaderParser
12 | {
13 | // Unlike most other headers, User-Agent and Server use whitespace as separators
14 | private const string separator = " ";
15 |
16 | internal static readonly ProductInfoHeaderParser SingleValueParser = new ProductInfoHeaderParser(false);
17 | internal static readonly ProductInfoHeaderParser MultipleValueParser = new ProductInfoHeaderParser(true);
18 |
19 | private ProductInfoHeaderParser(bool supportsMultipleValues)
20 | : base(supportsMultipleValues, separator)
21 | {
22 | }
23 |
24 | public override bool TryParseValue(string value, object storeValue, ref int index, out object parsedValue)
25 | {
26 | parsedValue = null;
27 |
28 | if (string.IsNullOrEmpty(value) || (index == value.Length))
29 | {
30 | return false;
31 | }
32 |
33 | // Skip leading whitespace
34 | int current = index + HttpRuleParser.GetWhitespaceLength(value, index);
35 |
36 | if (current == value.Length)
37 | {
38 | return false; // whitespace-only values are not valid
39 | }
40 |
41 | ProductInfoHeaderValue result = null;
42 | int length = ProductInfoHeaderValue.GetProductInfoLength(value, current, out result);
43 |
44 | if (length == 0)
45 | {
46 | return false;
47 | }
48 |
49 | // GetProductInfoLength() already skipped trailing whitespace. No need to do it here again.
50 | current = current + length;
51 |
52 | // If we have more values, make sure we saw a whitespace before. Values like "product/1.0(comment)" are
53 | // invalid since there must be a whitespace between the product and the comment value.
54 | if (current < value.Length)
55 | {
56 | // Note that for \r\n to be a valid whitespace, it must be followed by a space/tab. I.e. it's enough if
57 | // we check whether the char before the next value is space/tab.
58 | char lastSeparatorChar = value[current - 1];
59 | if ((lastSeparatorChar != ' ') && (lastSeparatorChar != '\t'))
60 | {
61 | return false;
62 | }
63 | }
64 |
65 | // Separators for "User-Agent" and "Server" headers are whitespace. This is different from most other headers
66 | // where comma/semicolon is used as separator.
67 | index = current;
68 | parsedValue = result;
69 | return true;
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/TimeSpanHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.Globalization;
7 |
8 | namespace System.Net.Http.Headers
9 | {
10 | internal class TimeSpanHeaderParser : BaseHeaderParser
11 | {
12 | internal static readonly TimeSpanHeaderParser Parser = new TimeSpanHeaderParser();
13 |
14 | private TimeSpanHeaderParser()
15 | : base(false)
16 | {
17 | }
18 |
19 | public override string ToString(object value)
20 | {
21 | Debug.Assert(value is TimeSpan);
22 |
23 | return ((int)((TimeSpan)value).TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);
24 | }
25 |
26 | protected override int GetParsedValueLength(string value, int startIndex, object storeValue,
27 | out object parsedValue)
28 | {
29 | parsedValue = null;
30 |
31 | int numberLength = HttpRuleParser.GetNumberLength(value, startIndex, false);
32 |
33 | if ((numberLength == 0) || (numberLength > HttpRuleParser.MaxInt32Digits))
34 | {
35 | return 0;
36 | }
37 |
38 | int result = 0;
39 | if (!HeaderUtilities.TryParseInt32(value, startIndex, numberLength, out result))
40 | {
41 | return 0;
42 | }
43 |
44 | parsedValue = new TimeSpan(0, 0, result);
45 | return numberLength;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderParser.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace System.Net.Http.Headers
8 | {
9 | internal class TransferCodingHeaderParser : BaseHeaderParser
10 | {
11 | private Func _transferCodingCreator;
12 |
13 | internal static readonly TransferCodingHeaderParser SingleValueParser =
14 | new TransferCodingHeaderParser(false, CreateTransferCoding);
15 | internal static readonly TransferCodingHeaderParser MultipleValueParser =
16 | new TransferCodingHeaderParser(true, CreateTransferCoding);
17 | internal static readonly TransferCodingHeaderParser SingleValueWithQualityParser =
18 | new TransferCodingHeaderParser(false, CreateTransferCodingWithQuality);
19 | internal static readonly TransferCodingHeaderParser MultipleValueWithQualityParser =
20 | new TransferCodingHeaderParser(true, CreateTransferCodingWithQuality);
21 |
22 | private TransferCodingHeaderParser(bool supportsMultipleValues,
23 | Func transferCodingCreator)
24 | : base(supportsMultipleValues)
25 | {
26 | Debug.Assert(transferCodingCreator != null);
27 |
28 | _transferCodingCreator = transferCodingCreator;
29 | }
30 |
31 | protected override int GetParsedValueLength(string value, int startIndex, object storeValue,
32 | out object parsedValue)
33 | {
34 | TransferCodingHeaderValue temp = null;
35 | int resultLength = TransferCodingHeaderValue.GetTransferCodingLength(value, startIndex,
36 | _transferCodingCreator, out temp);
37 |
38 | parsedValue = temp;
39 | return resultLength;
40 | }
41 |
42 | private static TransferCodingHeaderValue CreateTransferCoding()
43 | {
44 | return new TransferCodingHeaderValue();
45 | }
46 |
47 | private static TransferCodingHeaderValue CreateTransferCodingWithQuality()
48 | {
49 | return new TransferCodingWithQualityHeaderValue();
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/Headers/TransferCodingWithQualityHeaderValue.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 |
7 | namespace System.Net.Http.Headers
8 | {
9 | public sealed class TransferCodingWithQualityHeaderValue : TransferCodingHeaderValue, ICloneable
10 | {
11 | public double? Quality
12 | {
13 | get { return HeaderUtilities.GetQuality((ObjectCollection)Parameters); }
14 | set { HeaderUtilities.SetQuality((ObjectCollection)Parameters, value); }
15 | }
16 |
17 | internal TransferCodingWithQualityHeaderValue()
18 | {
19 | // Used by the parser to create a new instance of this type.
20 | }
21 |
22 | public TransferCodingWithQualityHeaderValue(string value)
23 | : base(value)
24 | {
25 | }
26 |
27 | public TransferCodingWithQualityHeaderValue(string value, double quality)
28 | : base(value)
29 | {
30 | Quality = quality;
31 | }
32 |
33 | private TransferCodingWithQualityHeaderValue(TransferCodingWithQualityHeaderValue source)
34 | : base(source)
35 | {
36 | // No additional members to initialize here. This constructor is used by Clone().
37 | }
38 |
39 | object ICloneable.Clone()
40 | {
41 | return new TransferCodingWithQualityHeaderValue(this);
42 | }
43 |
44 | public static new TransferCodingWithQualityHeaderValue Parse(string input)
45 | {
46 | int index = 0;
47 | return (TransferCodingWithQualityHeaderValue)TransferCodingHeaderParser.SingleValueWithQualityParser
48 | .ParseValue(input, null, ref index);
49 | }
50 |
51 | public static bool TryParse(string input, out TransferCodingWithQualityHeaderValue parsedValue)
52 | {
53 | int index = 0;
54 | object output;
55 | parsedValue = null;
56 |
57 | if (TransferCodingHeaderParser.SingleValueWithQualityParser.TryParseValue(
58 | input, null, ref index, out output))
59 | {
60 | parsedValue = (TransferCodingWithQualityHeaderValue)output;
61 | return true;
62 | }
63 | return false;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/HttpClientHandler.Core.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Globalization;
6 |
7 | namespace System.Net.Http
8 | {
9 | public partial class HttpClientHandler : HttpMessageHandler
10 | {
11 | // This partial implementation contains members common to Windows and Unix running on .NET Core.
12 |
13 | private volatile bool _operationStarted = false;
14 | private volatile bool _disposed = false;
15 |
16 | public long MaxRequestContentBufferSize
17 | {
18 | // This property is not supported. In the .NET Framework it was only used when the handler needed to
19 | // automatically buffer the request content. That only happened if neither 'Content-Length' nor
20 | // 'Transfer-Encoding: chunked' request headers were specified. So, the handler thus needed to buffer
21 | // in the request content to determine its length and then would choose 'Content-Length' semantics when
22 | // POST'ing. In .NET Core and UAP platforms, the handler will resolve the ambiguity by always choosing
23 | // 'Transfer-Encoding: chunked'. The handler will never automatically buffer in the request content.
24 | get
25 | {
26 | return 0; // Returning zero is appropriate since in .NET Framework it means no limit.
27 | }
28 |
29 | set
30 | {
31 | if (value < 0)
32 | {
33 | throw new ArgumentOutOfRangeException(nameof(value));
34 | }
35 |
36 | if (value > HttpContent.MaxBufferSize)
37 | {
38 | throw new ArgumentOutOfRangeException(nameof(value), value,
39 | SR.Format(CultureInfo.InvariantCulture, SR.net_http_content_buffersize_limit,
40 | HttpContent.MaxBufferSize));
41 | }
42 |
43 | CheckDisposedOrStarted();
44 |
45 | // No-op on property setter.
46 | }
47 | }
48 |
49 | private void CheckDisposed()
50 | {
51 | if (_disposed)
52 | {
53 | throw new ObjectDisposedException(GetType().ToString());
54 | }
55 | }
56 |
57 | private void CheckDisposedOrStarted()
58 | {
59 | CheckDisposed();
60 | if (_operationStarted)
61 | {
62 | throw new InvalidOperationException(SR.net_http_operation_started);
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.Net.Security;
7 | using System.Security.Cryptography.X509Certificates;
8 |
9 | namespace System.Net.Http
10 | {
11 | public partial class HttpClientHandler : HttpMessageHandler
12 | {
13 | // This partial implementation contains members common to all HttpClientHandler implementations.
14 | private const string SocketsHttpHandlerEnvironmentVariableSettingName = "DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER";
15 | private const string SocketsHttpHandlerAppCtxSettingName = "System.Net.Http.UseSocketsHttpHandler";
16 |
17 | private static bool UseSocketsHttpHandler
18 | {
19 | get
20 | {
21 | // First check for the AppContext switch, giving it priority over the environment variable.
22 | if (AppContext.TryGetSwitch(SocketsHttpHandlerAppCtxSettingName, out bool useSocketsHttpHandler))
23 | {
24 | return useSocketsHttpHandler;
25 | }
26 |
27 | // AppContext switch wasn't used. Check the environment variable to determine which handler should be used.
28 | string envVar = Environment.GetEnvironmentVariable(SocketsHttpHandlerEnvironmentVariableSettingName);
29 | if (envVar != null && (envVar.Equals("false", StringComparison.OrdinalIgnoreCase) || envVar.Equals("0")))
30 | {
31 | // Use WinHttpHandler on Windows and CurlHandler on Unix.
32 | return false;
33 | }
34 |
35 | // Default to using SocketsHttpHandler.
36 | return true;
37 | }
38 | }
39 |
40 | public static Func DangerousAcceptAnyServerCertificateValidator { get; } = delegate { return true; };
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/HttpClientHandler.netcoreapp.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Net.Security;
7 | using System.Security.Authentication;
8 | using System.Security.Cryptography.X509Certificates;
9 | using System.Threading;
10 | using System.Threading.Tasks;
11 |
12 | namespace System.Net.Http
13 | {
14 | // This partial implementation contains members common to NetCoreApp
15 | public partial class HttpClientHandler : HttpMessageHandler
16 | {
17 | private void ThrowForModifiedManagedSslOptionsIfStarted()
18 | {
19 | // Hack to trigger an InvalidOperationException if a property that's stored on
20 | // SslOptions is changed, since SslOptions itself does not do any such checks.
21 | _socketsHttpHandler.SslOptions = _socketsHttpHandler.SslOptions;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/HttpCompletionOption.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 |
9 | namespace System.Net.Http
10 | {
11 | public enum HttpCompletionOption
12 | {
13 | ResponseContentRead = 0,
14 | ResponseHeadersRead,
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/HttpMessageHandler.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace System.Net.Http
12 | {
13 | public abstract class HttpMessageHandler : IDisposable
14 | {
15 | protected HttpMessageHandler()
16 | {
17 | if (NetEventSource.IsEnabled) NetEventSource.Info(this);
18 | }
19 |
20 | protected internal abstract Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
21 |
22 | #region IDisposable Members
23 |
24 | protected virtual void Dispose(bool disposing)
25 | {
26 | // Nothing to do in base class.
27 | }
28 |
29 | public void Dispose()
30 | {
31 | Dispose(true);
32 | GC.SuppressFinalize(this);
33 | }
34 | #endregion
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/HttpMessageInvoker.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO;
6 | using System.Net.Http.Headers;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 |
10 | namespace System.Net.Http
11 | {
12 | public class HttpMessageInvoker : IDisposable
13 | {
14 | private volatile bool _disposed;
15 | private bool _disposeHandler;
16 | private HttpMessageHandler _handler;
17 |
18 | public HttpMessageInvoker(HttpMessageHandler handler)
19 | : this(handler, true)
20 | {
21 | }
22 |
23 | public HttpMessageInvoker(HttpMessageHandler handler, bool disposeHandler)
24 | {
25 | if (NetEventSource.IsEnabled) NetEventSource.Enter(this, handler);
26 |
27 | if (handler == null)
28 | {
29 | throw new ArgumentNullException(nameof(handler));
30 | }
31 |
32 | if (NetEventSource.IsEnabled) NetEventSource.Associate(this, handler);
33 |
34 | _handler = handler;
35 | _disposeHandler = disposeHandler;
36 |
37 | if (NetEventSource.IsEnabled) NetEventSource.Exit(this);
38 | }
39 |
40 | public virtual Task SendAsync(HttpRequestMessage request,
41 | CancellationToken cancellationToken)
42 | {
43 | if (request == null)
44 | {
45 | throw new ArgumentNullException(nameof(request));
46 | }
47 | CheckDisposed();
48 |
49 | if (NetEventSource.IsEnabled) NetEventSource.Enter(this, request);
50 |
51 | Task task = _handler.SendAsync(request, cancellationToken);
52 |
53 | if (NetEventSource.IsEnabled) NetEventSource.Exit(this, task);
54 |
55 | return task;
56 | }
57 |
58 | public void Dispose()
59 | {
60 | Dispose(true);
61 | GC.SuppressFinalize(this);
62 | }
63 |
64 | protected virtual void Dispose(bool disposing)
65 | {
66 | if (disposing && !_disposed)
67 | {
68 | _disposed = true;
69 |
70 | if (_disposeHandler)
71 | {
72 | _handler.Dispose();
73 | }
74 | }
75 | }
76 |
77 | private void CheckDisposed()
78 | {
79 | if (_disposed)
80 | {
81 | throw new ObjectDisposedException(GetType().ToString());
82 | }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/HttpParseResult.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Text;
7 |
8 | namespace System.Net.Http
9 | {
10 | internal enum HttpParseResult
11 | {
12 | Parsed,
13 | NotParsed,
14 | InvalidFormat,
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/HttpRequestException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics.CodeAnalysis;
6 | using System.IO;
7 |
8 | namespace System.Net.Http
9 | {
10 | [SuppressMessage("Microsoft.Serialization", "CA2229")]
11 | public class HttpRequestException : Exception
12 | {
13 | internal bool AllowRetry { get; }
14 |
15 | public HttpRequestException()
16 | : this(null, null)
17 | { }
18 |
19 | public HttpRequestException(string message)
20 | : this(message, null)
21 | { }
22 |
23 | public HttpRequestException(string message, Exception inner)
24 | : base(message, inner)
25 | {
26 | if (inner != null)
27 | {
28 | HResult = inner.HResult;
29 | }
30 | }
31 |
32 | // This constructor is used internally to indicate that a request was not successfully sent due to an IOException,
33 | // and the exception occurred early enough so that the request may be retried on another connection.
34 | internal HttpRequestException(string message, Exception inner, bool allowRetry)
35 | : this(message, inner)
36 | {
37 | AllowRetry = allowRetry;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/HttpUtilities.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.Threading.Tasks;
7 | using System.Threading;
8 |
9 | namespace System.Net.Http
10 | {
11 | internal static class HttpUtilities
12 | {
13 | internal static Version DefaultRequestVersion =>
14 | #if uap
15 | HttpVersion.Version20;
16 | #else
17 | HttpVersion.Version11;
18 | #endif
19 |
20 | internal static Version DefaultResponseVersion => HttpVersion.Version11;
21 |
22 | internal static bool IsHttpUri(Uri uri)
23 | {
24 | Debug.Assert(uri != null);
25 | return IsSupportedScheme(uri.Scheme);
26 | }
27 |
28 | internal static bool IsSupportedScheme(string scheme) =>
29 | IsSupportedNonSecureScheme(scheme) ||
30 | IsSupportedSecureScheme(scheme);
31 |
32 | internal static bool IsSupportedNonSecureScheme(string scheme) =>
33 | string.Equals(scheme, "http", StringComparison.OrdinalIgnoreCase) || IsNonSecureWebSocketScheme(scheme);
34 |
35 | internal static bool IsSupportedSecureScheme(string scheme) =>
36 | string.Equals(scheme, "https", StringComparison.OrdinalIgnoreCase) || IsSecureWebSocketScheme(scheme);
37 |
38 | internal static bool IsNonSecureWebSocketScheme(string scheme) =>
39 | string.Equals(scheme, "ws", StringComparison.OrdinalIgnoreCase);
40 |
41 | internal static bool IsSecureWebSocketScheme(string scheme) =>
42 | string.Equals(scheme, "wss", StringComparison.OrdinalIgnoreCase);
43 |
44 | // Always specify TaskScheduler.Default to prevent us from using a user defined TaskScheduler.Current.
45 | //
46 | // Since we're not doing any CPU and/or I/O intensive operations, continue on the same thread.
47 | // This results in better performance since the continuation task doesn't get scheduled by the
48 | // scheduler and there are no context switches required.
49 | internal static Task ContinueWithStandard(this Task task, object state, Action, object> continuation)
50 | {
51 | return task.ContinueWith(continuation, state, CancellationToken.None,
52 | TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/ReadOnlyMemoryContent.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO;
6 | using System.Runtime.InteropServices;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 |
10 | namespace System.Net.Http
11 | {
12 | public sealed class ReadOnlyMemoryContent : HttpContent
13 | {
14 | private readonly ReadOnlyMemory _content;
15 |
16 | public ReadOnlyMemoryContent(ReadOnlyMemory content)
17 | {
18 | _content = content;
19 | if (MemoryMarshal.TryGetArray(content, out ArraySegment array))
20 | {
21 | // If we have an array, allow HttpClient to take optimized paths by just
22 | // giving it the array content to use as its already buffered data.
23 | SetBuffer(array.Array, array.Offset, array.Count);
24 | }
25 | }
26 |
27 | protected override Task SerializeToStreamAsync(Stream stream, TransportContext context) =>
28 | stream.WriteAsync(_content).AsTask();
29 |
30 | internal override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) =>
31 | stream.WriteAsync(_content, cancellationToken).AsTask();
32 |
33 | protected internal override bool TryComputeLength(out long length)
34 | {
35 | length = _content.Length;
36 | return true;
37 | }
38 |
39 | protected override Task CreateContentReadStreamAsync() =>
40 | Task.FromResult(new ReadOnlyMemoryStream(_content));
41 |
42 | internal override Stream TryCreateContentReadStream() =>
43 | new ReadOnlyMemoryStream(_content);
44 |
45 | internal override bool AllowDuplex => false;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CancellationHelper.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace System.Net.Http
9 | {
10 | /// Provides utilities related to cancellation.
11 | internal static class CancellationHelper
12 | {
13 | /// The default message used by .
14 | private static readonly string s_cancellationMessage = new OperationCanceledException().Message; // use same message as the default ctor
15 |
16 | /// Determines whether to wrap an in a cancellation exception.
17 | /// The exception.
18 | /// The that may have triggered the exception.
19 | /// true if the exception should be wrapped; otherwise, false.
20 | internal static bool ShouldWrapInOperationCanceledException(Exception exception, CancellationToken cancellationToken) =>
21 | !(exception is OperationCanceledException) && cancellationToken.IsCancellationRequested;
22 |
23 | /// Creates a cancellation exception.
24 | /// The inner exception to wrap. May be null.
25 | /// The that triggered the cancellation.
26 | /// The cancellation exception.
27 | internal static Exception CreateOperationCanceledException(Exception innerException, CancellationToken cancellationToken) =>
28 | new TaskCanceledException(s_cancellationMessage, innerException, cancellationToken); // TCE for compatibility with other handlers that use TaskCompletionSource.TrySetCanceled()
29 |
30 | /// Throws a cancellation exception.
31 | /// The inner exception to wrap. May be null.
32 | /// The that triggered the cancellation.
33 | private static void ThrowOperationCanceledException(Exception innerException, CancellationToken cancellationToken) =>
34 | throw CreateOperationCanceledException(innerException, cancellationToken);
35 |
36 | /// Throws a cancellation exception if cancellation has been requested via .
37 | /// The token to check for a cancellation request.
38 | internal static void ThrowIfCancellationRequested(CancellationToken cancellationToken)
39 | {
40 | if (cancellationToken.IsCancellationRequested)
41 | {
42 | ThrowOperationCanceledException(innerException:null, cancellationToken);
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingWriteStream.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace System.Net.Http
10 | {
11 | internal partial class HttpConnection : IDisposable
12 | {
13 | private sealed class ChunkedEncodingWriteStream : HttpContentWriteStream
14 | {
15 | private static readonly byte[] s_finalChunkBytes = { (byte)'0', (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' };
16 |
17 | public ChunkedEncodingWriteStream(HttpConnection connection) : base(connection)
18 | {
19 | }
20 |
21 | public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken ignored)
22 | {
23 | HttpConnection connection = GetConnectionOrThrow();
24 | Debug.Assert(connection._currentRequest != null);
25 |
26 | // The token is ignored because it's coming from SendAsync and the only operations
27 | // here are those that are already covered by the token having been registered with
28 | // to close the connection.
29 |
30 | ValueTask task = buffer.Length == 0 ?
31 | // Don't write if nothing was given, especially since we don't want to accidentally send a 0 chunk,
32 | // which would indicate end of body. Instead, just ensure no content is stuck in the buffer.
33 | connection.FlushAsync() :
34 | new ValueTask(WriteChunkAsync(connection, buffer));
35 |
36 | return task;
37 |
38 | static async Task WriteChunkAsync(HttpConnection connection, ReadOnlyMemory buffer)
39 | {
40 | // Write chunk length in hex followed by \r\n
41 | await connection.WriteHexInt32Async(buffer.Length).ConfigureAwait(false);
42 | await connection.WriteTwoBytesAsync((byte)'\r', (byte)'\n').ConfigureAwait(false);
43 |
44 | // Write chunk contents followed by \r\n
45 | await connection.WriteAsync(buffer).ConfigureAwait(false);
46 | await connection.WriteTwoBytesAsync((byte)'\r', (byte)'\n').ConfigureAwait(false);
47 | }
48 | }
49 |
50 | public override async Task FinishAsync()
51 | {
52 | // Send 0 byte chunk to indicate end, then final CrLf
53 | HttpConnection connection = GetConnectionOrThrow();
54 | _connection = null;
55 | await connection.WriteBytesAsync(s_finalChunkBytes).ConfigureAwait(false);
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthWriteStream.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace System.Net.Http
10 | {
11 | internal partial class HttpConnection : IDisposable
12 | {
13 | private sealed class ContentLengthWriteStream : HttpContentWriteStream
14 | {
15 | public ContentLengthWriteStream(HttpConnection connection) : base(connection)
16 | {
17 | }
18 |
19 | public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken ignored) // token ignored as it comes from SendAsync
20 | {
21 | // Have the connection write the data, skipping the buffer. Importantly, this will
22 | // force a flush of anything already in the buffer, i.e. any remaining request headers
23 | // that are still buffered.
24 | HttpConnection connection = GetConnectionOrThrow();
25 | Debug.Assert(connection._currentRequest != null);
26 | return new ValueTask(connection.WriteAsync(buffer));
27 | }
28 |
29 | public override Task FinishAsync()
30 | {
31 | _connection = null;
32 | return Task.CompletedTask;
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CookieHelper.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Net.Http.Headers;
6 | using System.Diagnostics;
7 | using System.Collections.Generic;
8 |
9 | namespace System.Net.Http
10 | {
11 | internal static class CookieHelper
12 | {
13 | public static void ProcessReceivedCookies(HttpResponseMessage response, CookieContainer cookieContainer)
14 | {
15 | IEnumerable values;
16 | if (response.Headers.TryGetValues(KnownHeaders.SetCookie.Descriptor, out values))
17 | {
18 | // The header values are always a string[]
19 | var valuesArray = (string[])values;
20 | Debug.Assert(valuesArray.Length > 0, "No values for header??");
21 |
22 | Uri requestUri = response.RequestMessage.RequestUri;
23 | for (int i = 0; i < valuesArray.Length; i++)
24 | {
25 | try
26 | {
27 | cookieContainer.SetCookies(requestUri, valuesArray[i]);
28 | }
29 | catch (CookieException)
30 | {
31 | // Ignore invalid Set-Cookie header and continue processing.
32 | if (NetEventSource.IsEnabled)
33 | {
34 | NetEventSource.Error(response, $"Invalid Set-Cookie '{valuesArray[i]}' ignored.");
35 | }
36 | }
37 | }
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/EmptyReadStream.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace System.Net.Http
10 | {
11 | internal sealed class EmptyReadStream : HttpBaseStream
12 | {
13 | internal static EmptyReadStream Instance { get; } = new EmptyReadStream();
14 |
15 | private EmptyReadStream() { }
16 |
17 | public override bool CanRead => true;
18 | public override bool CanWrite => false;
19 |
20 | protected override void Dispose(bool disposing) { /* nop */ }
21 | public override void Close() { /* nop */ }
22 |
23 | public override int Read(Span buffer) => 0;
24 |
25 | public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken) =>
26 | cancellationToken.IsCancellationRequested ? new ValueTask(Task.FromCanceled(cancellationToken)) :
27 | new ValueTask(0);
28 |
29 | public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
30 | {
31 | ValidateCopyToArgs(this, destination, bufferSize);
32 | return NopAsync(cancellationToken);
33 | }
34 |
35 | public override void Write(ReadOnlySpan buffer) => throw new NotSupportedException(SR.net_http_content_readonly_stream);
36 |
37 | public override ValueTask WriteAsync(ReadOnlyMemory destination, CancellationToken cancellationToken) => throw new NotSupportedException();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ExposedSocketNetworkStream.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Sockets
6 | {
7 | // TODO: Delete once https://github.com/dotnet/corefx/issues/35410 is available.
8 | internal sealed class ExposedSocketNetworkStream : NetworkStream
9 | {
10 | public ExposedSocketNetworkStream(Socket socket, bool ownsSocket) : base(socket, ownsSocket) { }
11 |
12 | public new Socket Socket => base.Socket;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HPack/DynamicTable.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0.
3 | // See THIRD-PARTY-NOTICES.TXT in the project root for license information.
4 |
5 | namespace System.Net.Http.HPack
6 | {
7 | internal class DynamicTable
8 | {
9 | private HeaderField[] _buffer;
10 | private int _maxSize;
11 | private int _size;
12 | private int _count;
13 | private int _insertIndex;
14 | private int _removeIndex;
15 |
16 | public DynamicTable(int maxSize)
17 | {
18 | _buffer = new HeaderField[maxSize / HeaderField.RfcOverhead];
19 | _maxSize = maxSize;
20 | }
21 |
22 | public int Count => _count;
23 |
24 | public int Size => _size;
25 |
26 | public int MaxSize => _maxSize;
27 |
28 | public HeaderField this[int index]
29 | {
30 | get
31 | {
32 | if (index >= _count)
33 | {
34 | throw new IndexOutOfRangeException();
35 | }
36 |
37 | return _buffer[_insertIndex == 0 ? _buffer.Length - 1 : _insertIndex - index - 1];
38 | }
39 | }
40 |
41 | public void Insert(ReadOnlySpan name, ReadOnlySpan value)
42 | {
43 | int entryLength = HeaderField.GetLength(name.Length, value.Length);
44 | EnsureAvailable(entryLength);
45 |
46 | if (entryLength > _maxSize)
47 | {
48 | // http://httpwg.org/specs/rfc7541.html#rfc.section.4.4
49 | // It is not an error to attempt to add an entry that is larger than the maximum size;
50 | // an attempt to add an entry larger than the maximum size causes the table to be emptied
51 | // of all existing entries and results in an empty table.
52 | return;
53 | }
54 |
55 | var entry = new HeaderField(name, value);
56 | _buffer[_insertIndex] = entry;
57 | _insertIndex = (_insertIndex + 1) % _buffer.Length;
58 | _size += entry.Length;
59 | _count++;
60 | }
61 |
62 | public void Resize(int maxSize)
63 | {
64 | // TODO: What would cause us to need to grow the table size? The connection-level limit should prevent this, right?
65 | // Understand this better. If we do need to resize, we may want a better resize strategy.
66 | if (maxSize > _maxSize)
67 | {
68 | var newBuffer = new HeaderField[maxSize / HeaderField.RfcOverhead];
69 |
70 | for (var i = 0; i < Count; i++)
71 | {
72 | newBuffer[i] = _buffer[i];
73 | }
74 |
75 | _buffer = newBuffer;
76 | _maxSize = maxSize;
77 | }
78 | else
79 | {
80 | _maxSize = maxSize;
81 | EnsureAvailable(0);
82 | }
83 | }
84 |
85 | private void EnsureAvailable(int available)
86 | {
87 | while (_count > 0 && _maxSize - _size < available)
88 | {
89 | _size -= _buffer[_removeIndex].Length;
90 | _count--;
91 | _removeIndex = (_removeIndex + 1) % _buffer.Length;
92 | }
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HPack/HPackDecodingException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0.
3 | // See THIRD-PARTY-NOTICES.TXT in the project root for license information.
4 |
5 | using System.Runtime.Serialization;
6 |
7 | namespace System.Net.Http.HPack
8 | {
9 | // TODO: Should this be public?
10 | [Serializable]
11 | internal class HPackDecodingException : Exception
12 | {
13 | public HPackDecodingException()
14 | {
15 | }
16 |
17 | public HPackDecodingException(string message) : base(message)
18 | {
19 | }
20 |
21 | public HPackDecodingException(string message, Exception innerException) : base(message, innerException)
22 | {
23 | }
24 |
25 | public HPackDecodingException(SerializationInfo info, StreamingContext context) : base(info, context)
26 | {
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HPack/HeaderField.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0.
3 | // See THIRD-PARTY-NOTICES.TXT in the project root for license information.
4 |
5 | namespace System.Net.Http.HPack
6 | {
7 | internal struct HeaderField
8 | {
9 | // http://httpwg.org/specs/rfc7541.html#rfc.section.4.1
10 | public const int RfcOverhead = 32;
11 |
12 | public HeaderField(ReadOnlySpan name, ReadOnlySpan value)
13 | {
14 | // TODO: We're allocating here on every new table entry.
15 | // That means a poorly-behaved server could cause us to allocate repeatedly.
16 | // We should revisit our allocation strategy here so we don't need to allocate per entry
17 | // and we have a cap to how much allocation can happen per dynamic table
18 | // (without limiting the number of table entries a server can provide within the table size limit).
19 | Name = new byte[name.Length];
20 | name.CopyTo(Name);
21 |
22 | Value = new byte[value.Length];
23 | value.CopyTo(Value);
24 | }
25 |
26 | public byte[] Name { get; }
27 |
28 | public byte[] Value { get; }
29 |
30 | public int Length => GetLength(Name.Length, Value.Length);
31 |
32 | public static int GetLength(int nameLength, int valueLenth) => nameLength + valueLenth + 32;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HPack/HuffmanDecodingException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0.
3 | // See THIRD-PARTY-NOTICES.TXT in the project root for license information.
4 |
5 | using System.Runtime.Serialization;
6 |
7 | namespace System.Net.Http.HPack
8 | {
9 | // TODO: Should this be public?
10 | [Serializable]
11 | internal class HuffmanDecodingException : Exception
12 | {
13 | public HuffmanDecodingException()
14 | {
15 | }
16 |
17 | public HuffmanDecodingException(SerializationInfo info, StreamingContext context)
18 | : base(info, context)
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HPack/IntegerEncoder.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0.
3 | // See THIRD-PARTY-NOTICES.TXT in the project root for license information.
4 |
5 | using System.Diagnostics;
6 |
7 | namespace System.Net.Http.HPack
8 | {
9 | internal static class IntegerEncoder
10 | {
11 | ///
12 | /// Encodes an integer into one or more bytes.
13 | ///
14 | /// The value to encode. Must not be negative.
15 | /// The length of the prefix, in bits, to encode within. Must be between 1 and 8.
16 | /// The destination span to encode to.
17 | /// The number of bytes used to encode .
18 | /// If had enough storage to encode , true. Otherwise, false.
19 | public static bool Encode(int value, int numBits, Span destination, out int bytesWritten)
20 | {
21 | Debug.Assert(value >= 0);
22 | Debug.Assert(numBits >= 1 && numBits <= 8);
23 |
24 | if (destination.Length == 0)
25 | {
26 | bytesWritten = 0;
27 | return false;
28 | }
29 |
30 | destination[0] &= MaskHigh(8 - numBits);
31 |
32 | if (value < (1 << numBits) - 1)
33 | {
34 | destination[0] |= (byte)value;
35 |
36 | bytesWritten = 1;
37 | return true;
38 | }
39 | else
40 | {
41 | destination[0] |= (byte)((1 << numBits) - 1);
42 |
43 | if (1 == destination.Length)
44 | {
45 | bytesWritten = 0;
46 | return false;
47 | }
48 |
49 | value = value - ((1 << numBits) - 1);
50 | int i = 1;
51 |
52 | while (value >= 128)
53 | {
54 | destination[i++] = (byte)(value % 128 + 128);
55 |
56 | if (i >= destination.Length)
57 | {
58 | bytesWritten = 0;
59 | return false;
60 | }
61 |
62 | value = value / 128;
63 | }
64 | destination[i++] = (byte)value;
65 |
66 | bytesWritten = i;
67 | return true;
68 | }
69 | }
70 |
71 | private static byte MaskHigh(int n) => (byte)(sbyte.MinValue >> (n - 1));
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2ConnectionException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Runtime.Serialization;
6 |
7 | namespace System.Net.Http
8 | {
9 | [Serializable]
10 | internal sealed class Http2ConnectionException : Http2ProtocolException
11 | {
12 | public Http2ConnectionException(Http2ProtocolErrorCode protocolError)
13 | : base(SR.Format(SR.net_http_http2_connection_error, GetName(protocolError), ((int)protocolError).ToString("x")), protocolError)
14 | {
15 | }
16 |
17 | private Http2ConnectionException(SerializationInfo info, StreamingContext context) : base(info, context) { }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2ProtocolErrorCode.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | // NOTE: If any additional error codes are added here, they should also be added to Http2ProtocolException's mapping.
8 |
9 | ///
10 | /// Error codes defined by the HTTP/2 protocol, used in RST_STREAM and GOAWAY frames to convey the reasons for the stream or connection error.
11 | /// https://http2.github.io/http2-spec/#PROTOCOL_ERROR
12 | ///
13 | internal enum Http2ProtocolErrorCode
14 | {
15 | /// The associated condition is not a result of an error.
16 | NoError = 0x0,
17 | /// The endpoint detected an unspecific protocol error. This error is for use when a more specific error code is not available.
18 | ProtocolError = 0x1,
19 | /// The endpoint encountered an unexpected internal error.
20 | InternalError = 0x2,
21 | /// The endpoint detected that its peer violated the flow-control protocol.
22 | FlowControlError = 0x3,
23 | /// The endpoint sent a SETTINGS frame but did not receive a response in a timely manner.
24 | SettingsTimeout = 0x4,
25 | /// The endpoint received a frame after a stream was half-closed.
26 | StreamClosed = 0x5,
27 | /// The endpoint received a frame with an invalid size.
28 | FrameSizeError = 0x6,
29 | /// The endpoint refused the stream prior to performing any application processing.
30 | RefusedStream = 0x7,
31 | /// Used by the endpoint to indicate that the stream is no longer needed.
32 | Cancel = 0x8,
33 | /// The endpoint is unable to maintain the header compression context for the connection.
34 | CompressionError = 0x9,
35 | /// The connection established in response to a CONNECT request was reset or abnormally closed.
36 | ConnectError = 0xa,
37 | /// The endpoint detected that its peer is exhibiting a behavior that might be generating excessive load.
38 | EnhanceYourCalm = 0xb,
39 | /// The underlying transport has properties that do not meet minimum security requirements.
40 | InadequateSecurity = 0xc,
41 | /// The endpoint requires that HTTP/1.1 be used instead of HTTP/2.
42 | Http11Required = 0xd
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2ProtocolException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Runtime.Serialization;
6 |
7 | namespace System.Net.Http
8 | {
9 | [Serializable]
10 | internal abstract class Http2ProtocolException : Exception
11 | {
12 | public Http2ProtocolException(string message, Http2ProtocolErrorCode protocolError)
13 | : base(message)
14 | {
15 | ProtocolError = protocolError;
16 | }
17 |
18 | protected Http2ProtocolException(SerializationInfo info, StreamingContext context) : base(info, context)
19 | {
20 | ProtocolError = (Http2ProtocolErrorCode)info.GetInt32(nameof(ProtocolError));
21 | }
22 |
23 | public override void GetObjectData(SerializationInfo info, StreamingContext context)
24 | {
25 | info.AddValue(nameof(ProtocolError), (int)ProtocolError);
26 | base.GetObjectData(info, context);
27 | }
28 |
29 | internal Http2ProtocolErrorCode ProtocolError { get; }
30 |
31 | protected static string GetName(Http2ProtocolErrorCode code)
32 | {
33 | // These strings are the names used in the HTTP2 spec and should not be localized.
34 | switch (code)
35 | {
36 | case Http2ProtocolErrorCode.NoError:
37 | return "NO_ERROR";
38 | case Http2ProtocolErrorCode.ProtocolError:
39 | return "PROTOCOL_ERROR";
40 | case Http2ProtocolErrorCode.InternalError:
41 | return "INTERNAL_ERROR";
42 | case Http2ProtocolErrorCode.FlowControlError:
43 | return "FLOW_CONTROL_ERROR";
44 | case Http2ProtocolErrorCode.SettingsTimeout:
45 | return "SETTINGS_TIMEOUT";
46 | case Http2ProtocolErrorCode.StreamClosed:
47 | return "STREAM_CLOSED";
48 | case Http2ProtocolErrorCode.FrameSizeError:
49 | return "FRAME_SIZE_ERROR";
50 | case Http2ProtocolErrorCode.RefusedStream:
51 | return "REFUSED_STREAM";
52 | case Http2ProtocolErrorCode.Cancel:
53 | return "CANCEL";
54 | case Http2ProtocolErrorCode.CompressionError:
55 | return "COMPRESSION_ERROR";
56 | case Http2ProtocolErrorCode.ConnectError:
57 | return "CONNECT_ERROR";
58 | case Http2ProtocolErrorCode.EnhanceYourCalm:
59 | return "ENHANCE_YOUR_CALM";
60 | case Http2ProtocolErrorCode.InadequateSecurity:
61 | return "INADEQUATE_SECURITY";
62 | case Http2ProtocolErrorCode.Http11Required:
63 | return "HTTP_1_1_REQUIRED";
64 | default:
65 | return "(unknown error)";
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2StreamException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Runtime.Serialization;
6 |
7 | namespace System.Net.Http
8 | {
9 | [Serializable]
10 | internal sealed class Http2StreamException : Http2ProtocolException
11 | {
12 | public Http2StreamException(Http2ProtocolErrorCode protocolError)
13 | : base(SR.Format(SR.net_http_http2_stream_error, GetName(protocolError), ((int)protocolError).ToString("x")), protocolError)
14 | {
15 | }
16 |
17 | private Http2StreamException(SerializationInfo info, StreamingContext context) : base(info, context) { }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpAuthenticatedConnectionHandler.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace System.Net.Http
9 | {
10 | internal sealed class HttpAuthenticatedConnectionHandler : HttpMessageHandler
11 | {
12 | private readonly HttpConnectionPoolManager _poolManager;
13 |
14 | public HttpAuthenticatedConnectionHandler(HttpConnectionPoolManager poolManager)
15 | {
16 | _poolManager = poolManager;
17 | }
18 |
19 | protected internal override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
20 | {
21 | return _poolManager.SendAsync(request, doRequestAuth:true, cancellationToken);
22 | }
23 |
24 | protected override void Dispose(bool disposing)
25 | {
26 | if (disposing)
27 | {
28 | _poolManager.Dispose();
29 | }
30 |
31 | base.Dispose(disposing);
32 | }
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionHandler.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace System.Net.Http
9 | {
10 | internal sealed class HttpConnectionHandler : HttpMessageHandler
11 | {
12 | private readonly HttpConnectionPoolManager _poolManager;
13 |
14 | public HttpConnectionHandler(HttpConnectionPoolManager poolManager)
15 | {
16 | _poolManager = poolManager;
17 | }
18 |
19 | protected internal override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
20 | {
21 | return _poolManager.SendAsync(request, doRequestAuth:false, cancellationToken);
22 | }
23 |
24 | protected override void Dispose(bool disposing)
25 | {
26 | if (disposing)
27 | {
28 | _poolManager.Dispose();
29 | }
30 |
31 | base.Dispose(disposing);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionKind.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal enum HttpConnectionKind : byte
8 | {
9 | Http, // Non-secure connection with no proxy.
10 | Https, // Secure connection with no proxy.
11 | Proxy, // HTTP proxy usage for non-secure (HTTP) requests.
12 | ProxyTunnel, // Non-secure websocket (WS) connection using CONNECT tunneling through proxy.
13 | SslProxyTunnel, // HTTP proxy usage for secure (HTTPS/WSS) requests using SSL and proxy CONNECT.
14 | ProxyConnect // Connection used for proxy CONNECT. Tunnel will be established on top of this.
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionResponseContent.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.IO;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 |
10 | namespace System.Net.Http
11 | {
12 | internal sealed class HttpConnectionResponseContent : HttpContent
13 | {
14 | private Stream _stream;
15 | private bool _consumedStream; // separate from _stream so that Dispose can drain _stream
16 |
17 | public void SetStream(Stream stream)
18 | {
19 | Debug.Assert(stream != null);
20 | Debug.Assert(stream.CanRead);
21 | Debug.Assert(!_consumedStream);
22 |
23 | _stream = stream;
24 | }
25 |
26 | private Stream ConsumeStream()
27 | {
28 | if (_consumedStream || _stream == null)
29 | {
30 | throw new InvalidOperationException(SR.net_http_content_stream_already_read);
31 | }
32 | _consumedStream = true;
33 |
34 | return _stream;
35 | }
36 |
37 | protected sealed override Task SerializeToStreamAsync(Stream stream, TransportContext context) =>
38 | SerializeToStreamAsync(stream, context, CancellationToken.None);
39 |
40 | internal sealed override async Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken)
41 | {
42 | Debug.Assert(stream != null);
43 |
44 | using (Stream contentStream = ConsumeStream())
45 | {
46 | const int BufferSize = 8192;
47 | await contentStream.CopyToAsync(stream, BufferSize, cancellationToken).ConfigureAwait(false);
48 | }
49 | }
50 |
51 | protected internal sealed override bool TryComputeLength(out long length)
52 | {
53 | length = 0;
54 | return false;
55 | }
56 |
57 | protected sealed override Task CreateContentReadStreamAsync() =>
58 | Task.FromResult(ConsumeStream());
59 |
60 | internal sealed override Stream TryCreateContentReadStream() =>
61 | ConsumeStream();
62 |
63 | internal override bool AllowDuplex => false;
64 |
65 | protected sealed override void Dispose(bool disposing)
66 | {
67 | if (disposing)
68 | {
69 | if (_stream != null)
70 | {
71 | _stream.Dispose();
72 | _stream = null;
73 | }
74 | }
75 |
76 | base.Dispose(disposing);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentStream.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal abstract class HttpContentStream : HttpBaseStream
8 | {
9 | protected HttpConnection _connection;
10 |
11 | public HttpContentStream(HttpConnection connection)
12 | {
13 | _connection = connection;
14 | }
15 |
16 | protected override void Dispose(bool disposing)
17 | {
18 | if (disposing)
19 | {
20 | if (_connection != null)
21 | {
22 | _connection.Dispose();
23 | _connection = null;
24 | }
25 | }
26 |
27 | base.Dispose(disposing);
28 | }
29 |
30 | protected HttpConnection GetConnectionOrThrow()
31 | {
32 | return _connection ??
33 | // This should only ever happen if the user-code that was handed this instance disposed of
34 | // it, which is misuse, or held onto it and tried to use it later after we've disposed of it,
35 | // which is also misuse.
36 | ThrowObjectDisposedException();
37 | }
38 |
39 | private HttpConnection ThrowObjectDisposedException() => throw new ObjectDisposedException(GetType().Name);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpContentWriteStream.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics;
6 | using System.IO;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 |
10 | namespace System.Net.Http
11 | {
12 | internal partial class HttpConnection : IDisposable
13 | {
14 | private abstract class HttpContentWriteStream : HttpContentStream
15 | {
16 | public HttpContentWriteStream(HttpConnection connection) : base(connection) =>
17 | Debug.Assert(connection != null);
18 |
19 | public sealed override bool CanRead => false;
20 | public sealed override bool CanWrite => true;
21 |
22 | public sealed override void Flush() =>
23 | _connection?.Flush();
24 |
25 | public sealed override Task FlushAsync(CancellationToken ignored)
26 | {
27 | HttpConnection connection = _connection;
28 | return connection != null ?
29 | connection.FlushAsync().AsTask() :
30 | default;
31 | }
32 |
33 | public sealed override int Read(Span buffer) => throw new NotSupportedException();
34 |
35 | public sealed override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken) => throw new NotSupportedException();
36 |
37 | public sealed override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) => throw new NotSupportedException();
38 |
39 | public abstract Task FinishAsync();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Unix.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal sealed partial class HttpEnvironmentProxy : IWebProxy
8 | {
9 | public static bool TryCreate(out IWebProxy proxy)
10 | {
11 | // Get environment variables. Protocol specific take precedence over
12 | // general all_*, lower case variable has precedence over upper case.
13 | // Note that curl uses HTTPS_PROXY but not HTTP_PROXY.
14 |
15 | Uri httpProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpProxyLC));
16 | if (httpProxy == null && Environment.GetEnvironmentVariable(EnvCGI) == null)
17 | {
18 | httpProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpProxyUC));
19 | }
20 |
21 | Uri httpsProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpsProxyLC)) ??
22 | GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpsProxyUC));
23 |
24 | if (httpProxy == null || httpsProxy == null)
25 | {
26 | Uri allProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvAllProxyLC)) ??
27 | GetUriFromString(Environment.GetEnvironmentVariable(EnvAllProxyUC));
28 |
29 | if (httpProxy == null)
30 | {
31 | httpProxy = allProxy;
32 | }
33 |
34 | if (httpsProxy == null)
35 | {
36 | httpsProxy = allProxy;
37 | }
38 | }
39 |
40 | // Do not instantiate if nothing is set.
41 | // Caller may pick some other proxy type.
42 | if (httpProxy == null && httpsProxy == null)
43 | {
44 | proxy = null;
45 | return false;
46 | }
47 |
48 | string noProxy = Environment.GetEnvironmentVariable(EnvNoProxyLC) ??
49 | Environment.GetEnvironmentVariable(EnvNoProxyUC);
50 | proxy = new HttpEnvironmentProxy(httpProxy, httpsProxy, noProxy);
51 |
52 | return true;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpEnvironmentProxy.Windows.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal sealed partial class HttpEnvironmentProxy : IWebProxy
8 | {
9 | public static bool TryCreate(out IWebProxy proxy)
10 | {
11 | // Get environment variables. Protocol specific take precedence over
12 | // general all_*. On Windows, environment variables are case insensitive.
13 |
14 | Uri httpProxy = null;
15 | if (Environment.GetEnvironmentVariable(EnvCGI) == null)
16 | {
17 | httpProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpProxyUC));
18 | }
19 |
20 | Uri httpsProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvHttpsProxyUC));
21 |
22 | if (httpProxy == null || httpsProxy == null)
23 | {
24 | Uri allProxy = GetUriFromString(Environment.GetEnvironmentVariable(EnvAllProxyUC));
25 |
26 | if (httpProxy == null)
27 | {
28 | httpProxy = allProxy;
29 | }
30 |
31 | if (httpsProxy == null)
32 | {
33 | httpsProxy = allProxy;
34 | }
35 | }
36 |
37 | // Do not instantiate if nothing is set.
38 | // Caller may pick some other proxy type.
39 | if (httpProxy == null && httpsProxy == null)
40 | {
41 | proxy = null;
42 | return false;
43 | }
44 |
45 | string noProxy = Environment.GetEnvironmentVariable(EnvNoProxyUC);
46 | proxy = new HttpEnvironmentProxy(httpProxy, httpsProxy, noProxy);
47 |
48 | return true;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpNoProxy.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal sealed class HttpNoProxy : IWebProxy
8 | {
9 | public ICredentials Credentials { get; set; }
10 | public Uri GetProxy(Uri destination) => null;
11 | public bool IsBypassed(Uri host) => true;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/IHttpTrace.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace System.Net.Http
8 | {
9 | internal interface IHttpTrace
10 | {
11 | void Trace(string message, [CallerMemberName] string memberName = null);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.OSX.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal static partial class SystemProxyInfo
8 | {
9 | // On OSX we get default proxy configuration from either environment variables or the OSX system proxy.
10 | public static IWebProxy ConstructSystemProxy()
11 | {
12 | return HttpEnvironmentProxy.TryCreate(out IWebProxy proxy) ? proxy : new MacProxy();
13 | }
14 | }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Unix.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal static partial class SystemProxyInfo
8 | {
9 | // On Unix (except for OSX) we get default proxy configuration from environment variables. If the
10 | // environment variables are not defined, we return an IWebProxy object that effectively is
11 | // the "no proxy" object.
12 | public static IWebProxy ConstructSystemProxy()
13 | {
14 | return HttpEnvironmentProxy.TryCreate(out IWebProxy proxy) ? proxy : new HttpNoProxy();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.Windows.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal static partial class SystemProxyInfo
8 | {
9 | // On Windows we get default proxy configuration from either environment variables or the Windows system proxy.
10 | public static IWebProxy ConstructSystemProxy()
11 | {
12 | if (!HttpEnvironmentProxy.TryCreate(out IWebProxy proxy))
13 | {
14 | HttpWindowsProxy.TryCreate(out proxy);
15 | }
16 |
17 | return proxy ?? new HttpNoProxy();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal static partial class SystemProxyInfo
8 | {
9 | public static IWebProxy Proxy => s_proxy.Value;
10 |
11 | private static readonly Lazy s_proxy = new Lazy(ConstructSystemProxy);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/SystemProxyInfo.uap.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | namespace System.Net.Http
6 | {
7 | internal static partial class SystemProxyInfo
8 | {
9 | public static IWebProxy ConstructSystemProxy()
10 | {
11 | // For UAP this is currently not implemented.
12 | return new HttpNoProxy();
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/TaskCompletionSourceWithCancellation.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace System.Net.Http
9 | {
10 | internal class TaskCompletionSourceWithCancellation : TaskCompletionSource
11 | {
12 | private CancellationToken _cancellationToken;
13 |
14 | public TaskCompletionSourceWithCancellation() : base(TaskCreationOptions.RunContinuationsAsynchronously)
15 | {
16 | }
17 |
18 | private void OnCancellation()
19 | {
20 | TrySetCanceled(_cancellationToken);
21 | }
22 |
23 | public async Task WaitWithCancellationAsync(CancellationToken cancellationToken)
24 | {
25 | _cancellationToken = cancellationToken;
26 | using (cancellationToken.UnsafeRegister(s => ((TaskCompletionSourceWithCancellation)s).OnCancellation(), this))
27 | {
28 | return await Task.ConfigureAwait(false);
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/System/Net/Http/StringContent.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO;
6 | using System.Net.Http.Headers;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace System.Net.Http
12 | {
13 | public class StringContent : ByteArrayContent
14 | {
15 | private const string DefaultMediaType = "text/plain";
16 |
17 | public StringContent(string content)
18 | : this(content, null, null)
19 | {
20 | }
21 |
22 | public StringContent(string content, Encoding encoding)
23 | : this(content, encoding, null)
24 | {
25 | }
26 |
27 | public StringContent(string content, Encoding encoding, string mediaType)
28 | : base(GetContentByteArray(content, encoding))
29 | {
30 | // Initialize the 'Content-Type' header with information provided by parameters.
31 | MediaTypeHeaderValue headerValue = new MediaTypeHeaderValue((mediaType == null) ? DefaultMediaType : mediaType);
32 | headerValue.CharSet = (encoding == null) ? HttpContent.DefaultStringEncoding.WebName : encoding.WebName;
33 |
34 | Headers.ContentType = headerValue;
35 | }
36 |
37 | // A StringContent is essentially a ByteArrayContent. We serialize the string into a byte-array in the
38 | // constructor using encoding information provided by the caller (if any). When this content is sent, the
39 | // Content-Length can be retrieved easily (length of the array).
40 | private static byte[] GetContentByteArray(string content, Encoding encoding)
41 | {
42 | // In this case we treat 'null' strings different from string.Empty in order to be consistent with our
43 | // other *Content constructors: 'null' throws, empty values are allowed.
44 | if (content == null)
45 | {
46 | throw new ArgumentNullException(nameof(content));
47 | }
48 |
49 | if (encoding == null)
50 | {
51 | encoding = HttpContent.DefaultStringEncoding;
52 | }
53 |
54 | return encoding.GetBytes(content);
55 | }
56 |
57 | internal override Task SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) =>
58 | // Only skip the original protected virtual SerializeToStreamAsync if this
59 | // isn't a derived type that may have overridden the behavior.
60 | GetType() == typeof(StringContent) ? SerializeToStreamAsyncCore(stream, cancellationToken) :
61 | base.SerializeToStreamAsync(stream, context, cancellationToken);
62 |
63 | internal override Stream TryCreateContentReadStream() =>
64 | GetType() == typeof(StringContent) ? CreateMemoryStreamForByteArray() : // type check ensures we use possible derived type's CreateContentReadStreamAsync override
65 | null;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/uap/System/Net/CookieHelper.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Net.Internal;
8 | using InternalCookieException = System.Net.Internal.CookieException;
9 |
10 | namespace System.Net
11 | {
12 | internal static class CookieHelper
13 | {
14 | internal static IEnumerable GetCookiesFromHeader(string setCookieHeader)
15 | {
16 | List cookieStrings = new List();
17 |
18 | try
19 | {
20 | CookieParser parser = new CookieParser(setCookieHeader);
21 | string cookieString;
22 |
23 | while ((cookieString = parser.GetString()) != null)
24 | {
25 | cookieStrings.Add(cookieString);
26 | }
27 | }
28 | catch (InternalCookieException)
29 | {
30 | // TODO (#7856): We should log this. But there isn't much we can do about it other
31 | // than to drop the rest of the cookies.
32 | }
33 |
34 | return cookieStrings;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/System.Net.Http/src/uap/System/Net/cookieexception.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Diagnostics.CodeAnalysis;
6 |
7 | // The uap #define is used in some source files to indicate we are compiling classes
8 | // directly into the UWP System.Net.Http.dll implementation assembly in order to use internal class
9 | // methods. Internal methods are needed in order to map cookie response headers from the WinRT Windows.Web.Http APIs.
10 | // Windows.Web.Http is used underneath the System.Net.Http classes on .NET Native. Having other similarly
11 | // named classes would normally conflict with the public System.Net namespace classes.
12 | // So, we need to move the classes to a different namespace. Those classes are never
13 | // exposed up to user code so there isn't a problem. In the future, we might expose some of the internal methods
14 | // as new public APIs and then we can remove this duplicate source code inclusion in the binaries.
15 | #if uap
16 | namespace System.Net.Internal
17 | #else
18 | namespace System.Net
19 | #endif
20 | {
21 | ///
22 | /// [To be supplied.]
23 | ///
24 | public class CookieException : FormatException
25 | {
26 | ///
27 | /// [To be supplied.]
28 | ///
29 | public CookieException() : base()
30 | {
31 | }
32 |
33 | internal CookieException(string message) : base(message)
34 | {
35 | }
36 |
37 | internal CookieException(string message, Exception inner) : base(message, inner)
38 | {
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/System.Net.Http/tests/FunctionalTests/ByteAtATimeContent.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO;
6 | using System.Threading.Tasks;
7 |
8 | namespace System.Net.Http.Functional.Tests
9 | {
10 | internal sealed class ByteAtATimeContent : HttpContent
11 | {
12 | private readonly Task _waitToSend;
13 | private readonly TaskCompletionSource _startedSend;
14 | private readonly int _length;
15 | private readonly int _millisecondDelayBetweenBytes;
16 |
17 | public ByteAtATimeContent(int length) : this(length, Task.CompletedTask, new TaskCompletionSource(), millisecondDelayBetweenBytes: 0) { }
18 |
19 | public ByteAtATimeContent(int length, Task waitToSend, TaskCompletionSource startedSend, int millisecondDelayBetweenBytes)
20 | {
21 | _length = length;
22 | _waitToSend = waitToSend;
23 | _startedSend = startedSend;
24 | _millisecondDelayBetweenBytes = millisecondDelayBetweenBytes;
25 | }
26 |
27 | protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
28 | {
29 | await _waitToSend;
30 | _startedSend.SetResult(true);
31 |
32 | var buffer = new byte[1];
33 | for (int i = 0; i < _length; i++)
34 | {
35 | buffer[0] = (byte)i;
36 | await stream.WriteAsync(buffer);
37 | await stream.FlushAsync();
38 | await Task.Delay(_millisecondDelayBetweenBytes);
39 | }
40 | }
41 |
42 | protected override bool TryComputeLength(out long length)
43 | {
44 | length = _length;
45 | return true;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/System.Net.Http/tests/FunctionalTests/ChannelBindingAwareContent.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO;
6 | using System.Security.Authentication.ExtendedProtection;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace System.Net.Http.Functional.Tests
11 | {
12 | internal sealed class ChannelBindingAwareContent : HttpContent
13 | {
14 | private readonly byte[] _content;
15 |
16 | public ChannelBindingAwareContent(string content)
17 | {
18 | _content = Encoding.UTF8.GetBytes(content);
19 | }
20 |
21 | public ChannelBinding ChannelBinding { get ; private set; }
22 |
23 | protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
24 | {
25 | ChannelBinding = context.GetChannelBinding(ChannelBindingKind.Endpoint);
26 | return stream.WriteAsync(_content, 0, _content.Length);
27 | }
28 |
29 | protected override bool TryComputeLength(out long length)
30 | {
31 | length = _content.Length;
32 | return true;
33 | }
34 |
35 | protected override Task CreateContentReadStreamAsync()
36 | {
37 | return Task.FromResult(new MemoryStream(_content, 0, _content.Length, writable: false));
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/System.Net.Http/tests/FunctionalTests/Configurations.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp-Windows_NT;
5 | netcoreapp-Unix;
6 | uap-Windows_NT;
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/System.Net.Http/tests/FunctionalTests/CustomContent.netcore.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace System.Net.Http.Functional.Tests
10 | {
11 | internal partial class CustomContent : HttpContent
12 | {
13 | internal class SlowTestStream : CustomStream
14 | {
15 | private int _delay = 1000;
16 | private int _count;
17 | private int _trigger;
18 | private byte[] _content;
19 | private readonly TaskCompletionSource _sendingDone;
20 | private int _iteration;
21 |
22 | internal SlowTestStream(byte[] content, TaskCompletionSource tsc, int count=10, int trigger=1) : base(content, false)
23 | {
24 | _sendingDone = tsc;
25 | _trigger = trigger;
26 | _count = count;
27 | _content = content;
28 | }
29 |
30 | public override async Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
31 | {
32 | var buffer = new byte[bufferSize];
33 | int bytesRead;
34 | while ((bytesRead = await ReadAsync(buffer, cancellationToken)) != 0)
35 | {
36 | await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken);
37 | await destination.FlushAsync(); // some tests rely on data being written promptly to coordinate between client/server sides of test
38 | }
39 | }
40 |
41 | public async override ValueTask ReadAsync(Memory destination, CancellationToken cancellationToken)
42 | {
43 | if (_failException != null)
44 | {
45 | throw _failException;
46 | }
47 |
48 | if (_delay > 0)
49 | {
50 | await Task.Delay(_delay, cancellationToken);
51 | }
52 |
53 | _iteration++;
54 | if (_iteration == _trigger)
55 | {
56 | _sendingDone?.TrySetResult(true);
57 | }
58 |
59 | if (_count == _iteration)
60 | {
61 | return 0;
62 | }
63 |
64 | return _content.Length;
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/System.Net.Http/tests/FunctionalTests/DribbleStream.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.IO;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace System.Net.Http.Functional.Tests
10 | {
11 | public sealed class DribbleStream : Stream
12 | {
13 | private readonly Stream _wrapped;
14 | private readonly bool _clientDisconnectAllowed;
15 |
16 | public DribbleStream(Stream wrapped, bool clientDisconnectAllowed = false)
17 | {
18 | _wrapped = wrapped;
19 | _clientDisconnectAllowed = clientDisconnectAllowed;
20 | }
21 |
22 | public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
23 | {
24 | try
25 | {
26 | for (int i = 0; i < count; i++)
27 | {
28 | await _wrapped.WriteAsync(buffer, offset + i, 1);
29 | await _wrapped.FlushAsync();
30 | await Task.Yield(); // introduce short delays, enough to send packets individually but not so long as to extend test duration significantly
31 | }
32 | }
33 | catch (IOException) when (_clientDisconnectAllowed)
34 | {
35 | }
36 | }
37 |
38 | public override void Write(byte[] buffer, int offset, int count)
39 | {
40 | try
41 | {
42 | for (int i = 0; i < count; i++)
43 | {
44 | _wrapped.Write(buffer, offset + i, 1);
45 | _wrapped.Flush();
46 | }
47 | }
48 | catch (IOException) when (_clientDisconnectAllowed)
49 | {
50 | }
51 | }
52 |
53 | public override bool CanRead => _wrapped.CanRead;
54 | public override bool CanSeek => _wrapped.CanSeek;
55 | public override bool CanWrite => _wrapped.CanWrite;
56 | public override long Length => _wrapped.Length;
57 | public override long Position { get => _wrapped.Position; set => _wrapped.Position = value; }
58 | public override void Flush() => _wrapped.Flush();
59 | public override Task FlushAsync(CancellationToken cancellationToken) => _wrapped.FlushAsync(cancellationToken);
60 | public override int Read(byte[] buffer, int offset, int count) => _wrapped.Read(buffer, offset, count);
61 | public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => _wrapped.ReadAsync(buffer, offset, count, cancellationToken);
62 | public override long Seek(long offset, SeekOrigin origin) => _wrapped.Seek(offset, origin);
63 | public override void SetLength(long value) => _wrapped.SetLength(value);
64 | public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) => _wrapped.CopyToAsync(destination, bufferSize, cancellationToken);
65 | public override void Close() => _wrapped.Close();
66 | protected override void Dispose(bool disposing) => _wrapped.Dispose();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/System.Net.Http/tests/FunctionalTests/FakeDiagnosticSourceListenerObserver.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 |
8 | namespace System.Net.Http.Functional.Tests
9 | {
10 | public sealed class FakeDiagnosticListenerObserver : IObserver
11 | {
12 | private class FakeDiagnosticSourceWriteObserver : IObserver>
13 | {
14 | private readonly Action> _writeCallback;
15 |
16 | public FakeDiagnosticSourceWriteObserver(Action> writeCallback)
17 | {
18 | _writeCallback = writeCallback;
19 | }
20 |
21 | public void OnCompleted()
22 | {
23 | }
24 |
25 | public void OnError(Exception error)
26 | {
27 | }
28 |
29 | public void OnNext(KeyValuePair value)
30 | {
31 | _writeCallback(value);
32 | }
33 | }
34 |
35 | private readonly Action> _writeCallback;
36 |
37 | private Func _writeObserverEnabled = (name, arg1, arg2) => false;
38 |
39 | public FakeDiagnosticListenerObserver(Action> writeCallback)
40 | {
41 | _writeCallback = writeCallback;
42 | }
43 |
44 | public void OnCompleted()
45 | {
46 | }
47 |
48 | public void OnError(Exception error)
49 | {
50 | }
51 |
52 | public void OnNext(DiagnosticListener value)
53 | {
54 | if (value.Name.Equals("HttpHandlerDiagnosticListener"))
55 | {
56 | value.Subscribe(new FakeDiagnosticSourceWriteObserver(_writeCallback), IsEnabled);
57 | }
58 | }
59 |
60 | public void Enable()
61 | {
62 | _writeObserverEnabled = (name, arg1, arg2) => true;
63 | }
64 |
65 | public void Enable(Func writeObserverEnabled)
66 | {
67 | _writeObserverEnabled = (name, arg1, arg2) => writeObserverEnabled(name);
68 | }
69 |
70 | public void Enable(Func writeObserverEnabled)
71 | {
72 | _writeObserverEnabled = writeObserverEnabled;
73 | }
74 |
75 | public void Disable()
76 | {
77 | _writeObserverEnabled = (name, arg1, arg2) => false;
78 | }
79 |
80 | private bool IsEnabled(string s, object arg1, object arg2)
81 | {
82 | return _writeObserverEnabled.Invoke(s, arg1, arg2);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/System.Net.Http/tests/FunctionalTests/HPackTest.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 | // See the LICENSE file in the project root for more information.
4 |
5 | using System;
6 | using System.Collections;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Diagnostics;
10 | using System.IO;
11 | using System.Net.Test.Common;
12 | using System.Text;
13 | using System.Threading;
14 | using System.Threading.Tasks;
15 | using Xunit;
16 | using Xunit.Abstractions;
17 | using System.Data;
18 | using System.Runtime.InteropServices.ComTypes;
19 |
20 | namespace System.Net.Http.Functional.Tests
21 | {
22 | public class HPackTest : HttpClientHandlerTestBase
23 | {
24 | protected override bool UseSocketsHttpHandler => true;
25 | protected override bool UseHttp2 => true;
26 |
27 | public HPackTest(ITestOutputHelper output) : base(output)
28 | {
29 | }
30 |
31 | private const string LiteralHeaderName = "x-literal-header";
32 | private const string LiteralHeaderValue = "testing 456";
33 |
34 | [Theory]
35 | [MemberData(nameof(HeaderEncodingTestData))]
36 | public async Task HPack_HeaderEncoding(string headerName, string expectedValue, byte[] expectedEncoding)
37 | {
38 | await Http2LoopbackServer.CreateClientAndServerAsync(
39 | async uri =>
40 | {
41 | using HttpClient client = CreateHttpClient();
42 |
43 | using HttpRequestMessage request = new HttpRequestMessage();
44 | request.Method = HttpMethod.Post;
45 | request.RequestUri = uri;
46 | request.Version = HttpVersion.Version20;
47 | request.Content = new StringContent("testing 123");
48 | request.Headers.Add(LiteralHeaderName, LiteralHeaderValue);
49 |
50 | (await client.SendAsync(request)).Dispose();
51 | },
52 | async server =>
53 | {
54 | Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
55 | (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync();
56 |
57 | HttpHeaderData header = requestData.Headers.Single(x => x.Name == headerName);
58 | Assert.Equal(expectedValue, header.Value);
59 | Assert.True(expectedEncoding.AsSpan().SequenceEqual(header.Raw));
60 |
61 | await connection.SendDefaultResponseAsync(streamId);
62 | });
63 | }
64 |
65 | public static IEnumerable