Website GET from code fails

User avatar
katit
Уже с Приветом
Posts: 23960
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Website GET from code fails

Post by katit »

Website GET from code fails

Раньше работало. Сейчас перестало.

https://www.iftach.org/taxmatrix/charts/4Q2017.xml

Код простяцкий:

Code: Select all

var request = WebRequest.Create(uri) as HttpWebRequest;
                using (var response = request.GetResponse() as HttpWebResponse)
                {
                    // Get the response stream  
                    var stream = response?.GetResponseStream();
                    if (stream != null)
                    {
                        var reader = new StreamReader(stream);
                        return reader.ReadToEnd();
                    }
                }
Ошибка:

Code: Select all

Authentication failed because the remote party has closed the transport stream.
Думал может чего не то с хидерами(может сайт решил проверять агентов например). Посмотрел как работает в Фиддлере, ТОЖЕ САМОЕ вставил в Фиддлере чтобы заэмулировать запрос и оно также там не работает.

Что за фигня?
Лучше водки — хуже нет! ©
nightmare2
Уже с Приветом
Posts: 7187
Joined: 31 Jan 2005 15:06
Location: GA

Re: Website GET from code fails

Post by nightmare2 »

Нашли проблему?
Возможно я не прав так как не особо разбираюсь в секьюрити, но это похоже на броблему с Transport Layer Security (TLS).
Кажется .net использует какой-то из TLS по умолчанию.
Может тут проблема?
Vaiyo A-O, A Home Va Ya Ray, Vaiyo A-Rah, Jerhume Brunnen G!
User avatar
VovaK98
Уже с Приветом
Posts: 1828
Joined: 04 Mar 2002 10:01
Location: Tampa

Re: Website GET from code fails

Post by VovaK98 »

Добавь вверху

Code: Select all

[Flags]
    private enum MySecurityProtocolType
    {
        //
        // Summary:
        //     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
        Ssl3 = 48,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
        Tls = 192,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
        Tls11 = 768,
        //
        // Summary:
        //     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
        Tls12 = 3072
    }
    
а в коде уже вот это

Code: Select all

System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls);

Вот весь мой тестовый код (windows forms project):

Code: Select all

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Security;

namespace test_web_dwnld {
	public partial class Form1:Form {
		[Flags]
		private enum MySecurityProtocolType
		{
			//
			// Summary:
			//     Specifies the Secure Socket Layer (SSL) 3.0 security protocol.
			Ssl3 = 48,
			//
			// Summary:
			//     Specifies the Transport Layer Security (TLS) 1.0 security protocol.
			Tls = 192,
			//
			// Summary:
			//     Specifies the Transport Layer Security (TLS) 1.1 security protocol.
			Tls11 = 768,
			//
			// Summary:
			//     Specifies the Transport Layer Security (TLS) 1.2 security protocol.
			Tls12 = 3072
		}

		public Form1() {
			InitializeComponent();
		}

		private void button1_Click(object sender,EventArgs e) {
			string LastError = "";
			string s_result = "";
			string tmpurl = "https://www.iftach.org/TaxMatrix/charts/4Q2017.xml";
			WebClient wc = null;
			try {
				wc = new WebClient();
				wc.Encoding = Encoding.UTF8;
				System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)(MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls);
				byte[] result = wc.DownloadData(tmpurl);
				if (result!=null && result.Length>0) {
					s_result = Encoding.UTF8.GetString(result);
				}
			} catch (WebException wex) {
				string response = "";
				if (wex.InnerException!=null)
					response = wex.InnerException.ToString();
				LastError = wex.Message;
				LastError = LastError + "\r\n" + response;
			} catch (Exception ex) {
				LastError = ex.Message;
			} finally {
				if (wc!=null)
					wc.Dispose();
			}
		}
	}
}




