Розширення конвеєра http

Конвеєр подій програми не обмежується тільки запитами до веб-форм .aspx. Він також застосовується і в разі, якщо створюються спеціальні обробники, які обслуговують файли спеціальних типів.

Навіщо може знадобитися створювати спеціальний обробник? У більшості випадків в цьому немає ніякої необхідності. Однак іноді все-таки зручно мати низькорівневий інтерфейс, як і раніше надає доступ до корисних об'єктів на кшталт Response і Request, але при цьому не використовує всю модель веб-форми з її численними елементами управління.

Підключається архітектура ASP.NET дозволяє реалізувати подібні сценарії дивно просто. Наприклад, нові обробники для файлів спеціальних типів можна "підключати", просто додаючи відповідні конфігураційні параметри. Однак спочатку необхідно розібратися з тим, як працює конвеєр HTTP.

обробники HTTP

Кожен вступник в додаток ASP.NET запит обробляється спеціально призначеним для цього компонентом, який називається обробником HTTP (HTTP handler). Обробники HTTP грають головну роль в структурі обробки запитів ASP.NET. Для обслуговування файлів різних типів в ASP.NET використовуються різні обробники HTTP. Наприклад, для веб-сторінок застосовується обробник, який створює об'єкти сторінки і її елементів управління, запускає код і візуалізує остаточний HTML.

Реєструвати свої обробники HTTP можна двома способами. Якщо використовується вбудований в Visual Studio веб-сервер, стара версія IIS або версія IIS 7.x в класичному режимі, обробники HTTP повинні додаватися в розділ елемента всередині файлу web.config. Нижче показано це місце:

всередині розділу можна розміщувати елементи для реєстрації нових обробників і елементи для скасування реєстрації існуючих обробників. Ключовий набір певних подібним чином оброблювачів можна бачити в кореневому файлі web.config. Нижче показаний фрагмент цього файлу:

Коли використовується IIS 7.x в інтегрованому режимі (режим за замовчуванням), описаний вище метод реєстрації обробників HTTP не працює. У такій ситуації IIS зчитує розділ і використовує обробники, певні в його підрозділі :

подібно розділу , нові обробники HTTP реєструються додаванням елементів в розділ . Це невелика зміна в файлі конфігурації підкреслює більш серйозну зміну в способі роботи IIS. У версіях, що передують IIS 7 (і в разі запуску IIS 7.x в класичному режимі), при отриманні кожного запиту спочатку проводиться перевірка, з якими програмами зіставлений запитуваний тип файлу. Якщо тип файлу зіставлений з ASP.NET, IIS передає цей файл механізму ASP.NET, який потім зчитує інформацію, що стосується оброблювачів, з файлу web.config і вирішує, що робити далі з даними запитом.

Недолік такого підходу в тому, що весь процес залежить від початкової реєстрації файлу. Якщо механізм ASP.NET не зареєстрований для певного типу файлів, спеціальний обробник або модуль HTTP при запиті файлу такого типу запустити не вдасться.

Версія IIS 7.x більш інтелектуальна. В інтегрованому режимі вона справляється із завданням по відправці запиту належному оброблювачу HTTP і завжди зчитує інформацію про обробниках з розділу . Якщо спробувати зареєструвати обробники в розділі , то при запуску програми буде відображена сторінка з помилкою IIS. Це дозволяє запобігти загрозі безпеки через наявність веб-додатки, в якому визначені обробники реалізовані, але в дійсності не використовуються. (Додавши в розділ елемент . це поведінка можна відключити, і тоді IIS 7.x буде приймати розділ . Однак діяти таким чином не рекомендується.)

Створення спеціального обробника HTTP

Якщо потрібно працювати на більш низькому рівні, ніж пропонує модель веб-форм, щоб забезпечити спеціалізований вид обробки, можна реалізувати власний обробник HTTP.

Для побудови спеціального обробника HTTP необхідно просто створити клас, який реалізує інтерфейс IHttpHandler. Цей клас можна помістити в каталог App_Code або скомпілювати як частина автономної DLL-збірки (іншими словами, у вигляді окремого проекту бібліотеки класів) і додати в веб-додаток посилання на нього.

Інтерфейс IHttpHandler вимагає від класу реалізації двох членів:

ASP.NET викликає цей метод при отриманні запиту. Саме тут обробники HTTP виконують всю роботу. Отримати доступ до внутрішніх об'єктів ASP.NET (таким як Request, Response і Server) можна за допомогою об'єкта HttpContext, переданого цим методом

Після того як метод ProcessRequest () завершить свою роботу, ASP.NET перевіряє цю властивість, щоб дізнатися, чи може даний екземпляр обробника HTTP використовуватися повторно. Значення true вказує, що об'єкт обробника HTTP може використовуватися повторно для іншого запиту такого ж типу, а значення false - що об'єкт обробника HTTP повинен бути відкинутий

Нижче показаний приклад створення найпростішого обробника HTTP. Він просто повертає фіксований блок HTML-розмітки з повідомленням:

Якщо ви створюєте це розширення як проект бібліотеки класів, знадобиться додати посилання на збірку System.Web.dll, що містить велику кількість класів ASP.NET. Без цього посилання ви не зможете застосовувати такі типи, як IHttpHandler і HttpContext.

Конфігурація спеціального обробника HTTP

Після того як клас обробника HTTP створений і зроблений доступним веб-додатком (за рахунок приміщення його в каталог App_Code або додавання посилання), розширення готове до використання. Наступним дією буде зміна файлу web.config для веб-додатки з метою реєстрації обробника HTTP. Приклад показаний нижче:

При реєстрації обробника HTTP вказуються три важливих деталі. Атрибут verb визначає тип HTTP-запиту - POST або GET (для всіх типів запитів використовується *). Атрибут path показує розширення файлу, який буде викликати оброблювач HTTP. У цьому прикладі розділ web.config пов'язує клас SimpleHandler з ім'ям файлу test.simple.

Нарешті, атрибут type ідентифікує клас обробника HTTP. Ця ідентифікація складається з двох частин. Перша частина являє повністю кваліфіковане ім'я класу (в цьому прикладі - HttpExtensions.SimpleHandler). За цією частиною слід кома і ім'я DLL-файлу збірки, що містить даний клас (в розглянутому прикладі - HttpExtensions.dll). Зверніть увагу, що розширення .dll мається на увазі завжди, тому вказувати його не потрібно.

Якщо ви використовуєте підхід з App_Code замість окремо компільованою збірки, можете взагалі опустити ім'я DLL-файлу, оскільки ASP.NET згенерує його автоматично.

Розширення конвеєра http

Використання обробників HTTP, котрі мають потреби в конфігурації

У ASP.NET також підтримується альтернативний підхід, який дозволяє уникати реєстрації обробників HTTP і не піклуватися про налаштування їх параметрів в файлі конфігурації - використання розпізнається розширення .ashx. Яка б версія IIS не застосовувалася (навіть інтегрований веб-сервер Visual Studio), всі запити, що закінчуються розширенням .ashx, автоматично сприймаються як запити, які обслуговуються спеціальним обробником HTTP.

Для створення файлу .ashx в Visual Studio виберіть в меню Website (Веб-сайт) (або в меню Project (Проект) для веб-проекту) пункт Add New Item (Додати новий елемент) і вкажіть Generic Handler (Загальний обробник). Потім введіть відповідне ім'я і клацніть на кнопці Add (Додати) для створення обробника.

Файл .ashx починається з директиви WebHandler. Ця директива вказує на клас, який повинен надаватися через цей файл. наприклад:

Ім'я класу може відповідати класу в каталозі App_Code або класу в посилається збірці. В якості альтернативи можна визначити клас прямо в файлі .ashx (під директивою WebHandler). У будь-якому випадку, коли користувач запросить файл .ashx, буде виконаний відповідний клас обробника HTTP. Якщо ви збережете попередній приклад як файл simple.ashx, то всякий раз при запиті клієнтом simple.ashx буде виконуватися спеціальний веб-обробник. Більш того, тип файлу .ashx зареєстрований в IIS, тому конфігурувати IIS при розгортанні програми не знадобиться.

Використовувати конфігураційний файл або файл .ashx - справа особистих уподобань. Однак файли .ashx зазвичай застосовуються для більш простих розширень, які розробляються для одного веб-додатки. Файли також надають певний рівень гнучкості. Наприклад, можна зареєструвати обробник HTTP, щоб працювати з запитами, що закінчуються даними розширенням, в той час як файл .ashx обслуговуватиме запит зі специфічним ім'ям файлу.

Також можна зареєструвати обробник HTTP для безлічі додатків (реєструючи його у файлі web.config і встановлюючи збірку в GAC). Щоб домогтися того ж ефекту за допомогою файлу .ashx, потрібно скопіювати файл .ashx в кожен віртуальний каталог.

Створення більш функціонального обробника HTTP

У попередньому прикладі обробник HTTP просто повертав блок статичної HTML-розмітки. Однак припустимо створювати і більш складні обробники. Наприклад, можна прочитати дані, відправлені сторінці або задані в рядку запиту, і застосувати їх для настройки згенерованих вихідних даних. Нижче показаний приклад відображення вихідного коду для запитуваного файлу. У ньому використовується підтримка введення-виведення файлу з простору імен System.IO.

Цей код просто знаходить потрібний файл, читає його вміст і за рахунок застосування невеликої заміни рядків (наприклад, заміна порожнього простору неразривающімся пробілами, а розривів рядків - елементом
) І HTML-кодування будує уявлення, безпечно відображається в браузері.

Тепер можна зіставити обробник з розширенням файлу:

Після цього обробник HTTP відобразить вихідний код для файлу .cs:

Розширення конвеєра http

Створення обробника HTTP для вмісту, відмінного від HTML

Деякі з найбільш цікавих оброблювачів HTTP генерує не HMTL-вміст, а вміст інших типів, наприклад, зображення. Це дає можливість не покладатися на фіксовані файли, а витягувати або генерувати вміст програмним шляхом. Наприклад, можна прочитати вміст великого ZIP-файлу із запису в базі даних і за допомогою методу Response.BinaryWrite () відправити його клієнту.

Можна навіть рушити ще далі і побудувати обробник HTTP для динамічного створення ZIP-архіву, що складається з декількох файлів меншого розміру. В обох випадках для клієнта, що використовує обробник HTTP, все буде виглядати так, як ніби браузер завантажує звичайний файл, хоча в дійсності вміст обслуговується за допомогою коду ASP.NET.

Якщо сторінка, яка використовує зображення, знаходиться на іншому сайті, виникає потенційна проблема. Ця сторінка не тільки викрадає ваше зображення, але ще і створює додаткове навантаження на ваш сервер. Причина в тому, що всякий раз, коли хтось переглядає цей інший сайт, зображення запитується з вашого сервера. Якщо викрадене зображення з'являється на якомусь популярному веб-сайті, тоді додаткове навантаження на сервер може виявитися дуже високою і значно зменшити доступну пропускну здатність, необхідну для обслуговування ваших власних сторінок.

Ця проблема - викрадення пропускної здатності за рахунок посилань на ресурси, що знаходяться на вашому сервері - неформально називається Лічінга (leeching). Вона є головним джерелом "головного болю" для популярних веб-сайтів, які обслуговують величезні обсяги відмінного від HTML вмісту (наприклад, сайтів обміну фотографіями, таких як Flickr). Багато веб-сайти протидіють цій проблемі тим же способом, що і описаний нижче обробник HTTP, а саме - відмовляються обслуговувати зображення або замінюють його фіктивним малюнком, якщо заголовок сторінки, що посилається показує, що запит надійшов з іншого веб-сайту.

Нижче наведено обробник HTTP, який реалізує таке рішення в ASP.NET. Для роботи цього коду знадобиться імпортувати простору імен System.Globalization і System.I0:

Щоб цей обробник захищав файли зображень, його знадобиться зареєструвати для обслуговування файлів відповідних типів. Нижче показані параметри у файлі web.config, які налаштовують обробник на обслуговування файлів типу .gif і .png:

На основі наведеного прикладу можна придумати багато інших способів застосування оброблювачів HTTP: скажімо, використовувати їх для візуалізації спеціальних зображень, для виконання спеціальних запитів до бази даних, або навіть для повернення двійкових даних. Всі ці приклади розширюють архітектуру ASP.NET, але обходять модель веб-сторінок. В результаті виходять більш компактні та ефективні компоненти.

Можна також створювати обробники HTTP, що працюють в асинхронному режимі. Це означає, що для виконання своєї роботи вони створюють новий потік, а не використовують один з робітників потоків ASP.NET. Такий прийом покращує масштабованість в ситуаціях, коли повинна виконуватися завдання, що займає багато часу, але не вимагає безлічі ресурсів центрального процесора (ЦП). Класичним прикладом можуть бути очікування читання якогось виключно повільного мережевого ресурсу.

Кількість робочих потоків, які можуть запускатися в ASP.NET одночасно, є фіксованим (і звичайно дорівнює 25). При досягненні цієї межі додаткові запити будуть поміщатися в чергу, навіть при наявності вільного часу ЦП. Завдяки асинхронним обробникам, додаткові запити зможуть прийматися, оскільки ці обробники створюють для кожного запиту новий потік, а не використовують робочий процес.

Зрозуміло, такий підхід пов'язаний з певним ризиком: при створенні занадто великої кількості потоків або при спробі виконати одночасно занадто велика кількість завдань, які споживають багато ресурсів ЦП, серйозно постраждає продуктивність всього веб-сервера.

Схожі статті