141 lines
6.0 KiB
Plaintext
141 lines
6.0 KiB
Plaintext
модуль хттп
|
||
|
||
импорт "стд::вывод"
|
||
импорт "исх/строка"
|
||
импорт "исх/сеть/тцп"
|
||
|
||
фн сериализовать хттп-запрос(хост: Строка, обращение: ХттпОбращение): Строка {
|
||
пусть метод := обращение.метод
|
||
если метод = "" {
|
||
метод := "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
|
||
}
|
||
}
|
||
|
||
хост := строка.обрезать пробельные символы(хост)
|
||
если хост = "" {
|
||
оплошность := "пустой хост в урл"
|
||
вернуть Урл{}
|
||
}
|
||
|
||
если путь = "" { путь := "/" }
|
||
|
||
вернуть Урл{ хост: хост, порт: порт, путь: путь }
|
||
}
|