P.S. Извиняюсь, если уже не актуально. Только час назад этот пост увидел.
Несите чушь бережно, стараясь не расплескать. Чушь хороша, когда она полная.
User avatar
katit
Уже с Приветом
Posts: 23960
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Re: Website GET from code fails

Post by katit »

Спасибо! Код запускается раз в квартал, так что я уже руками чего надо сделал. Но надо пофиксить будет. Но что-то новенькое, раньше не видел.

Самое интереснот что Фиддлер падает также как и моя прога, у них там тоже простяцкий код на .NET видимо :)
Лучше водки — хуже нет! ©
User avatar
Boriskin
Уже с Приветом
Posts: 18862
Joined: 30 Aug 2001 09:01
Location: 3rd planet

Re: Website GET from code fails

Post by Boriskin »

Если код не менялся ни там, ни тут - то стоит посмотреть на сертификаты, может что-то заэкспайрилось или не поддерживается больше и теперь по умолчанию отваливается.
Last edited by Boriskin on 11 Jan 2018 19:21, edited 2 times in total.
Тупизна как Энтропия. Неумолимо растет.
User avatar
VovaK98
Уже с Приветом
Posts: 1828
Joined: 04 Mar 2002 10:01
Location: Tampa

Re: Website GET from code fails

Post by VovaK98 »

katit wrote: 11 Jan 2018 18:58 Самое интереснот что Фиддлер падает также как и моя прога, у них там тоже простяцкий код на .NET видимо :)
Эта бодяга, похоже, началась по мере перехода на новые SHA-256 SSL сертификаты.
У фидлера, скорее всего, старый Framework крутится. Мой код выше патчит проблему как раз для более старого фреймворка (4.0 и старше).

В 4.6 уже TLS 1.2 прописан, так что одной такой строки д.б. достаточно:

Code: Select all

System.Net.ServicePointManager.SecurityProtocol = MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls;
Несите чушь бережно, стараясь не расплескать. Чушь хороша, когда она полная.
User avatar
katit
Уже с Приветом
Posts: 23960
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Re: Website GET from code fails

Post by katit »

VovaK98 wrote: 11 Jan 2018 19:18
katit wrote: 11 Jan 2018 18:58 Самое интереснот что Фиддлер падает также как и моя прога, у них там тоже простяцкий код на .NET видимо :)
Эта бодяга, похоже, началась по мере перехода на новые SHA-256 SSL сертификаты.
У фидлера, скорее всего, старый Framework крутится. Мой код выше патчит проблему как раз для более старого фреймворка (4.0 и старше).

В 4.6 уже TLS 1.2 прописан, так что одной такой строки д.б. достаточно:

Code: Select all

System.Net.ServicePointManager.SecurityProtocol = MySecurityProtocolType.Tls12 | MySecurityProtocolType.Tls11 | MySecurityProtocolType.Tls;
Похоже как это глобальная засада! Строку правильнее написать так:

