/
EvilBeaver
/
OneScript
Обзор
Документация
Войти
/
EvilBeaver
/
OneScript
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
v2.0.2
src/OneScript.StandardLibrary/Http/HttpResponseContext.cs
175 строк
7 KB
EvilBeaver
Merge remote-tracking branch 'origin/develop' into develop
14 дек 2025, 22:11
14 дек 2025, 22:11
07f6cec
Код
Авторство
О чём код?
/*---------------------------------------------------------- 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 at http://mozilla.org/MPL/2.0/. ----------------------------------------------------------*/ using System; using System.IO; using System.Net; using System.Text; using OneScript.Contexts; using OneScript.StandardLibrary.Binary; using OneScript.StandardLibrary.Collections; using OneScript.StandardLibrary.Text; using ScriptEngine.Machine; using ScriptEngine.Machine.Contexts; namespace OneScript.StandardLibrary.Http { /// <summary> /// Ответ от HTTP-сервера /// </summary> [ContextClass("HTTPОтвет", "HTTPResponse")] public class HttpResponseContext : AutoContext<HttpResponseContext>, IDisposable { private readonly MapImpl _headers = new MapImpl(); // TODO: Нельзя выделить массив размером больше чем 2GB // поэтому функционал сохранения в файл не должен использовать промежуточный буфер _body private HttpResponseBody _body; private HttpWebResponse _response; private string _defaultCharset; private string _filename; public HttpResponseContext(HttpWebResponse response, string 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 ProcessHeaders(WebHeaderCollection webHeaderCollection) { foreach (var item in webHeaderCollection.AllKeys) { _headers.Insert(ValueFactory.Create(item), ValueFactory.Create(webHeaderCollection[item])); } } private void ProcessResponseBody(HttpWebResponse response, string dumpToFile) { if (response.ContentLength == 0) { _body = null; return; } _filename = dumpToFile; _body = new HttpResponseBody(response, dumpToFile); } /// <summary> /// Соответствие. Заголовки ответа сервера. /// </summary> [ContextProperty("Заголовки", "Headers")] public MapImpl Headers => _headers; /// <summary> /// Код состояния HTTP ответа. Число. /// </summary> [ContextProperty("КодСостояния", "StatusCode", CanWrite = false)] public int StatusCode { get; set; } /// <summary> /// Получает ответ сервера в виде строки /// </summary> /// <param name="encoding">КодировкаТекста или Строка. Кодировка полученного текста. По умолчанию принимается кодировка из заголовка Content-Type</param> /// <returns></returns> [ContextMethod("ПолучитьТелоКакСтроку", "GetBodyAsString")] public IValue GetBodyAsString(IValue encoding = null) { if (_body == null) return ValueFactory.Create(); Encoding enc; if (encoding == null) { if (String.IsNullOrEmpty(_defaultCharset)) _defaultCharset = "utf-8"; enc = Encoding.GetEncoding(_defaultCharset); } else enc = TextEncodingEnum.GetEncoding(encoding); using(var reader = new StreamReader(_body.OpenReadStream(), enc)) { return ValueFactory.Create(reader.ReadToEnd()); } } /// <summary> /// Интерпретировать ответ, как ДвоичныеДанные /// </summary> /// <returns>ДвоичныеДанные</returns> [ContextMethod("ПолучитьТелоКакДвоичныеДанные", "GetBodyAsBinaryData")] public IValue GetBodyAsBinaryData() { if (_body == null) return ValueFactory.Create(); using (var stream = _body.OpenReadStream()) using (var memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); return new BinaryDataContext(memoryStream.ToArray()); } } /// <summary> /// Интерпретировать ответ, как Поток /// </summary> /// <param name="rawStream">Булево. Будет получен сырой поток без дополнительной обработки. По умолчанию Ложь</param> /// <returns>Поток</returns> [ContextMethod("ПолучитьТелоКакПоток", "GetBodyAsStream")] public IValue GetBodyAsStream(bool rawStream = false) { if (_body == null) return ValueFactory.Create(); return new GenericStream(_body.OpenReadStream(rawStream), true); } /// <summary> /// Получить файл, в который записан ответ сервера. /// </summary> /// <returns>Строка. Имя файла с ответом. Если ответ не записывался в файл - возвращает Неопределено.</returns> [ContextMethod("ПолучитьИмяФайлаТела", "GetBodyFileName")] public IValue GetBodyFileName() { if (_filename == null) return ValueFactory.Create(); return ValueFactory.Create(_filename); } /// <summary> /// Закрыть HTTP ответ и освободить ресурсы /// </summary> [ContextMethod("Закрыть", "Close")] public void Close() { Dispose(); } public void Dispose() { _response?.Dispose(); _response = null; _body?.Dispose(); _body = null; } } }