Из цикла лекций «Технологии разработки Internet-приложений» для студентов 4-го курса кафедры Компьютерных технологий физического факультета Донецкого национального университета Технологии разработки Internetприложений Среда Delphi: CGI, ISAPI приложения Потоки, почта, куки, авторизация, IntraWeb ДонНУ, кафедра КТ, проф. В. К. Толстых Потоки С помощью потоков можно передавать данные практически любого типа (MIME – Multipurpose Internet Mail Extension), из любого источника, доступного на Web-сервере. При получении информации конкретного типа браузер отыскивает приложение, которое должно использоваться для обработки данных этого типа, после чего передает ему эти данные Основные свойства: Response.ContentStream – содержимое потока Response.ContentType – MIME-тип пересылаемых данных Основной метод: Response.SendResponse – отправить ответ Типы потоков в Delphi: TFileStream, TStringStream, TMemoryStream (буфер в ОЗУ), TBlobStream (чтение/запись полей Binary large object), TWinSocketStream (чтение/запись в сокете), TOleStream (COM интерфейс чтения/записи) Пример 1 Передача изображения потоком TFileStream (из файла) Запрос клиента <html> <body> <Center> <H1> Разные потоки </H2> </Center> <a href="http://localhost/net-web/Scripts/stream.exe"> Доставить мышонка! </a> </body> </html> Ответ сервера Обработчик события onAction 1 (без PathInfo) procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var Page: TStrings; begin Page:=TStringList.Create; With Page do begin Add('<html><body>'); Add('<center><H2> Вот он! </H2>'); Add('<img src="http://localhost/net-web/'); Add('Scripts/stream.exe/mouse" alt="мышонок">'); Add('</center></body></html>'); end; Вызов второго Action с Response.Content:= Page.Text; PathInfo - mouse Page.Free; end; Ответ сервера Обработчик события onAction 2 (PathInfo - mouse) procedure TWebModule1.WebModule1WebActionItem2Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var FS: TFileStream; begin // Создаём поток из файла mouse.gif: FS:=TFileStream.Create('../Images/mouse.gif',fmOpenRead); Response.ContentType:='image/gif'; //необходим модуль GIFImage Response.ContentStream:=FS; Response.SendResponse; // можно не удалять объект-поток, он будет удален автоматически // при завершении обработчика onAction end; Пример 2 Передача изображения потоком TMemoryStream Var Jpg: TJPEGImage; B: TBitmap; MS: TMemoryStream; begin Jpg := TJPEGImage.Create; //пусть поток будет - jpeg try B := TBitmap.Create; //пусть исходный рисунок будет - bmp try ProcGenerate(B); //создание рисунка bmp … Jpg.Assign(B); //конвертирование bmp в jpeg finally B.Free end; MS := TMemoryStream.Create; Jpg.SaveToStream(MS); //запись в поток данных объекта Jpg MS.Position := 0; //текущую позицию потока – в начало Response.ContentType := 'image/jpeg'; Response.ContentStream := MS; finally Jpg.Free; {поток удалять не надо} end; end; Создание рисунка для потока procedure ProcGenerate(var B:TBitmap); begin With B Do begin Width := 300; Height := 300; Canvas.TextOut(0,0,'Создал Красников'); Canvas.Pen.Color := clTeal; Canvas.Pen.Width := 2; r:=0; while r<6.29 Do begin {r-параметр - от 0 до 2*pi} x:= 150 + (125*abs(sin(r*10))+25)*cos(r); y:= 150 + (125*abs(cos(r*10))+25)*sin(r); Canvas.MoveTo(round(x),round(y)); Canvas.LineTo(round(x)+1,round(y)+1); r:=r+0.004; end; end; end; Результаты работы Почта - Indy Internet Direct – открытые Internet-компоненты Основные свойства TIdSMTP– реализует клиентский SMTP-протокол Host :String – адрес (IP, доменный) удаленного SMTP-сервера PORT:Integer – для SMTP=25 UserName :String – login автора сообщения Password :String – пароль автора сообщения (для аутентификации) AuthenticationType – (atNone, atLogin) без или с простой проверкой подлинности AuthSchemesSupported :TStringList методы аутентификации SMTP-сервера Основные свойства TIdMessage: содержит Internet-сообщение From.Text :String – адрес отправителя Recipients.EMailAddresses :String – адреса получателей, через запятую ContentType :String – MIME-тип сообщения CharSet :String – кодировка шрифта, например CharSet:='windows-1251' ; Body: TStrings – тело сообщения Subject :String – тема сообщения Компоненты From, Recipients и их свойства Свойства TIdMessage.From: автор сообщения (стандарт RFC 822) Address, Name, Text : String – адрес отправителя Пример, IdMessage.From.Name := 'Jane Doe'; IdMessage.From.Address := 'janed@another.net'; IdMessage.From.Text := '"John Doe" <jdoe@some.net>'; // IdMessage.From.Text содержит 'Jane Doe <janed@another.net>' // IdMessage.From.Name содержит 'John Doe' // IdMessage.From.Address содержит 'jdoe@some.net' Свойства TIdMessage.Recipients: получатель EMailAddresses: String – адрес отправителя (стандарт RFC 822) Items[0-2] – поля Address, Name,Text как в адресе отправителя Отправка сообщений TIdSMTP Основные методы : Create, Destroy – создание, удаление объекта типа TIdMessage ClearHeader, ClearBody, Clear – очистить заголовок, тело, всё Connect – установить связь с SMTP-сервером для отправки сообщения Send(сообщение типа TIdMessage) – отправить сообщение Disconnect – разорвать связь с SMTP-сервером Authenticate: Boolean – выполнить аутентификацию, при успехе - True Пример отправки сообщения IdMessage1 с возможной аутентификацией: With IdSMTP1 Do begin AuthenticationType:=atNone; try Connect; if AuthSchemesSupported.IndexOf('LOGIN')>-1 then // требуется ли аутент.? begin AuthenticationType:=atLogin; Authenticate; end; // - если «да» Send(IdMessage1); Disconnect; finally IdMessage1.Destroy; end; // - если оно дальше не нужно end; Пример создания сообщения Var IdMessage1: TIdMessage; … begin // данные для подключения к SMTP (настройка IdSMTP1) IdSMTP1.Host:='195.184.198.5'; IdSMTP1.UserName:='Vova'; IdSMTP1.Password:='xxxxxxxx'; IdMessage1:= TIdMessage.Create(nil); // создание письма With IdMessage1 Do begin // создание заголовка и тела письма From.Text:='vava@fbi.gov'; Recipients.EMailAddresses:='jon@dongu.donetsk.ua'; ContentType:='text/plain'; CharSet:='windows-1251'; Subject:='тема письма'; Body.Add('строка 1'); Body.Add('строка 2');… End; Cookie Файл Cookie – до 4 Кб, - до 300 файлов для каждого пользователя, до 20 значений от одного домена Cookie (печенье, проныра) - это текстовая строка, которая может включаться в запросы и ответы протокола HTTP. Разработчики Webприложений организуют хранение в файлах Сookie на компьютере пользователя такие сведения, как персональные данные пользователя, логин и пароль, свои глобальные переменные и др. данные необходимые им для обработки последующих посещений клиента. Постоянным файлом Cookie называется файл, сохраняемый на компьютере после выхода из браузера. Этот файл Cookie может быть прочитан сайтом при его повторном посещении. Сохраненный на компьютере файл Cookie может прочитать только тот сайт, который его создал. Браузер, перед соединением с каждым сайтом, проверяет нет ли от него Cookie, если есть – добавляет его содержимое к HTTPзапросу этого сайта. Временные (сеансовые) файлы Cookie сохраняются только в течение текущего сеанса обозревателя и удаляются с компьютера после выхода из браузера. Cookie «Коллекции» Браузер отправляет серверу заголовки его коллекций cookie толстых@google[1].txt Заголовок Cookie PREF - имя Cookie ID=87b064fd051aeab5:TM=11273990 36:LM=1127399036:S=BBYhpV8Zu96 - его значение Jn_bq google.com/ 1536 2618878336 32111634 1143386432 Cookie 1 29736833 * C:\Documents and Settings\пользователь\Cookies толстых@Cookie[2].txt : Заголовок Cookie 1 - имя Cookie 1 LastVisit 10.03.2005+16%3A38%3A38 - его значение localhost/net-web/Scripts/Cookie.exe/ 1024 302955264 29739266 3267401456 Cookie 1 29739039 * Заголовок Cookie 2 - имя Cookie 2 Hi - его значение Hallo%2C+Client! localhost/net-web/Scripts/Cookie.exe/ 1024 302955264 29739266 3267401456 Cookie 2 29739039 * При повторной записи Cookie значения одинаковых параметров обновляются, а новые – добавляются. При этом имя файла Cookie получает очередной номер в квадратных скобках. Коллекция TCookieCollection для объекта Response - контейнер Response.Cookies объектов TCookie, - список всех заголовков Cookie в Web-ответе Основные свойства коллекции: Response.Cookies.Items[i]: TCookie – заголовок Cookie номер i в Web-ответе Response.Cookies.Count – количество Cookie в коллекции Основные методы коллекции: Response.Cookies.Add:TCookie – добавляет заголовок Cookie в Web-ответ свойства для TCookie: Name, Value, Domain, Path :String (ограничивает пути для Domain), Expires :TDateTime (срок жизни Cookie), Secure :Boolean (должен ли клиент использовать защищенное соединение https при передачи заголовка Cookie), HeaderValue (заголовок Cookie), Response.Cookies.Clear – удаляет все Cookie в коллекции Response.Cookies.Delete(i: Integer) – удаляет i-тый Cookie в коллекции Метод Response.SetCookieField для добавления Cookie в Web-ответ SetCookieField (Values :TStrings (заголовки – имена и значения всех Cookie), Domain, Path, Expires, Secure) Пример добавления Cookie: procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var List: TStrings; begin List:=TStringList.Create; // контейнер заголовков Cookie try List.Add('LastVisit='+ {имя Cookie 1} FormatDateTime('mm/dd/yyyy hh:mm:ss',Now) {значение Cookie 1}) ; List.Add('Hi='+ {имя Cookie 2 } 'Hallo, Client!‘ {значение Cookie 2}) ; Response.SetCookieField(List,'','',Now+1,False); // срок жизни – 1 день Response.Content:='<Html><Body> Cookie Установлен!</Body></html>'; finally List.Free; end; end; Свойства Request для Cookie Основные свойства Request: Cookie :String – заголовки всех Cookie, пришедших от клиента, т.е. пары Name=Value (другие не высылаются) через ; CookieFields :TStrings – контейнер строк-пар 'Name=Value' Методы Request для Cookie Основной метод Request: ExtractCookieFields (List: TStrings) – прочитать в контейнер List пары 'Name=Value ' всех Cookie List.Values['Name'] – прочитать значение 'Value' для Cookie с именем 'Name' из контейнера строк List Пример чтения Cookie procedure TWebModule1.WebModule1WebActionItem2Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var List: TStrings; begin List:=TStringList.Create; // контейнер для всех заголовков Cookie try Request.ExtractCookieFields(List); {прочитать заголовки Cookie в список} Response.Content:='<Html><Body>'+ '<P><b> Значение Cookie 1: </b><br>'+ List.Values['LastVisit']+ '<P><b> Значение Cookie 2: </b><br>'+ List.Values['Hi']+ '<P><b> Свойство Request.Cookie: </b><br>'+ Request.Cookie+'</Body></html>'; finally List.Free; end; end; Демонстрация Cookie 1 2 Пример добавления Cookie через свойство Cookies (Авторизация) Здесь в Cookie записывается пароль авторизации, что позволяет клиенту не проводить авторизацию при посещении этого сайта в течение суток. Пароль из Cookie передается серверу при незащищенном (не https) подключении клиента и без встроенной проверки подлинности Windows. Код обработчика OnAction для работы с Cookie: Handled := False; // добавление Cookie не завершает Web-ответ with Response.Cookies.Add do begin Name := 'LastPassword'; // Установка Cookie ’LastPassword’ для текущей авторизации, // либо, если авторизация не была проведена, то чтение данных // об авторизации из cookie ’LastPassword’ запроса request: Value := Request.Authorization; if Value = '' then Value := Request.CookieFields.Values['LastPassword‘]; Secure := False; // требование незащищенного подключения Expires := Now + 1; // срок жизни – 1 день end; Далее, в других Action, можно проверить пароль в Value данного Cookie Аутентификация и авторизация Установка доступа с проверкой подлинности встроенными средствами Windows Основана на обмене сервера зашифрованными сообще-ниями с Internet Explorer для подтверждения удостоверения пользователя Результаты авторизации (переговоры) не анонимным доступом средствами Win – скрыты Cookie LastPassword www.donnu.edu.ua/netweb/scripts/Authorization.exe / 1024 2173330560 29741265 865149456 29741039 * Результаты авторизации (переговоров) при анонимном доступе средствами Win можно сохранять в файл LastPassword Negotiate+TlRMTVNTUAADAAAAGAAYAHoAAAAYABgAkgAAABAAEABA AAAAGgAaAFAAAAAQABAAagAAAAAAAACqAAAABYKIoEQATwBOAE4 AVQBXAFcAVwBBAGQAbQBpAG4AaQBzAHQAcgBhAHQAbwByAFQATw BMAFMAVABZAEsASACPy1GbyQn5fQAAAAAAAAAAAAAAAAAAAABVD Kh%2FiIUNZrwwSNq4EULmSS069xQBU5c%3D www.donnu.edu.ua/net-web/scripts/Authorization.exe/ 1024 Идентификатор сессии 3683330560 Пароль 29741265 2378119456 29741039 * Проверка подлинности «Обычная» - не встроенными средствами Windows Очередной запрос при сохраненном ранее пароле При обычной авторизации, не встроенными средствами Widows, пароль отправляется в текстовом формате и его можно сохранить и в системе и в файле Очередной запрос при не сохраненном пароле Создание IntraWeb приложения - технология создания Web-приложений от фирмы AtoZed IntraWeb – это разработка форм Web приложений, ничем не отличающаяся от разработки обычных форм. В результате получается приложение, генерирующее для клиента обычные HTML-страницы с кодом на JavaScript. Выдача результатов в HTML обеспечивает совместимость с самыми распространенными браузерами IntraWeb Код обработчика кнопки «Посчитать сумму» procedure TformMain.IWButton1Click(Sender: TObject); var a,b,res : Double; code : Integer; begin val(IWEdit1.Text,a,code); val(IWEdit2.Text,b,code); res:=a+b; IWEdit3.Text:=FormatFloat('0.##',res); end; Запуск IntraWeb Запуск Результаты работы: