protected HttpRequestResultInfo ProcessRuleRaw(HttpRequestUnitTestRule rule, ILogger logger) { var result = new HttpRequestResultInfo { ErrorCode = HttpRequestErrorCode.Success, Rule = rule, StartDate = DateTime.Now }; try { if (rule == null) { throw new ArgumentNullException("rule"); } logger.Debug("Правило: " + rule.DisplayName); if (string.IsNullOrWhiteSpace(rule.Url)) { result.ErrorCode = HttpRequestErrorCode.UrlFormatError; result.ErrorMessage = "Укажите URL"; return(result); } Uri uri = null; try { uri = new Uri(rule.Url); } catch (UriFormatException) { result.ErrorCode = HttpRequestErrorCode.UrlFormatError; result.ErrorMessage = "Неверный формат URL"; return(result); } if (new[] { "http", "https" }.Contains(uri.Scheme.ToLowerInvariant()) == false) { result.ErrorCode = HttpRequestErrorCode.UrlFormatError; result.ErrorMessage = "Неверная схема URI. Используйте http или https"; return(result); } if (NetworkHelper.IsDomainHasIp(uri.Host) == false) { result.ErrorCode = HttpRequestErrorCode.UnknownDomain; result.ErrorMessage = "Не удалось получить IP-адрес"; return(result); } var formDatas = rule.GetWebFormsDatas(); var requestHeaders = rule.GetRequestHeaders(); var requestCookies = rule.GetRequestCookies(); // установим таймаут var timeOutSeconds = rule.TimeoutSeconds ?? 60; if (timeOutSeconds > 60) { timeOutSeconds = 60; } // обновим URL if (rule.Method == HttpRequestMethod.Get && formDatas.Count > 0) { var uriBuilder = new UriBuilder(uri); var httpValueCollection = HttpUtility.ParseQueryString(uriBuilder.Uri.Query); foreach (var webFormData in formDatas) { httpValueCollection.Add(webFormData.Key, webFormData.Value); } uriBuilder.Query = httpValueCollection.ToString(); uri = uriBuilder.Uri; } // создадим запрос var request = (HttpWebRequest)WebRequest.Create(uri); logger.Debug("Uri: " + request.RequestUri.AbsoluteUri); request.MaximumAutomaticRedirections = 4; request.MaximumResponseHeadersLength = 20; request.Timeout = timeOutSeconds * 1000; request.ReadWriteTimeout = timeOutSeconds * 1000; result.Request = request; // добавим заголовки HTTP foreach (var header in requestHeaders) { if (string.Equals("User-Agent", header.Key, StringComparison.OrdinalIgnoreCase)) { request.UserAgent = header.Value; } else { request.Headers.Add(header.Key, header.Value); } } // Обязательно заполним UserAgent // Пустого UserAgent быть не должно // Многие сервера выдают ошибку из-за этого if (string.IsNullOrEmpty(request.UserAgent)) { request.UserAgent = "Zidium"; } // добавим куки foreach (var cookie in requestCookies) { request.CookieContainer.Add(new Cookie(cookie.Key, cookie.Value)); } // добавим данные веб-формы var postData = ""; if (rule.Method == HttpRequestMethod.Post) { request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; var httpValueCollection = HttpUtility.ParseQueryString(string.Empty); foreach (var formData in formDatas) { httpValueCollection.Add(formData.Key, formData.Value); } postData = httpValueCollection.ToString(); // данный метод внутри кодирует спец символы var data = Encoding.UTF8.GetBytes(postData); request.ContentLength = postData.Length; using (var dataStream = request.GetRequestStream()) { dataStream.Write(data, 0, data.Length); dataStream.Close(); } } // получаем ответ try { var response = (HttpWebResponse)request.GetResponse(); result.ErrorCode = CheckResponse(result, timeOutSeconds, response, logger); } catch (SocketException exception) { result.ErrorMessage = exception.Message; result.ErrorCode = HttpRequestErrorCode.TcpError; logger.Error(exception); } catch (IOException exception) { result.ErrorMessage = exception.Message; result.ErrorCode = HttpRequestErrorCode.TcpError; logger.Error(exception); } catch (WebException exception) { result.ErrorMessage = exception.Message; if (exception.Response != null) { var httpResponse = (HttpWebResponse)exception.Response; if (result.ResponseHeaders == null) { result.ResponseHeaders = GetResponseHeaders(httpResponse); } if (result.ResponseHtml == null) { result.ResponseHtml = GetResponseHtml(httpResponse); } if (result.HttpStatusCode == null) { result.HttpStatusCode = httpResponse.StatusCode; } } if (exception.Status == WebExceptionStatus.Timeout) { result.ErrorCode = HttpRequestErrorCode.Timeout; } else if (exception.Status == WebExceptionStatus.ProtocolError) { result.ErrorCode = HttpRequestErrorCode.InvalidResponseCode; } else { result.ErrorCode = HttpRequestErrorCode.TcpError; logger.Error(exception); } } } catch (WebException exception) { result.ErrorCode = HttpRequestErrorCode.TcpError; result.ErrorMessage = exception.Message; logger.Error(exception); } catch (Exception exception) { exception.Data.Add("UnitTestId", rule.HttpRequestUnitTest.UnitTestId); exception.Data.Add("RuleId", rule.Id); exception.Data.Add("RuleName", rule.DisplayName); exception.Data.Add("UnitTestName", rule.HttpRequestUnitTest.UnitTest.DisplayName); logger.Error(exception); result.ErrorCode = HttpRequestErrorCode.UnknownError; result.ErrorMessage = exception.Message; } finally { result.EndDate = DateTime.Now; logger.Info(result.Rule.Url + " => " + result.ErrorCode); } return(result); }
protected HttpRequestErrorCode CheckResponse( HttpRequestResultInfo httpResult, int timeOutSeconds, HttpWebResponse response, ILogger logger) { var rule = httpResult.Rule; httpResult.ErrorMessage = null; // headers httpResult.ResponseHeaders = response.Headers.ToString(); // html body var html = string.Empty; var responseStream = response.GetResponseStream(); if (responseStream != null) { var streamReader = new StreamReader(responseStream, Encoding.UTF8); //todo почему всегда Encoding.UTF8? html = streamReader.ReadToEnd(); } httpResult.ResponseHtml = html; // проверка responseCode httpResult.HttpStatusCode = response.StatusCode; var responseCode = (int)response.StatusCode; var validResponseCode = rule.ResponseCode ?? 200; if (responseCode != validResponseCode) { // неверный код ответа var message = string.Format( "Неверный ResponseCode (получено {0}, должно быть {1})", responseCode, validResponseCode); httpResult.ErrorMessage = message; logger.Info(message); logger.Debug("ReponseHtml: " + html); return(HttpRequestErrorCode.InvalidResponseCode); } // проверка ContentLength if (rule.MaxResponseSize > 0 && response.ContentLength > rule.MaxResponseSize) { // слишком большой ответ var message = string.Format( "Превышен ContentLength (получено {0}, должно быть максимум {1})", response.ContentLength, rule.MaxResponseSize); httpResult.ErrorMessage = message; logger.Info(message); return(HttpRequestErrorCode.TooLargeResponse); } // проверка timeOut var endTime = DateTime.Now; var duration = endTime - httpResult.StartDate; if (duration.TotalSeconds > timeOutSeconds) { // превышение тайматута var message = string.Format( "Превышен таймаут выполнения (получилось {0} секунд, должно быть максимум {1} секунд)", duration, timeOutSeconds); httpResult.ErrorMessage = message; logger.Info(message); return(HttpRequestErrorCode.Timeout); } if (string.IsNullOrEmpty(rule.SuccessHtml) == false && html.Contains(rule.SuccessHtml) == false) { // не найден обязательный фрагмент html var message = "Не найден обязательный фрагмент html"; if (message.Length > 90) { message = message.Substring(90) + "..."; } httpResult.ErrorMessage = message; logger.Info(message); return(HttpRequestErrorCode.SuccessHtmlNotFound); } if (string.IsNullOrEmpty(rule.ErrorHtml) == false && html.Contains(rule.ErrorHtml)) { // найден недопустимый фрагмент html var message = "Найден недопустимый фрагмент html: " + rule.ErrorHtml; if (message.Length > 90) { message = message.Substring(90) + "..."; } httpResult.ErrorMessage = message; logger.Info(message); return(HttpRequestErrorCode.ErrorHtmlFound); } // ура, все ОК return(HttpRequestErrorCode.Success); }