init here
This commit is contained in:
235
исх/сеть/хттп/парсер.tri
Normal file
235
исх/сеть/хттп/парсер.tri
Normal 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
|
||||
|
||||
если строка.извлечь цел(заглавие.значение, номер байта, новый размер контента) {
|
||||
размер контента := новый размер контента
|
||||
}
|
||||
}
|
||||
|
||||
ответ.заглавия.добавить(заглавие)
|
||||
}
|
||||
}
|
||||
} иначе {
|
||||
ответ.туловище := строка.соединить(ответ.туловище, данные)
|
||||
}
|
||||
}
|
||||
|
||||
вернуть ответ
|
||||
}
|
||||
Reference in New Issue
Block a user