Code: Select all

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
Проблема только в том что это будет настройка всего AppDomain
ВРОДЕ как вот этот конфиг вверху у народа работает (и оно работает в конкретном случае). Но я сегодня работал над "апгрейдом" одного из веб сервисов который требует тлс12. У меня в одном сервице интеграции с десятками провайдеров. Вот и пойми чего сейчас сломается :( Нет возможность контролировать на уровне одного клиента/запроса.
Лучше водки — хуже нет! ©
User avatar
VovaK98
Уже с Приветом
Posts: 1828
Joined: 04 Mar 2002 10:01
Location: Tampa

Re: Website GET from code fails

Post by VovaK98 »

katit wrote: 05 Feb 2018 20:36 Похоже как это глобальная засада! Строку правильнее написать так:

Code: Select all

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
Проблема только в том что это будет настройка всего AppDomain
ВРОДЕ как вот этот конфиг вверху у народа работает (и оно работает в конкретном случае). Но я сегодня работал над "апгрейдом" одного из веб сервисов который требует тлс12. У меня в одном сервице интеграции с десятками провайдеров. Вот и пойми чего сейчас сломается :( Нет возможность контролировать на уровне одного клиента/запроса.
Да, наверное, лучше все протоколы сразу подключить. Ну, заработало и слава богу. :fr:
Если опять сломается, заявимся с лопатами и вилами починим коллективными усилиями :)
Несите чушь бережно, стараясь не расплескать. Чушь хороша, когда она полная.
User avatar
katit
Уже с Приветом
Posts: 23960
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Re: Website GET from code fails

Post by katit »

VovaK98 wrote: 06 Feb 2018 01:13
katit wrote: 05 Feb 2018 20:36 Похоже как это глобальная засада! Строку правильнее написать так:

Code: Select all

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
Проблема только в том что это будет настройка всего AppDomain
ВРОДЕ как вот этот конфиг вверху у народа работает (и оно работает в конкретном случае). Но я сегодня работал над "апгрейдом" одного из веб сервисов который требует тлс12. У меня в одном сервице интеграции с десятками провайдеров. Вот и пойми чего сейчас сломается :( Нет возможность контролировать на уровне одного клиента/запроса.
Да, наверное, лучше все протоколы сразу подключить. Ну, заработало и слава богу. :fr:
Если опять сломается, заявимся с лопатами и вилами починим коллективными усилиями :)
Так проблме "ширше". Настройка покрывает весь AppDomain. Починив это, оно может поламать что-то другое. А контролировать on "case by case" basis низзя :( Только делить AppDomains..
Лучше водки — хуже нет! ©
User avatar
VovaK98
Уже с Приветом
Posts: 1828
Joined: 04 Mar 2002 10:01
Location: Tampa

Re: Website GET from code fails

Post by VovaK98 »

katit wrote: 06 Feb 2018 01:23 Так проблме "ширше". Настройка покрывает весь AppDomain. Починив это, оно может поламать что-то другое. А контролировать on "case by case" basis низзя :( Только делить AppDomains..
Да вроде всё должно работать. Мы же не сервер пишем, где можно случайно поломать весь application pool, а клиента.
Опять же, согласно концепции фреймворка, в одном приложении может быть несколько AppDomains. Можно попробовать локализовать в отдельный app thread.
Вот тут пишут, как искусственно отделить appdomain, хотя мне кажется, что как-то сложновато. В качестве прототипа я бы сначала просто сделал отдельный тред, а если не пойдёт, то можно вынести в отдельный appdomain, или даже в другое приложение.
Несите чушь бережно, стараясь не расплескать. Чушь хороша, когда она полная.
User avatar
katit
Уже с Приветом
Posts: 23960
Joined: 05 Jul 2003 22:34
Location: Брест -> St. Louis, MO

Re: Website GET from code fails

Post by katit »

VovaK98 wrote: 06 Feb 2018 01:52
katit wrote: 06 Feb 2018 01:23 Так проблме "ширше". Настройка покрывает весь AppDomain. Починив это, оно может поламать что-то другое. А контролировать on "case by case" basis низзя :( Только делить AppDomains..
Да вроде всё должно работать. Мы же не сервер пишем, где можно случайно поломать весь application pool, а клиента.
Опять же, согласно концепции фреймворка, в одном приложении может быть несколько AppDomains. Можно попробовать локализовать в отдельный app thread.
Вот тут пишут, как искусственно отделить appdomain, хотя мне кажется, что как-то сложновато. В качестве прототипа я бы сначала просто сделал отдельный тред, а если не пойдёт, то можно вынести в отдельный appdomain, или даже в другое приложение.
Да, в данном случае это не проблема. Но я сегодня правил в другом месте, а там монстр-сервис который аггрегирует данные от тучи провайдеров. И все в MEF Imports/etc. Там разделять на AppDomains будет не так тривиально. Но ладно, посмотрим, будем по мере появления проблемы решать.
Лучше водки — хуже нет! ©

Return to “Вопросы и новости IT”