아주 나쁜 html을위한 HtmlAgilityPack에있는 Stackoverflow 예외를 방지하는 방법

c# html-agility-pack stack-overflow

문제

MVC 5 Web API에서 HtmlAgilityPack을 사용하고 있습니다. 시간의 99.99 %, 아무 문제도 없다 ... 위치 짐 및 나가 원하는 원본을 추출하기 위하여 그 (것)들을 분석한다. 내 API는 문제없이 하루에 수십만 번 치게 될 수 있습니다. 과거 24 시간 동안 2 백만 건이 넘는 조회수를 행복하게 처리했습니다 ...

그러나 때때로 몹시 형성된 웹 사이트는 오류 500 응답을 유발합니다. 모든 후속 요청에 500 개의 오류가 발생하고 사이트를 완전히 사용할 수 없게됩니다. 이 시나리오의 유일한 해결책은 웹 응용 프로그램을 다시 시작하는 것입니다. 이 사이트는 Windows Azure에서 호스팅됩니다. 부하 평형 대용량 인스턴스를 사용하고 CPU 스파이크가 높으면 높게 유지됩니다. 과거에는 하나의 Medium Azure 인스턴스 (2 코어 / 3.5GB RAM)에서 정상적으로 실행되었습니다.

오류는 Stackoverflow ... 나는 내가 잡을 수 없다는 것을 알고 있습니다.

이 코드는 콘솔 응용 프로그램을 충돌시키지 않습니다.

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load("http://nursingandmidwiferycareersni.com/");            
Console.Write(doc.DocumentNode.InnerText);

...하지만 그것은 확실히 MVC 웹 응용 프로그램을 중단합니다.

그러나 간단한 MVC 웹 응용 프로그램에서 http://nursingandmidwiferycareersni.com/ 과 같은 사이트에서 stackoverflow 오류를 재현 할 수 있습니다. http://nursingandmidwiferycareersni.com/https://validator.w3.org에 넣으면 validator.w3.org에 내부 서버 오류가 발생합니다!

이 문제를 해결하기 위해 필요한 경우 HAP 소스 코드를 해킹 할 것입니다 ... 현재 Nuget 패키지 만 사용하고 있습니다.

HAP에서 발생하는 stackoverflow를 방지 할 수 있습니까?
아니면 끔찍한 html을 확인하고 충돌을 방지하는 방법이 있습니까?

인기 답변

ParseHtml 메서드와 ParsedHtml 형식을 입력하기 ParsedHtml 됩니다.

public async Task<ParsedHtml> TryParseHtml(
    string untrustedHtml,
    CancellationToken cancellationToken)
{
    var tcs = new TaskCompletionSource<ParsedHtml>();

    var thread = new Thread(() =>
    {
        ParsedHtml result = ParseHtml(untrustedHtml);
        tcs.TrySetResult(result);
    });
    thread.Start();

    using (cancellationToken.Register(() => tcs.TrySetCanceled()))
    {
        try
        {
            return await tcs.Task;
        }
        catch (OperationCanceledException)
        {
            thread.Abort();
            throw;
        }
    }
}

이 아이디어는 모든 HTML 페이지에 대해 스레드를 시작하고 찢어 버리는 것이 아니라 성공 사례에서 스레드를 다시 사용함으로써보다 효율적으로 확장 될 수 있습니다.



Related

아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow