Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Неопасное применение заголовка HTTP IfModifiedSince в PCL библиотеках

Anna | 17.06.2014 | нет комментариев
Мы разрабатываем приложение под несколько платформ, всю платформо само­стоятельную часть создаем с поддержкой PCL, усердствуя добиться максимального яруса пере применения компонентов. Для коммуникаций с сервером применяется класс HttpWebRequest тот, что реализует всю нужную от транспортного яруса функциональность.

Незадолго протокол был оптимизирован, в нем возникла вероятность сократить объем передаваемых данных указывая горизонт актуальности. Реализована данная оптимизация с поддержкой обработки HTTP заголовка IfModifiedSince, впрочем у объекта HttpWebRequest в PCL не доступного качество IfModifiedSince. Это не казалось задачей заголовок был добавлен напрямую в коллекцию заголовков запроса.

request.Headers[HttpRequestHeader.IfModifiedSince] = timeStamp.ToString();

Протестировав решение на WindowsPhone приложении я удостоверился в его работоспособности, но все юнит тесты транспортного яруса выдали ошибки. Изучив задачу нашел, что реализация WebHeaderCollection для платформы Windows, не разрешает напрямую задавать данный заголовок и требует, Дабы разработчики применяли качество HttpWebRequest.IfModifiedSince которое не доступно в сборках PCL.

Для решения этой я сотворил способ растяжения для класса HttpWebRequest реализующий следующую логику работы:

При первом обращении к способу, пытаемся добавить заголовок в коллекцию заголовков запроса, если это не получается, с поддержкой отражения ищем у объекта запроса поле IfModifiedSince и создаем и кешируем делегат для установки значения свойства.

При последующих обращениях к способу, используем кэшированный делегат для установки значения заголовка IfModifiedSince.

namespace System.Net
{
	public static class NetExtensions
	{
		private static Action<HttpWebRequest, DateTime> _setIfMofifiedSince;
		public static void SetIfModifiedSince(this HttpWebRequest request, DateTime value)
		{
			Guard.NotNull(request);

			if (_setIfMofifiedSince != null)
			{
				_setIfMofifiedSince(request, value);
				return;
			}

			try
			{
				request.Headers[HttpRequestHeader.IfModifiedSince] = value.ToString();
				return;
			}
			// ReSharper disable once EmptyGeneralCatchClause
			catch
			{
			}

			var property = request.GetType().GetRuntimeProperty("IfModifiedSince");
			if (property != null
				&& property.CanWrite)
			{
				var method = property.SetMethod;
				if (method != null)
				{
					_setIfMofifiedSince = (Action<HttpWebRequest, DateTime>)method.CreateDelegate(typeof(Action<HttpWebRequest, DateTime>));
				}
			}

			if (_setIfMofifiedSince == null)
			{
				throw new Exception("Unable to set IfModifiedSince");
			}

			_setIfMofifiedSince(request, value);
		}
	}
}

Применяя данный способ растяжения код остается простым для чтения и понимания.

request.SetIfModifiedSince(timeStamp);
Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB