Не так давно я писал про единственную более менее готовую библиотеку OAuth для Delphi, которую хотел использовать в Twitter'e. Проблема её использования заключалась в том, что при отправке сообщений, содержащих русские символы возвращалась ошибка 401. Сегодня эта досадная ошибка была решена. В связи с чем выкладываю в доступ исправленную библиотеку OAuth для Delphi.
Прежде всего, следует указать автора этой библиотеки, т.к. я всего лишь немного доработал её, а не создал с нуля - вот ссылка на его блог. К сожалению, его проект по OAuth уже долгое время не развивается, но кое-какие исходники, при необходимости, вы сможете найти в блоге, в т.ч. и модуль для работы с Twitter'ом с использованием библиотеки.
Теперь, что касается исправлений. Ошибка заключалась в том, что при доступе к ресурсам Twitter'а неверно формировалась строка Base_String. По спецификации OAuth все символы в строке должны быть в кодировке URF-8 и при этом параметры URL (за исключением параметров OAuth) должны располагаться по алфавиту. Кодирование строки проводилось следующим образом:
base := 'POST&' + TOAuthUtil.urlEncodeRFC3986(URL) + '&' + UrlEncode(encodeParams(oParams,'&',false));
В encodeParams кодирование параметров проходило так:
buf := Params.Names[i] + '='+ UrlEncode(Utf8Encode(Params.ValueFromIndex[i])) + ''
Функция UrlEncode выглядит следующим образом:
function UrlEncode(const S : String) : String; var I : Integer; Ch : Char; begin Result := ''; for I := 1 to Length(S) do begin Ch := S[I]; if ((Ch >= '0') and (Ch <= '9')) or ((Ch >= 'a') and (Ch <= 'z')) or ((Ch >= 'A') and (Ch <= 'Z')) or (Ch = '.') or (Ch = '-') or (Ch = '_') or (Ch = '~')then Result := Result + Ch else Result := Result + '%' + IntToHex(Ord(Ch), 2); end; end;
В результате при кодировании любого русского символа получалась следующая картина:
символ
П = %D0%9F
оказывался в Base String как:
%2541F%25440
А при отправке POST-запроса снова как
%D0%9F
В результате чего сервер и возвращал нам 401 ошибку.
Я немного видоизменил кодирование параметров в Base String и использовал вместо UrlEncode немного измененную функцию из Synapse - EncodeTriplet:
function EncodeTriplet(const Value: AnsiString; Delimiter: AnsiChar; Specials: TSpecials): AnsiString; var n, l: Integer; s: AnsiString; c: AnsiChar; begin SetLength(Result, Length(Value) * 3); l := 1; for n := 1 to Length(Value) do begin c := Value[n]; if c in Specials then begin Result[l] := Delimiter; Inc(l); s := IntToHex(Ord(c), 2); Result[l] := s[1]; Inc(l); Result[l] := s[2]; Inc(l); end else begin Result[l] := c; Inc(l); end; end; Dec(l); SetLength(Result, l); end;
Где TSpecials - множество:
type TSpecials = set of AnsiChar; const URLSpecialChar: TSpecials = [#$00..#$20, '<', '>', '"', '%', '{', '}', '|', '\', '^', '~', '[', ']', '`', #$7F..#$FF];
Проверил работу библиотеки, отправив сообщения в Twitter, используя методы API update и direct_messages/new - сообщения отправились без проблем, в т.ч. и сообщения, содержащие в нике пользователя или в тексте спец. символы.
Теперь можете , скачивать с блога автора модуль для Twitter'а и создавать свои приложения для Twitter в Delphi.
На всякий случай приведу ссылки, которые могу быть Вам полезны:
1. Репозиторий с первоначальным исходником библиотеки (не обновлялся более года)
2. Блог автора проекта OAuthDelphi
3. Пост в моем блоге по использованию библиотеки.
UPDATE 05.03.11
Twitter OAuth(4.76 kB)
Если Вам часто приходится иметь дело с обменом электронных валют, то специально для Вас представляю -мониторинг обменных пунктов. Здесь вы сможете найти тот обменник курс которого будет Вам наиболее выгодным.
-----------------------------------
| Делись! | Загружай! | Плюсуй! |
| | |









20 мая 2010 в 5:52 пп
Twitter OAuth и русские символы. Решено. | Delphi в Internet…
Thank you for submitting this cool story — Trackback from progg.ru…
30 мая 2010 в 4:28 пп
Не работает закачка с iFolder
30 мая 2010 в 5:07 пп
проверил. всё работает
04 Мар 2011 в 1:49 пп
Перезалей пожалуйста на другой файлоообменник, невозможно скачать от сюда
05 Мар 2011 в 9:02 пп
Ссылка на скачивание архива внизу поста (архив лежит на хостинге блога)
18 Мар 2011 в 8:09 пп
Привет, Влад!
Занялся тут написанием проги под твиттер. возник следющий вопрос. Взял твой модуль OAuth с кириллицей. Все хорошо, все работает (тебе, к стати спасибо за это). Одно «НО» не хочет восклицательный знак отправлять сразу «401″ ошибка и хоть ты тресни… Не подскажешь, как можно эту проблему решить?
18 Мар 2011 в 8:11 пп
Ах, да, чуть не забыл, я с Indy (может это важно) использую версию. Т.к. только недавно с Indy разобрался, и нет желания с новой библиотекой разбираться
18 Мар 2011 в 8:26 пп
А, все, видно погорячился тревогу бить, добавил «?»,»!»,»#»,»@» (всЕ, которые не работали) в Specials все заработало.
Сорри за беспокойство!
18 Мар 2011 в 8:43 пп
Да я особенно не встревожился :) Всегда пожалуйста