Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions src/OneScript.StandardLibrary/Http/HttpResponseBody.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*----------------------------------------------------------
/*----------------------------------------------------------
This Source Code Form is subject to the terms of the
Mozilla Public License, v.2.0. If a copy of the MPL
was not distributed with this file, You can obtain one
Expand All @@ -25,6 +25,7 @@ class HttpResponseBody : IDisposable

private readonly bool _autoDecompress;
private long _contentSize = 0;
private Stream _rawStream;

public HttpResponseBody(HttpWebResponse response, string dumpToFile)
{
Expand All @@ -33,17 +34,18 @@ public HttpResponseBody(HttpWebResponse response, string dumpToFile)
_inMemBody = Array.Empty<byte>();
return;
}


_rawStream = response.GetResponseStream();
_autoDecompress = string.Equals(response.ContentEncoding, "gzip", StringComparison.OrdinalIgnoreCase);
_contentSize = _autoDecompress ? -1 : response.ContentLength;

if (String.IsNullOrEmpty(dumpToFile))
if (!String.IsNullOrEmpty(dumpToFile))
{
InitInMemoryResponse(response);
InitFileBackedResponse(response, dumpToFile);
}
else
else if(_autoDecompress)
{
InitFileBackedResponse(response, dumpToFile);
InitInMemoryResponse(response);
}
}

Expand Down Expand Up @@ -78,12 +80,12 @@ public Stream OpenReadStream()
{
return new FileStream(_backingFileName, FileMode.Open, FileAccess.Read);
}
else if (_inMemBody != null)
{
return new MemoryStream(_inMemBody);
}
else if (_inMemBody != null)
{
return new MemoryStream(_inMemBody);
}
else
throw new InvalidOperationException("No response body");
return _rawStream;
}

private Stream GetResponseStream(HttpWebResponse response)
Expand Down
38 changes: 24 additions & 14 deletions src/OneScript.StandardLibrary/Http/HttpResponseContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*----------------------------------------------------------
/*----------------------------------------------------------
This Source Code Form is subject to the terms of the
Mozilla Public License, v.2.0. If a copy of the MPL
was not distributed with this file, You can obtain one
Expand Down Expand Up @@ -28,18 +28,25 @@ public class HttpResponseContext : AutoContext<HttpResponseContext>, IDisposable
// TODO: Нельзя выделить массив размером больше чем 2GB
// поэтому функционал сохранения в файл не должен использовать промежуточный буфер _body
private HttpResponseBody _body;

private HttpWebResponse _response;

private string _defaultCharset;
private string _filename;

public HttpResponseContext(HttpWebResponse response)
{
RetrieveResponseData(response, null);
}

public HttpResponseContext(HttpWebResponse response, string dumpToFile)
{
RetrieveResponseData(response, dumpToFile);
StatusCode = (int)response.StatusCode;
_defaultCharset = response.CharacterSet;

ProcessHeaders(response.Headers);
ProcessResponseBody(response, dumpToFile);
_response = response;

if (_body != null && _body.AutoDecompress)
{
_headers.Delete(ValueFactory.Create("Content-Encoding"));
_headers.SetIndexedValue(ValueFactory.Create("Content-Length"), ValueFactory.Create(_body.ContentSize));
}
}

private void RetrieveResponseData(HttpWebResponse response, string dumpToFile)
Expand Down Expand Up @@ -137,10 +144,10 @@ public IValue GetBodyAsBinaryData()
return ValueFactory.Create();

using (var stream = _body.OpenReadStream())
{
var data = new byte[stream.Length];
stream.Read(data, 0, data.Length);
return new BinaryDataContext(data);
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
return new BinaryDataContext(memoryStream.ToArray());
}
}

Expand Down Expand Up @@ -181,8 +188,11 @@ public void Close()

public void Dispose()
{
if (_body != null)
_body.Dispose();
_response?.Dispose();
_response = null;

_body?.Dispose();
_body = null;
}
}
}
90 changes: 90 additions & 0 deletions tests/http.os
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Перем юТест;

Перем мАдресРесурса; // URL ресурса (хоста) для тестирования запросов
Перем ПортТестовогоСервера;

Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт

Expand Down Expand Up @@ -36,6 +37,9 @@
ВсеТесты.Добавить("ТестДолженПроверитьЧтоМожноЗадатьТелоЗапросаСПомощьюПотока");

ВсеТесты.Добавить("ТестДолженПроверитьЧтоМетодыБезТелаПриУстановленномТелеУспешноВыполняются");
ВсеТесты.Добавить("ТестДолженПроверитьЧтоРаботаетПолучениеДвоичныхДанныхИзОтвета");

ВсеТесты.Добавить("ТестДолженПроверитьПолучениеStreamEvent");

Возврат ВсеТесты;
КонецФункции
Expand Down Expand Up @@ -376,6 +380,91 @@

КонецПроцедуры

Процедура ТестДолженПроверитьЧтоРаботаетПолучениеДвоичныхДанныхИзОтвета() Экспорт

Запрос = Новый HttpЗапрос("/bytes/10");
Соединение = Новый HttpСоединение(мАдресРесурса);
Ответ = Соединение.ВызватьHTTPМетод("GET", Запрос);

ДД = Ответ.ПолучитьТелоКакДвоичныеДанные();
юТест.ПроверитьТип(ДД, Тип("ДвоичныеДанные"));
юТест.ПроверитьРавенство(ДД.Размер(), 10);

КонецПроцедуры

Процедура ТестДолженПроверитьПолучениеStreamEvent() Экспорт

МенеджерФоновыхЗаданий = Новый МенеджерФоновыхЗаданий;
ЗаданиеВебсервера = МенеджерФоновыхЗаданий.Выполнить(ЭтотОбъект, "Вебсервер");

ПортТестовогоСервера = 8181;
Соединение = Новый HTTPСоединение("http://127.0.0.1:" + ПортТестовогоСервера);
Запрос = Новый HTTPЗапрос("/");

// Подождем пока поднимится сервер
Приостановить(1000);

Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();

Ответ = Соединение.ВызватьHTTPМетод("GET", Запрос);

Прошло = ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт;
ютест.ПроверитьМеньше(Прошло, 600);

ТелоПоток = Ответ.ПолучитьТелоКакПоток();
юТест.ПроверитьТип(ТелоПоток, Тип("Поток"));

ЧтениеДанных = Новый ЧтениеДанных(ТелоПоток);
Таймаут = 600;
Пока Истина Цикл

ПрочтенныеДанные = ЧтениеДанных.Прочитать(20);

Строка = ПолучитьСтрокуИзДвоичныхДанных(ПрочтенныеДанные.ПолучитьДвоичныеДанные());
Прошло = ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт;

ютест.ПроверитьМеньше(Прошло, Таймаут);

Таймаут = Таймаут + Таймаут;
Если Строка = "" ИЛИ Строка = "data: [DONE]" + Символы.ПС + Символы.ПС Тогда
Прервать;
КонецЕсли;

юТест.ПроверитьРавенство(Строка, "data: [1]" + Символы.ПС + Символы.ПС);

КонецЦикла;

ТелоПоток.Закрыть();

МенеджерФоновыхЗаданий.Очистить();
КонецПроцедуры

Функция ОбработчикЗапроса(Контекст, СледующийОбработчик) Экспорт

Контекст.Ответ.КодСостояния = 200;
Контекст.Ответ.ТипКонтента = "text/event-stream";

ПотокОтвета = ПолучитьДвоичныеДанныеИзСтроки("data: [1]" + Символы.ПС + Символы.ПС).ОткрытьПотокДляЧтения();
ПотокОтвета.КопироватьВ(Контекст.Ответ.Тело);

Приостановить(500);
ПотокОтвета = ПолучитьДвоичныеДанныеИзСтроки("data: [1]" + Символы.ПС + Символы.ПС).ОткрытьПотокДляЧтения();
ПотокОтвета.КопироватьВ(Контекст.Ответ.Тело);

Приостановить(500);
ПотокОтвета = ПолучитьДвоичныеДанныеИзСтроки("data: [DONE]" + Символы.ПС + Символы.ПС).ОткрытьПотокДляЧтения();
ПотокОтвета.КопироватьВ(Контекст.Ответ.Тело);

КонецФункции

Процедура Вебсервер() Экспорт

Вебсервер = Новый ВебСервер(ПортТестовогоСервера);
Вебсервер.ДобавитьОбработчикЗапросов(ЭтотОбъект, "ОбработчикЗапроса");
Вебсервер.Запустить();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А как гасить? Процессы тестов не виснут?


КонецПроцедуры

Функция JsonВОбъект(Json)

ЧтениеJSON = Новый ЧтениеJSON;
Expand Down Expand Up @@ -418,6 +507,7 @@

// Пробуем типовые варианты httpbin
Кандидаты = Новый Массив;
Кандидаты.Добавить("http://127.0.0.1:8085");
Кандидаты.Добавить("https://httpbin.org");
Кандидаты.Добавить("https://httpbingo.org");

Expand Down