URLTransformer мне чем-то не подошел

Автор mikekaganski, 13 января 2022, 19:35

0 Пользователи и 1 гость просматривают эту тему.

mikekaganski

Цитата: sokol92 от 13 января 2022, 19:20Стандартный сервис URLTransformer мне чем-то не подошел - надо поискать чем.

Поищите. У нас там такое наворочено в разборе URL, и каждый день приносит новые радости. Это очень сильное колдунство. Лучше им пользоваться, чем писать своё, и если есть баги - не забывайте их сообщать ;)
С уважением,
Михаил Каганский

sokol92

Цитата: mikekaganski от 13 января 2022, 19:35Лучше им пользоваться, чем писать своё
Полностью согласен, но я взял регулярное выражение непосредственно из стандарта RFC3986 и далее использовал "базовый" сервис TextSearch2.

Кстати, кажется упомянутый URLTransformer стандарту и противоречил, ну-ка, ну-ка...
Владимир.

sokol92

#2
Кажется, нашел компромат.  :)

Sub UrlTest
 Dim oUrlTrans, url As New com.sun.star.util.URL, retval As Boolean, arr
 
 oUrlTrans=CreateUnoService("com.sun.star.util.URLTransformer")
 url.Complete="en.wikipedia.org:443/wiki/URL?key1=a&key2=b#URL_structure"
 retval=oUrlTrans.parseStrict(URL)
 Msgbox "retval::" & retval & " path::" & url.Path & " query::" & url.Arguments
 
 arr=UrlParse(url.complete)
 Msgbox "retval::" & arr(0) & " path::" & arr(3) & " query::" & arr(4)
End Sub



Функция UrlParse приведена здесь.
Макрос выводит:
retval::True path::443/wiki/URL?key1=a&key2=b#URL_structure query::
retval::0 path::443/wiki/URL query::key1=a&key2=b


Сервис не отделяет параметров (аргументов) от пути, регулярное выражение из RFC3986 отделяет.

Прошу прощения у автора темы за Offtop (хотя мы обсуждаем URL).
Владимир.

sokol92

Михаил, спасибо за перенос темы (я это не умею делать).
Владимир.

sokol92

Такой URL сервис показывает как ошибочный, а стандарту он нравится:

en.wikipedia.org/wiki/URL?key1=a&key2=b#URL_structure

Firefox тоже не против.
Владимир.

mikekaganski

Цитата: sokol92 от 13 января 2022, 20:37

  url.Complete="en.wikipedia.org:443/wiki/URL?key1=a&key2=b#URL_structure"
  retval=oUrlTrans.parseStrict(URL)


Цитата: sokol92 от 13 января 2022, 21:07
en.wikipedia.org/wiki/URL?key1=a&key2=b#URL_structure

parseStrict ожидает, что в неё передаётся *полный* URL. То есть у него есть схема и всё остальное. В первом случае она считает схемой всё до двоеточия; во втором - двоеточия вообще нет.

Есть parseSmart, но я его не пробовал.
С уважением,
Михаил Каганский

mikekaganski

#6
Цитата: sokol92 от 13 января 2022, 20:37
Sub UrlTest
 ...
 url.Complete="en.wikipedia.org:443/wiki/URL?key1=a&key2=b#URL_structure"
 ...
 arr=UrlParse(url.complete)
 Msgbox "retval::" & arr(0) & " path::" & arr(3) & " query::" & arr(4)
End Sub


Макрос выводит:
retval::0 path::443/wiki/URL query::key1=a&key2=b


Можно заметить, что Ваш код, как и parseStrict, неправильно отделяет путь: 443 - не часть пути. А если вывод сделать таким:

Msgbox "scheme::" & arr(1) & " host::" & arr(2) & " path::" & arr(3) & " query::" & arr(4) & " fragment::" & arr(5)

то вывод будет

scheme::en.wikipedia.org host:: path::443/wiki/URL query::key1=a&key2=b fragment::URL_structure

и станет очевидно, что регулярка точно так же обманута (протокол и хост поменялись местами). Тут ситуация очень похожа на "нельзя парсить HTML с помощью регулярок". Эта тема невероятно сложная, и даже несмотря на то, что это решение приведено в стандарте, оно кривое.


Цитата: sokol92 от 13 января 2022, 20:37
Сервис не отделяет параметров (аргументов) от пути, регулярное выражение из RFC3986 отделяет.

