init here

This commit is contained in:
2025-11-26 21:32:41 +03:00
commit 33c97acade
91 changed files with 9155 additions and 0 deletions

View File

@@ -0,0 +1,235 @@
модуль хттп
импорт "исх/строка"
импорт "исх/вперед-назад"
импорт "исх/сеть/тцп"
фн сериализовать хттп ответ*(р: ХттпОтвет): Строка {
пусть ответ := строка.собрать(строка.ф("$стр $цел $стр\r\n", р.версия, р.код, р.состояние))
пусть есть размер контента := ложь
цикл [номер]заглавие среди р.заглавия {
если заглавие.имя = "Content-Length" { есть размер контента := истина }
ответ := строка.собрать(ответ, строка.ф("$стр: $стр\r\n", заглавие.имя, заглавие.значение))
}
если ~ есть размер контента {
ответ := строка.собрать(ответ, строка.ф("Content-Length: $цел\r\n", длина(р.туловище(:Строка8))))
}
ответ := строка.собрать(ответ, "\r\n")
если длина(р.туловище) > 0 {
ответ := строка.собрать(ответ, р.туловище)
}
вернуть ответ
}
фн отправить хттп ответ*(с: тцп.ТцпСоединение, р: ХттпОтвет) {
пусть данные := сериализовать хттп ответ(р)
с.записать(данные)
}
фн разобрать хттп обращение*(с: вперед-назад.Крипипаста): ХттпОбращение {
пусть сколько читаем = 1024
пусть прочитано := 0
пусть обращение = ХттпОбращение{}
пусть данные := ""
пусть первая линия := ""
пусть добрались до тела := ложь
пусть размер контента: Цел64 := -1
пока истина {
пусть сколько прочитать: Цел64 := -1
если размер контента > 0 & добрались до тела {
сколько прочитать := размер контента - прочитано
}
если сколько прочитать = 0 {
вернуть обращение
}
пусть новые данные = с.прочитать(сколько читаем)
прочитано := прочитано + длина(новые данные)
если длина(новые данные) = 0 {
вернуть обращение
}
данные := строка.собрать(данные, новые данные)
если ~ добрались до тела {
пока длина(данные) > 0 {
пусть конец строки = строка.индекс(данные, 0, "\n")
если конец строки = -1 {
прервать
}
пусть линия = строка.обрезать пробельные символы(строка.извлечь(данные, 0, конец строки))
данные := строка.извлечь(данные, конец строки + 1, длина(данные(:Строка8)) - конец строки)
если линия = "" {
если размер контента > 0 {
пусть индекс переноса = строка.индекс(данные, 0, "\n")
добрались до тела := истина
данные := строка.извлечь(данные, индекс переноса + 1, длина(данные(:Строка8)) - индекс переноса)
прочитано := длина(данные(:Строка8))
обращение.туловище := данные
данные := ""
прервать
} иначе {
вернуть обращение
}
}
если первая линия = "" {
первая линия := линия
пусть части = строка.разобрать(первая линия, " ")
если длина(части) >= 1 { обращение.метод := части[0] }
если длина(части) >= 2 {
цикл [номер]часть среди части {
если номер > 0 & номер < длина(части) - 1 {
если номер > 1 {
обращение.путь := строка.собрать(обращение.путь, " ")
}
обращение.путь := строка.собрать(обращение.путь, часть)
}
}
}
если длина(части) >= 3 { обращение.версия := части[длина(части) - 1] }
} иначе {
пусть заглавие = ХттпЗаглавие{}
строка.разделить(линия, ":", заглавие.имя, заглавие.значение)
заглавие.имя := строка.обрезать пробельные символы(заглавие.имя)
заглавие.значение := строка.обрезать пробельные символы(заглавие.значение)
если размер контента < 0 & заглавие.имя = "Content-Length" {
пусть новый размер контента := 0
пусть номер байта := 0
если строка.извлечь цел(заглавие.значение, номер байта, новый размер контента) {
размер контента := новый размер контента
}
}
обращение.заглавия.добавить(заглавие)
}
}
} иначе {
обращение.туловище := строка.соединить(обращение.туловище, данные)
}
}
вернуть обращение
}
фн разобрать хттп ответ*(с: тцп.ТцпСоединение): ХттпОтвет {
пусть сколько читаем = 1024
пусть прочитано := 0
пусть ответ = ХттпОтвет{}
пусть данные := ""
пусть первая линия := ""
пусть добрались до тела := ложь
пусть размер контента: Цел64 := -1
пока истина {
пусть сколько прочитать: Цел64 := -1
если размер контента > 0 & добрались до тела {
сколько прочитать := размер контента - прочитано
}
если сколько прочитать = 0 {
вернуть ответ
}
пусть новые данные = с.прочитать(сколько читаем)
прочитано := прочитано + длина(новые данные)
если длина(новые данные) = 0 {
вернуть ответ
}
данные := строка.собрать(данные, новые данные)
если ~ добрались до тела {
пока длина(данные) > 0 {
пусть конец строки = строка.индекс(данные, 0, "\n")
если конец строки = -1 {
прервать
}
пусть линия = строка.обрезать пробельные символы(строка.извлечь(данные, 0, конец строки))
данные := строка.извлечь(данные, конец строки + 1, длина(данные(:Строка8)) - конец строки)
если линия = "" {
если размер контента > 0 {
добрались до тела := истина
прочитано := длина(данные(:Строка8))
ответ.туловище := данные
данные := ""
прервать
} иначе {
вернуть ответ
}
}
если первая линия = "" {
первая линия := линия
пусть части = строка.разобрать(первая линия, " ")
если длина(части) >= 1 { ответ.версия := части[0] }
если длина(части) >= 2 {
пусть новый код := 0
пусть номер байта := 0
если строка.извлечь цел(части[1], номер байта, новый код) {
ответ.код := новый код
}
}
если длина(части) >= 3 {
цикл [номер]часть среди части {
если номер >= 2 {
если номер > 2 {
ответ.состояние := строка.собрать(ответ.состояние, " ")
}
ответ.состояние := строка.собрать(ответ.состояние, часть)
}
}
}
} иначе {
пусть заглавие = ХттпЗаглавие{}
строка.разделить(линия, ":", заглавие.имя, заглавие.значение)
заглавие.имя := строка.обрезать пробельные символы(заглавие.имя)
заглавие.значение := строка.обрезать пробельные символы(заглавие.значение)
если размер контента < 0 & заглавие.имя = "Content-Length" {
пусть новый размер контента := 0
пусть номер байта := 0
если строка.извлечь цел(заглавие.значение, номер байта, новый размер контента) {
размер контента := новый размер контента
}
}
ответ.заглавия.добавить(заглавие)
}
}
} иначе {
ответ.туловище := строка.соединить(ответ.туловище, данные)
}
}
вернуть ответ
}