URL кодирует все возможные символы

Часто я делаю запрос на Ruby, который терпит неудачу, потому что серверу не нравится кодировка. Типичным примером является наличие пробелов как +, когда сервер понимает только %20. Сегодня я столкнулся с сервером, который не любит незакодированные дефисы (-), требуя вместо них %2D.

Я пробовал CGI.escape, URI.escape, ERB::Util.url_encode, WEBrick::HTTPUtils.escape, и ни один из них не кодирует дефисы.

В прошлом я прибегал к gsubобработке оскорбительных символов по мере необходимости, но поскольку я нахожу больше серверов с большим количеством особенностей, я бы предпочел более стабильное решение.

Существует ли стандартный (т.е. без внешних зависимостей) подход, при котором проц кодирует все, что возможно?

Я не ищу просто дефисную кодировку или gsub всего по одному.


person user137369    schedule 15.10.2019    source источник
comment
Что вы планируете делать с серверами, которым не нравится закодированная форма некоторых символов?   -  person Sergio Tulentsev    schedule 15.10.2019
comment
Спецификация W3 гласит: 1) Пробелы должны быть заменены символами +. 2) Символы от *, -, ., от 0 до 9, от A до Z, _ и от a до z можно оставить как есть. 3) Замените все остальные символы их процентным кодированием. См.: w3.org/ TR/2013/CR-html5-20130806/   -  person 3limin4t0r    schedule 15.10.2019


Ответы (1)


URI.escape устарел и заменен на CGI::escape, который соответствует RFC, захватывая небуквенные символы и преобразовывая их. Это модуль, который делает это:

# https://ruby-doc.org/stdlib-2.4.3/libdoc/cgi/rdoc/CGI/Util.html

# File cgi/util.rb, line 11
def escape(string)
  encoding = string.encoding
  string.b.gsub(/([^ a-zA-Z0-9_.-]+)/) do |m|
    '%' + m.unpack('H2' * m.bytesize).join('%').upcase
  end.tr(' ', '+').force_encoding(encoding)
end      

В конце концов, в исправлении нуждается сервер, а не ваш код. Вы можете выполнить манипатч или разветвить CGI и удалить - из регулярного выражения или gsub() символ.

person Mike Mackintosh    schedule 15.10.2019
comment
О, так вот куда убежал URI.escape. - person tadman; 16.10.2019
comment
Разветвление кажется гораздо лучшей идеей, чем обезьянье исправление, поскольку вы можете просто включить это на границе приложения. - person max; 16.10.2019
comment
Согласен с подходом разветвления - person Mike Mackintosh; 16.10.2019