Files
srab/исх/сеть/хттп/клиент.tri
2025-11-26 21:32:41 +03:00

141 lines
6.0 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
модуль хттп
импорт "стд::вывод"
импорт "исх/строка"
импорт "исх/сеть/тцп"
фн сериализовать хттп-запрос(хост: Строка, обращение: ХттпОбращение): Строка {
пусть метод := обращение.метод
если метод = "" {
метод := "GET"
}
пусть путь := обращение.путь
если путь = "" {
путь := "/"
}
пусть первая := строка.ф("$стр $стр HTTP/1.1\r\n", метод, путь)
пусть есть длина := ложь
пусть выход := первая
цикл [номер]заглавие среди обращение.заглавия {
если заглавие.имя = "Content-Length" { есть длина := истина }
выход := строка.собрать(выход, строка.ф("$стр: $стр\r\n", заглавие.имя, заглавие.значение))
}
выход := строка.собрать(выход, строка.ф("Host: $стр\r\n", хост))
если ~ есть длина {
выход := строка.собрать(выход, строка.ф("Content-Length: $цел\r\n", длина(обращение.туловище(:Строка8))))
}
выход := строка.собрать(выход, "\r\n")
если длина(обращение.туловище) > 0 { выход := строка.собрать(выход, обращение.туловище) }
вернуть выход
}
фн послать далеко и надолго*(хост: Строка, порт: Цел64, обращение: ХттпОбращение): ХттпОтвет {
пусть соединение = тцп.подключиться(хост, порт)
пусть данные = сериализовать хттп-запрос(хост, обращение)
соединение.записать(данные)
вывод.ф("Ждем хттп ответ\n")
пусть ответ = разобрать хттп ответ(соединение)
соединение.закрыть()
вывод.ф("Дождались\n")
вернуть ответ
}
фн послать на три буквы*(хост: Строка, порт: Цел64, путь: Строка): ХттпОтвет {
вернуть послать далеко и надолго(хост, порт, ХттпОбращение{ метод: "GET", путь: путь })
}
тип Урл* = класс {
хост*: Строка := ""
порт*: Цел64 := 0
путь*: Строка := ""
}
фн парсить урл*(стр: Строка, оплошность := Строка): Урл {
оплошность := ""
пусть с = строка.обрезать пробельные символы(стр)
если с = "" {
оплошность := "пустой урл"
вернуть Урл{}
}
пусть схема := "http"
пусть ост := с
если строка.разделить(с, "://", схема, ост) {
схема := строка.обрезать пробельные символы(схема)
} иначе {
// без схемы считаем http
схема := "http"
ост := с
}
// отделяем authority и путь
пусть № слеша = строка.индекс(ост, 0, "/")
пусть авторитет := ""
пусть путь := ""
если № слеша >= 0 {
пусть ост8 = ост(:Строка8)
авторитет := строка.извлечь(ост, 0, № слеша)
путь := строка.извлечь(ост, № слеша, длина(ост8) - № слеша)
} иначе {
авторитет := ост
путь := ""
}
авторитет := строка.обрезать пробельные символы(авторитет)
если авторитет = "" {
оплошность := "пустой хост в урл"
вернуть Урл{}
}
// парсим хост и порт
пусть хост := авторитет
пусть порт: Цел64 := 0
пусть № двоеточия = строка.индекс(авторитет, 0, ":")
если № двоеточия >= 0 {
пусть ав8 = авторитет(:Строка8)
хост := строка.извлечь(авторитет, 0, № двоеточия)
пусть порт строка := строка.извлечь(авторитет, № двоеточия + 1, длина(ав8) - (№ двоеточия + 1))
порт строка := строка.обрезать пробельные символы(порт строка)
пусть порт значение := 0
пусть № байта := 0
если ~ строка.извлечь цел(порт строка, № байта, порт значение) {
оплошность := "некорректный порт в урл"
вернуть Урл{}
}
если порт значение <= 0 | порт значение > 65535 {
оплошность := "порт вне диапазона в урл"
вернуть Урл{}
}
порт := порт значение
} иначе {
если схема = "https" {
порт := 443
} иначе {
порт := 80
}
}
хост := строка.обрезать пробельные символы(хост)
если хост = "" {
оплошность := "пустой хост в урл"
вернуть Урл{}
}
если путь = "" { путь := "/" }
вернуть Урл{ хост: хост, порт: порт, путь: путь }
}