Выпустил небольшое обновление библиотеки Nemiro.OAuth.
Версия v1.11 включает исправление недочета с кодированием имен параметров URL, который мог вызвать проблемы при расчете подписи для версий протокола OAuth 1.0.
Также добавлена долгожданная возможность загрузки больших файлов, так что теперь не придется писать дополнительные методы для этого.
Обновлению подверглась и библиотека с формами авторизации для Windows Forms - Nemiro.OAuth.LoginForms. Младший номер версии сборки остался прежним, поскольку, кроме изменения ссылок, ничего нового в Nemiro.OAuth.LoginForms сделано не было. Для различия пакетов, к номеру версии добавлен номер ревизии. В итоге номер обновленной версии Nemiro.OAuth.LoginForms имеет следующий вид v1.4.2423.
Получить Nemiro.OAuth и Nemiro.OAuth.LoginForms можно через Диспетчер пакетов Nuget.
PM> Install-Package Nemiro.OAuth
PM> Install-Package Nemiro.OAuth.LoginForms
----------------------------------------------------------------------------—
Также была произведена большая реорганизация исходного кода проекта (на сервере GitHub). Из решения были удалены все проекты-примеры, коих накопилось уже больше двадцати. Теперь работать с исходным кодом будет комфортно даже новичкам. Примеры были вынесены в отдельные, независимые, решения.
Этим проектом я не занимался уже больше года, поскольку все и так работает нормально. Кое-что уже успел забыть, и стилистика написания кода у меня немного изменилась за это время.
Внедрять новые доработки сложно, поскольку это может нанести вред и все нужно делать аккуратно, сохраняя совместимость, стараясь не перегружать и не усложнять код, а в идеале, чтобы все было более ли менее ровно. Архитектура в принципе пока держится, но реализация некоторых моментов мне уже не нравится, благо таких моментов пока мало.
Радует, что пользователи помогают друг другу в решении возникающих проблем. Вопросы о загрузке больших файлов возникают регулярно и мне порядком поднадоело отвечать, что это не входит в рамки задачи авторизации по протоколу OAuth 😊. Впрочем, я видимо сам виноват, точнее проект виноват, это же он себя таким сделал.
Унифицированные методы работы с API различных поставщиков появились в рамках решения задачи получения информации из профилей пользователей. Это необходимо, поскольку данных в OAuth обычно недостаточно и получить дополнительную информацию можно только через API, который у всех разный. Раньше приходилось искать отдельные решения для получения подробных данных пользователей, адаптировать эти решения под свои задачи или писать новые, ковыряясь в документации к API. Реализация механизмов работы с API оказалась неплохой и было решено открыть эти методы для общего доступа (изначально они были внутренними (internal)). Загрузка бинарных данных и асинхронные запросы не были предусмотрены даже в теории.
С развитием проекта выяснилось, что библиотеку можно использовать в приложениях Windows Forms, в которых синхронные веб-методы Nemiro.OAuth приводили к определенным трудностям. Асинхронность была достигнута путем оборачивания синхронных методов в потоки. Это не очень хорошее решение, но довольно простое и не усложняет код. Использование родных асинхронных методов было бы лучшим решением, но они сложные и сделать вспомогательные веб-методы Nemiro.OAuth простыми в использовании было бы гораздо труднее.
Стоит отметить, что библиотека разрабатывалась под .NET Framework 4.0 с сохранением полной совместимости с .NET 3.5. Новые версии .NET упростили бы код, но пока это не повод делать шаг от отказа поддержки .NET 3.5, создавая параллельные сборки исключительно под новые версии .NET. Сейчас код под все версии .NET одинаковый.
Когда пользователи стали пытаться использовать библиотеку для передачи больших файлов, появилась проблема с утечкой памяти. Проблема была в буферизации и использовании синхронных методов записи содержимого запроса, т.е. программа готовила данные для отправки в памяти и только после этого передавала их на сервер. Поскольку в API обычно передаются текстовые данные небольшого объема, подобные методы работы вполне оправданы. Впрочем, проблема надуманная, поскольку отправить большие данные можно своим кодом, это не так сложно, и я показывал много примеров на эту тему. Но вопрос все равно постоянно возникал. Все решения задачи в рамках проекта Nemiro.OAuth, которые приходили мне на ум, были сложными и затрагивали публичные методы, либо сильно их перегружали/усложняли. В итоге я решил делать запись содержимого запроса в поток асинхронным методом, а все остальное, как и было, оставить синхронным, но для этого пришлось делать блокировку текущего потока путем размещения очень бесконечного цикла с задержками в четверть секунды. Да, немного криво, но это работает 😊 Если возникнет вопрос о блокировке дочерних потоков при блокировке родителя (задержка в четверть секунды), то все нормально, дети в этом плане не зависят от родителей. Решение привело к появлению дополнительных опциальных параметров в веб-методах. В итоге у асинхронного метода нижнего уровня аж четырнадцать параметров, все опциальные. Метод выполнения запросов с буферизацией (старый вариант) тоже остался и может быть использован принудительно, при возникновении проблем. Стоит отметить, что вариант без буферизации используется только для POST и PUT запросов, которые содержат бинарные данные. Что касается возможных проблем, то отправить большие объемы данных просто так может не получится. По умолчанию большие данные отправляются частями, но не каждый сервер может поддерживать такой метод. В качестве альтернативного решения, можно отправить все как есть, но придется указать длину содержимого (Content-Length), а с получением этой информации у библиотеки могут быть трудности, так что нужно указывать размер самостоятельно (в специально добавленный для этого параметр). Серверы Яндекс, Google и Dropbox поддерживают отправку частями, так что беспокоиться на этот счет не стоит.
Библиотека создавалась для проектов ASP.NET и имеет ссылку на сборку System.Web. Это ограничивает её использование. Вывести сборку в принципе можно, но на это потребуется несколько версий. Пока я не планирую этого делать.
Помимо получения стабильной версии продукта, в проекте с отрытым исходным кодом еще неплохо не забывать о самом исходном коде. В идеале, чтобы проект открывался и компилировался у всех с первого раза и без проблем. Этого не просто добиться, много подводных камней: кривые ссылки, пути, номера версий, софт, пакеты, кеш и всякий мусор. В итоге процесс тестирования файлов проекта занимает времени больше, чем получение стабильных версий сборок. Но это скорее потому, что процесс тестирования правильности работы кода во многом автоматизирован и достаточно нажать на одну кнопку и посмотреть на отчет. Правда на написание самих тестов тоже нужно какое-то время. Было бы неплохо как-то автоматизировать тестирование файлов проекта, чтобы тоже одной кнопкой :). Думаю, это можно сделать даже без необходимости создания «ручных» тестов.