Как можно увидеть в исходном коде, parseStrict при обнаружении неизвестного протокола не пытается быть умным, а делит на части очень примитивно - "Minimal support for unknown protocols".
С уважением,
Михаил Каганский

mikekaganski

С уважением,
Михаил Каганский

mikekaganski

Цитата: sokol92 от 13 января 2022, 19:53
я взял регулярное выражение непосредственно из стандарта RFC3986

Насчёт стандарта (и о причинах таких проблем) - вот цитата оттуда:

Цитата: RFC 3986
3.  Syntax Components

  The generic URI syntax consists of a hierarchical sequence of
  components referred to as the scheme, authority, path, query, and
  fragment.

     URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

  ...

  The scheme and path components are required, though the path may be
  empty (no characters).

Поэтому никакой URL не может считаться правильным без схемы, хотя мы привыкли вводить просто www.foo.bar. Именно для таких неправильных адресов и придуманы хитрости типа parseSmart.
С уважением,
Михаил Каганский

sokol92

Михаил, спасибо за (продуктивное) исследование!
Кстати, у нас есть ведь под капотом это;)
Владимир.

mikekaganski

Цитата: sokol92 от 14 января 2022, 13:05
Кстати, у нас есть ведь под капотом это;)

:) не вполне понял, что Вы имеете ввиду - что мы можем это использовать при написании макросов на Питоне, или что-то ещё (скажем, что всякий раз, когда мы парсим URL в коде ЛО, мы должны обращаться к Питону)?
С уважением,
Михаил Каганский

sokol92

Цитата: mikekaganski от 14 января 2022, 13:18когда мы парсим URL в коде ЛО, мы должны обращаться к Питону
Тут есть некий дуализм ("не мы, а вы").
Классы UNO это и ТЗ и инструмент для разработчиков (к которым относитесь Вы), и инструмент для прикладных программистов (к которым относимся мы).
Можно, к примеру, создать какой-нибудь сервис URLParse, который будет реализовывать достаточно развитые интерфейсы Питона. Прикладники будут в восторге, разработчикам LO он тоже может пригодиться в каких-то ситуациях. Или в поставляемых версиях LO есть ограничения на использование Python в коде LO?
Владимир.

mikekaganski

#12
Ну во-первых, у питона недостаточно развиты интерфейсы парсинга URL :) - посмотрите список поддерживаемых схем. Мы не поддерживаем многое из того, что там перечислено, зато у нас есть свои схемы - macro:, uno: и т.п., а также схемы общего назначения типа Office URI.

Во-вторых, мы парсим URL при каждом чихе. Хотя бы потому, что все команды UNO проходят через URL. И дополнительные накладные расходы (на передачу в Питон, ожидание его интерпретации со всеми чудесами GIL (у нас и так хватает своих чудес типа SolarMutex), получение оттуда и преобразование в наши строки ...) недопустимы.

В-третьих (вытекает из во-первых и во-вторых), поскольку мы не сможем отказаться от своих парсеров, использование классов Python будет очередной реализацией однотипного функционала (а у нас и так две реализации, которые мы объединить боимся, т.к. они несколько отличаются и обе - части API).

Ну и наконец - в такой ситуации нет смысла превращать API ЛО просто в средство альтернативного доступа к библиотекам какого-то ЯП. Если программисту понадобится воспользоваться библиотеками питона - пожалуйста, напрямую с питоном и общайтесь. API ЛО тут ни при чём :)
С уважением,
Михаил Каганский

sokol92

Понятно, спасибо!
Пользуясь случаем, нагло задам еще родственный вопрос.  :)

Какие в LO предлагаются / планируются средства для обработки HTTP(S) - запросов?
Я с этим столкнулся в первые недели знакомства с LO, когда нужно было получить / передать данные через WEB API. Для POST-запросов нашлась лишь ссылка на японском языке (как я сейчас понимаю, автор - Hanya). Попытки применить указанный подход в реальных случаях не удались. Пришлось применять внешние вызовы программы Curl (успешно). Альтернатива - все тот же Python.
Владимир.

mikekaganski

Да в принципе никаких, кроме ucp/ucb; если оно не работает, нужны багрепорты ;) - но удовольствие то ещё, и я думаю, просто мало кто этим реально пользуется.
С уважением,
Михаил Каганский