ブログ

割とコンピュータよりの情報をお届けします。

HttpClientは標準でProxy経由の通信になる

.NET FrameworkでHttpClientを使う機会があった.何も気にせずに使い始めると通信にProxyの設定が適用される.

.NET Framework 4.5からの機能だとおもうが,HttpClientというものが使えるようになった.TcpClientでは気にする必要があるKeepAlive/Httpsなどの実装を気にせずに使用できるようだ.参考となるページはHttpClientクラスでWebページを取得するには?[C#、VB]であろうか.
(ただこの記事が書かれた時と状況が異なる点がSystem.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;の部分である.現在では脆弱性の懸念から,SSL 3やTLS1.1などが無効化され始めており,最初からTLS1.2でつなげに行かなければ失敗するサーバーが多くなっている点である.)
さて,外のサーバーに接続する場合には
HttpClientHandler handler = new HttpClientHandler();
handler.UseProxy = false;
もいらない(はずである).
しかし,ローカルにプロキシサーバーを設けている場合にはローカルアドレスに対してプロキシを使用しない設定にしても,http://192.168.1.1/などにリクエストを送ろうとすると,Windows の仕様(ほぼバグ)によりプロキシを経由しようとする.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // 取得したいWebページのURI
            Uri webUri = new Uri("https://www.valuestar.work/");

            // Call the method "GetWebPageAsync"
            Task<string> webTask = GetWebPageAsync(webUri);
            webTask.Wait(); // Mainメソッド内でawaitのかわりの待機
            string result = webTask.Result;  // content of the result 

            Console.WriteLine(result);
#if DEBUG
            Console.ReadKey();
#endif
        }

        static async Task<string> GetWebPageAsync(Uri uri)
        {
            // Forced to use TLS1.2
            System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;

            // Setting: "Do not use proxy"
            HttpClientHandler handler = new HttpClientHandler();
            handler.UseProxy = false;

            using (HttpClient client = new HttpClient(handler))
            {

                // setting timeout (optional)
                client.Timeout = TimeSpan.FromSeconds(10.0);

                try
                {
                    // Main part of this function
                    return await client.GetStringAsync(uri);
                }
                catch (HttpRequestException e)
                {
                    // Related to HTTP
                    Console.WriteLine("\nHTTP Exception");
                    Exception ex = e;
                    while (ex != null)
                    {
                        Console.WriteLine(ex.Message);
                        ex = ex.InnerException;
                    }
                }
                catch (TaskCanceledException e)
                {
                    // Timeout
                    Console.WriteLine("\nTimeout");
                    Console.WriteLine(e.Message);
                }
                catch (Exception e)
                {
                    // Others
                    Console.WriteLine(e.Message);
                }
                return null;
            }
        }
    }
}

困った問題である.http://127.0.0.1/などはループバックなのにプロキシを経由されるというほぼバグ仕様によりデバッグ中に相当苦労させられた.

2019/04/24 コンピュータ   TakeMe
< Previous Article     To List     Next Article >

コメント送信フォーム


※ Email will not be published
Loading...
 Please enter the letters of the image