Блог по программированию в среде Delphi

Поиск по блогу

Есть идея по созданию интересной программы?

Опиши тут и я по возможности постараюсь это реализовать специально для тебя! Без $ ))
Показаны сообщения с ярлыком Wininet. Показать все сообщения
Показаны сообщения с ярлыком Wininet. Показать все сообщения

среда, 29 декабря 2010 г.

Простенький пример выполнения запроса в Wininet

По просьбе трудящихся выкладываю вот такой простенький исходник программки с помощью, которой можно получить ТИЦ и PR  сайта путем выполнения POST запроса

Скрин примера



unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,WinInet, StdCtrls;

type
  TfrmMain = class(TForm)
    Button1: TButton;
    edtSite: TEdit;
    lblTC_PR: TLabel;
    lblSite: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}
const
  // дефолное название приложение через которое якобы происходит соединение
  DefaultAppName ='Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6';

function exam(msData: TMemoryStream):string;
  function DataAvailable(hRequest: pointer; out Size: cardinal): BOOLEAN;
  begin
    Result := WinInet.InternetQueryDataAvailable(hRequest, Size, 0, 0);
  end;
var
  hInternet, hConnect, hRequest: pointer;
  dwBytesRead, i, L: cardinal;
  sTemp: AnsiString; // текст страницы
  sHeader: String;
begin
  Result:='';
  try
    hInternet := InternetOpen(PChar(DefaultAppName),INTERNET_OPEN_TYPE_PRECONFIG, Nil, Nil, 0);
    if Assigned(hInternet) then
    begin
      // Открываем сессию
      //http://ip-whois.net/pr_cy_check.php обратите внимание как записал в коде адрес сайта
      hConnect := InternetConnect(hInternet, PWideChar('ip-whois.net'),INTERNET_DEFAULT_HTTP_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 1);
      if Assigned(hConnect) then
      begin
        // открываем запрос
        hRequest := HttpOpenRequest(hConnect, PWideChar('POST'),
          PWideChar('/pr_cy_check.php'), HTTP_VERSION, nil, Nil,
          INTERNET_FLAG_KEEP_CONNECTION, 1);

        sHeader:='Accept: */*';
        HttpAddRequestHeaders(hRequest, Pointer(sHeader), Length(sHeader), HTTP_ADDREQ_FLAG_ADD);
        sHeader:= 'Content-Type: application/x-www-form-urlencoded';
        HttpAddRequestHeaders(hRequest, Pointer(sHeader), Length(sHeader), HTTP_ADDREQ_FLAG_ADD);
        sHeader:= 'Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3';
        HttpAddRequestHeaders(hRequest, Pointer(sHeader), Length(sHeader), HTTP_ADDREQ_FLAG_ADD);
        sHeader:= 'Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7';
        HttpAddRequestHeaders(hRequest, Pointer(sHeader), Length(sHeader), HTTP_ADDREQ_FLAG_ADD);

        if Assigned(hRequest) then
        begin
          // Отправляем запрос
          i := 1;
          if HttpSendRequest(hRequest, nil, 0, msData.memory, msData.Size) then
          begin
            repeat
              DataAvailable(hRequest, L); // Получаем кол-во принимаемых данных
              if L = 0 then
                break;
              SetLength(sTemp, L + i);
              if not InternetReadFile(hRequest, @sTemp[i], sizeof(L),dwBytesRead) then
                break; // Получаем данные с сервера
              inc(i, dwBytesRead);
            until dwBytesRead = 0;
            sTemp[i] := #0;
            Result:=sTemp;
          end;
        end;
      end;
    end;
  finally
    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hInternet);
  end;
end;

function TC_PR(aValue:string):string;
var
  i:Integer;
  TC,PR:string;
begin
  i:=AnsiPos('</h2><h3>ТИЦ: ',aValue);
  if i=0 then
  begin
    Result:='Неизвестно!';
    Exit;
  end;
  Delete(aValue,1,i+length('</h2><h3>ТИЦ: ')-1);
  i:=AnsiPos('</h3><h3>PR: ',aValue);
  TC:=Copy(aValue,0,i-1);
  Delete(aValue,1,i+length('</h3><h3>PR: ')-1);
  i:=AnsiPos('</h3><br>',aValue);
  PR:=Copy(aValue,0,i-1);
  Result:='ТИЦ '+TC+' PR '+PR;
end;

procedure TfrmMain.Button1Click(Sender: TObject);
var
  zapros:TStringStream;
  sTemp:string;
begin
  zapros:=TStringStream.Create;
  zapros.WriteString('T1='+edtSite.Text+'&B1=T2=%D3%E7%ED%E0%F2%FC+%D2%C8%D6+%E8+PR');
  sTemp:=exam(zapros);
  if Length(sTemp)>0 then
    lblTC_PR.Caption:=TC_PR(sTemp);

  zapros.Free;
end;

end.

Скачать исходник проекта можно отсюда Download

суббота, 11 сентября 2010 г.

Загрузка изображения из интернета в поток (Delphi)

uses wininet;

function LoadImage(url:string): TMemoryStream;
var
  hInternet, hConnect: pointer;
  dwBytesRead, i, L: cardinal;
  sTemp: AnsiString;
begin
  Result:=TMemoryStream.Create;
  hInternet := InternetOpen('MyApp', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
    if Assigned(hInternet) then
    begin
      hConnect := InternetOpenUrl(hInternet, PChar(url), nil, 0, 0, 0);
      if Assigned(hConnect) then
        try
          i := 1;
          repeat
            SetLength(sTemp, L + i);
            if not InternetReadFile(hConnect, @sTemp[i], sizeof(L),dwBytesRead) then
              break;
            inc(i, dwBytesRead);
            until dwBytesRead = 0;
        finally
          InternetCloseHandle(hConnect);
        end;
    end;
  finally
    InternetCloseHandle(hInternet);
  end;
  Result.Write(sTemp[1], Length(sTemp));
  Result.Position := 0;
end;

Данную функцию использовал для загрузки изображений с различными форматами:
bmp, gif, png, jpeg, tiff, ico и др. Проблем не возникало. Главное, что необходимо сделать это сохранять картинки с теми же расширениями которые у них были, чтобы потом не возникало путаницы. Я сохранял с именами файлов которые брал из прямых ссылок на картинки.

Для получения имени файла из Url использую функцию

function ExtractUrlFileName(const AUrl: string): string;
var
  i: Integer;
begin
  i := LastDelimiter('/', AUrl);
  Result := Copy(AUrl, i + 1, Length(AUrl) - (i));
end;

вторник, 27 июля 2010 г.

Функция по загрузке jpg в Timage (Delphi)

Не скажу, что прям моя разработка, но к ней я свою корявую руку приложил))

//непосредственно сама функция по загрузке картинки формата jpg из сети интернет
//для работы функции необходимо добавить в uses ... wininet, Jpeg;


function GetImage(url:string): TPicture;
var
  hInternet, hConnect: pointer;
  dwBytesRead, i, L: cardinal;
  sTemp,aUrl: AnsiString; // текст страницы
  memStream: TMemoryStream;
  jpegimg: TJPEGImage;
begin
  hInternet := InternetOpen('MyApp', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
    if Assigned(hInternet) then
    begin
      hConnect := InternetOpenUrl(hInternet, PChar(url), nil, 0, 0, 0);
      if Assigned(hConnect) then
        try
          i := 1;
          repeat
            SetLength(sTemp, L + i);
            if not InternetReadFile(hConnect, @sTemp[i], sizeof(L),dwBytesRead) then
              break; // Получаем данные с сервера
            inc(i, dwBytesRead);
            until dwBytesRead = 0;
        finally
          InternetCloseHandle(hConnect);
        end;
    end;
  finally
    InternetCloseHandle(hInternet);
  end;
  memStream := TMemoryStream.Create;
  jpegimg := TJPEGImage.Create;
  try
    memStream.Write(sTemp[1], Length(sTemp));
    memStream.Position := 0;
    //загрузка изображения из потока
    jpegimg.LoadFromStream(memStream);
    Result:=TPicture.Create;
    Result.Assign(jpegimg);
  finally
    //очистка
    memStream.Free;
    jpegimg.Free;
  end;
end;

воскресенье, 27 июня 2010 г.

InternetCloseHandle

Закрытие дескриптора любой функции Wininet

Синтаксис Delphi

function InternetCloseHandle(hInet: HINTERNET): BOOL; stdcall;


hInet Дескриптор который необходимо закрыть.

Возвращает True если дескриптор закрыт успешно, в противном случае False для получения дополнительной информации вызовите функцию GetLastError

InternetReadFile

Чтение результатов выполнения функций InternetOpenUrl, FtpOpenFile или HttpOpenRequest

Синтаксис Delphi

function InternetReadFile(hFile: HINTERNET; lpBuffer: Pointer;
                         dwNumberOfBytesToRead: DWORD;
                         var lpdwNumberOfBytesRead: DWORD): BOOL; stdcall;

hFile     Дескриптор сессии, полученный вызовом функции.
lpBuffer  Адрес буфера в который будут записаны данные
dwNumberOfBytesToRead  Размер буфера в который будут записаны данные.
lpdwNumberOfBytesRead  Число прочитанных байт.

HttpSendRequest

Посылает указанный запрос на сервер HTTP
Синтаксис Delphi

function HttpSendRequest(hRequest: HINTERNET; lpszHeaders: PChar;
                                        dwHeadersLength: DWORD; lpOptional: Pointer;
                                        dwOptionalLength: DWORD): BOOL; stdcall;
 
hRequest  Дескриптор, полученный вызовом предыдущей функции.

lpszHeaders, dwHeadersLength  Позволяет добавлять дополнительные заголовки к запросу. Подробнее об HTTP заголовках можно узнать на www.w3.org.

lpOptional,dwOptionalLength  Указатель на данные, которые будут посланы на сервер вместе с запросом. Используется в методах "POST" и "PUT".

Простенький пример отправки POST запроса в wininet

HttpOpenRequest

HTTP запрос выполняется в несколько этапов: открытие запроса, определение HTTP заголовка, собственно отправка запроса, чтение и обработка данных. Эта функция, как следует из её названия, открывает HTTP запрос.

Синтаксис Delphi 

function HttpOpenRequest(hConnect: HINTERNET; lpszVerb: PChar;
                                          lpszObjectName: PChar; lpszVersion: PChar; lpszReferrer: PChar;
                                          lplpszAcceptTypes: PLPSTR; dwFlags: DWORD;
                                          dwContext: DWORD): HINTERNET; stdcall;

hConnect Дескриптор сессии.

lpszVerb Задаёт имя команды запроса. Мы будем использовать методы "GET" и "POST".

lpszObjectName Имя целевого объекта. Это может быть просто HTML файл, скрипт или выполняемый модуль на сервере.

lpszReferer URL адрес предыдущей страницы. Чаще всего этот параметр игнорируется серверами, но если вдруг сервер перестанет подавать признаки жизни, попробуйте задать его, может помочь.

lpszAcceptTypes Определяет тип содержимого допускаемого клиентской стороной. Иногда MS IE передаёт сюда вот такую длинную строчку: "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, */*", иногда это просто "*/*".

dwFlags Комбинация интернет флагов. Например, при использовании SSL соединений мы будем указывать флаг INTERNET_FLAG_SECURE. Так же нам будет полезен флаг INTERNET_FLAG_KEEP_CONNECTION, который позволяет удерживать соединение с сервером между запросами. Это бывает полезно, если мы хотим, чтобы сервер не забыл о нас во время сессий требующих входа по паролю.

суббота, 26 июня 2010 г.

InternetReadFile

Синтаксис Delphi 
function InternetReadFile(hFile: HINTERNET; 
                          lpBuffer: Pointer; 
                          dwNumberOfBytesToRead: DWORD; 
                          var lpdwNumberOfBytesRead: DWORD): BOOL; stdcall;

Параметры:
  • HFile – указатель на файл, полученный после вызова функции InternetOpenUrl.
  • LpBuffer – указатель на буфер, куда будут заноситься данные.
  • DwNumberOfBytesToRead - число байт, которое нужно причитать.
  • lpdwNumberOfBytesRead - содержит количество прочитанных байтов. Устанавливается в 0 перед проверкой ошибок.
Функция позволяет считывать данные, используя указатель, полученный в результате вызова InternetOpenUrl, FtpOpenFile, GopherOpenFile, или HttpOpenRequest. Так же, как и все остальные функции, возвращает TRUE или FALSE. После завершения работы функции нужно освободить указатель Hfile, вызвав InternetCloseHandle(hUrlFile) .
Вот, в принципе, и все об самых основных функциях. Для простейшего приложения можно определить примерно такой упрощенный алгоритм использования Internet- функций Win32 API взамен стандартным компонентов. HSession:= InternetOpen - открывает сессию.
HConnect:= InternetConnect - устанавливает соединение.
hHttpFile:=httpOpenRequest
HttpSendRequest - HttpOpenRequest и HttpSendRequest используются вместе для получения доступа к файлу по HTTP- протоколу. Вызов HttpOpenRequest создает указатель и определяет необходимые параметры, а HttpOpenRequest отсылает запрос HTTP серверу, используя эти параметры.

InternetOpenUrl

Синтаксис Delphi   
function InternetOpenUrl(hInet: HINTERNET; 
                         lpszUrl: PChar; 
                         lpszHeaders: PChar; 
                         dwHeadersLength: DWORD; 
                         dwFlags: DWORD; 
                         dwContext: DWORD): HINTERNET; stdcall;

Параметры:
  • HInet – указатель, полученный после вызова InternetOpen.
  • LpszUrl – URL , до которого нужно получить доступ. Обязательно должен начинаться с указания протокола, по которому будет происходить соединение. Поддерживаются следующие протоколы - ftp:, gopher:, http:, https:.
  • LpszHeaders – содержит заголовок HTTP запроса.
  • DwHeadersLength – длина заголовка. Если заголовок nil, то можно установить значение –1, и длина будет вычислена автоматически.
  • DwFlags – флаг, задающий дополнительные параметры перед выполнением функции. Вот некоторые его значения: INTERNET_ FLAG_EXISTING_CONNECT, INTERNET_FLAG_HYPERLINK, INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP, INTERNET_FLAG_NO_AUTO_REDIRECT, INTERNET_FLAG_NO_CACH E_WRITE, INTERNET_FLAG_NO_COOKIES.
Возвращается значение TRUE, если соединение успешно, или FALSE - в противном случае. Теперь можно спокойно считывать нужный файл функцией InternetReadFile.

InternetConnect

Функция открывает сессию с указанным сервером, используя протокол FTP, HTTP, Gopher.

Синтаксис Delphi  
function InternetConnect (hInet: HINTERNET;
                                      lpszServerName: PChar;
                                      nServerPort: INTERNET_PORT;
                                      lpszUsername: PChar;
                                      lpszPassword: PChar;
                                      dwService: DWORD;
                                      dwFlags: DWORD;
                                      dwContext: DWORD): HINTERNET; stdcall;
Параметры:
  • HInet – указатель, полученный после вызова InternetOpen.
  • LpszServerName – имя сервера, с которым нужно установить соединение. Может быть как именем хоста – domain.com.ua, так и IP- адресом – 134.123.44.67.
  • NServerPort – указывает на TCP/IP порт, с которым нужно соединиться. Для задания стандартных портов служат константы: NTERNET_DEFAULT_FTP_PORT (port 21), INTERNET_DEFAULT_GOPHER_PORT (port 70), INTERNET_DEFAULT_HTTP_PORT (port 80), INTERNET_DEFAULT_HTTPS_ PORT (port 443), INTERNET_DEFAULT_SOCKS_PORT (port 1080), INTERNET_INVALID_PORT_NUMBER – порт по умолчанию для сервиса, описанного в dwService. Стандартные порты для различных сервисов находятся в файле SERVICES в директории Windows.
  • LpszUsername – имя пользователя, желающего установить соединение. Если установлено в nil , то будет использовано имя по умолчанию, но для HTTP это вызовет исключение.
  • LpszPassword – пароль пользователя для доступа к серверу. Если оба значения установить в nil, то будут использованы параметры по умолчанию.
  • DwService – задает сервис, который требуется от сервера. Может принимать значения INTERNET_SERVICE_FTP, INTERNET_SERVICE_GOPHER, INTERNET_SERVICE_HTTP.
  • DwFlags - Задает специфические параметры для соединения. Например, если DwService установлен в INTERNET_SERVICE_FTP, то можно установить в INTERNET_FLAG_PASSIVE для использования пассивного режима.
Функция возвращает указатель на установленную сессию или nil в случае невозможности ее установки.
Итак, мы имеем связь с сервером, нужный нам порт открыт. Теперь следует открыть соответствующий файл. Для этого определена функция InternetOpenUrl. Она принимает полный URL файла и возвращает указатель на него. Кстати, перед ее использованием не нужно вызывать InternetConnect.

InternetOpen

Эта функция инициализирует WinInet  и возвращает дескриптор, который необходим для вызова других функций WinInet. В случае неудачи возвращается NULL.

Синтаксис Delphi
function InternetOpen(lpszAgent: PChar; dwAccessType: DWORD;
lpszProxy, lpszProxyBypass: PChar; dwFlags: DWORD): HINTERNET; stdcall;

Параметры:
lpszAgent
– строка символов, которая передается серверу и идентифицирует программное обеспечение, пославшее запрос.
dwAccessType
- задает необходимые параметры доступа. Принимает следующие значения:
  • INTERNET_OPEN_TYPE_DIRECT – обрабатывает все имена хостов локально.
  • INTERNET_OPEN_TYPE_PRECONFIG – берет установки из реестра.
  • INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY - берет установки из реестра и предотвращает запуск Jscript или Internet Setup (INS) файлов.
  • INTERNET_OPEN_TYPE_PROXY – использование прокси-сервера. В случае неудачи использует INTERNET_OPEN_TYPE_DIRECT. LpszProxy – адрес прокси-сервера. Игнорируется только если параметр dwAccessType отличается от INTERNET_OPEN_TYPE_PROXY. LpszProxyBypass - спис ок имен или IP- адресов, соединяться с которыми нужно в обход прокси-сервера. В списке допускаются шаблоны. Так же, как и предыдущий параметр, не может содержать пустой строки. Если dwAccessType отличен от INTERNET_OPEN_TYPE_PROXY, то значения игнорируютс я, и параметр можно установить в nil. DwFlags – задает параметры, влияющие на поведение Internet- функций . Возможно применение комбинации из следующих разрешенных значений: INTERNET_FLAG_ASYNC, INTERNET_FLAG_FROM_CACHE, INTERNET_FLAG_OFFLINE
Функция инициализирует использование Internet- функций Win32 API. В принципе, ваше приложение может неоднократно вызывать эту функцию, например, для доступа к различным сервисам, но обычно ее достаточно вызвать один раз. При последующих вызовах других фун кций возвращаемый указатель HINTERNET должен передаваться им первым. Таким образом, можно дважды вызвать InternetOpen, и, имея два разных указателя HINTERNET, работать с HTTP и FTP параллельно. В случае неудачи, она возвращает nil, и для более детального анализа следует вызвать GetLastError.

Wininet Delphi for MSDN (Мой корявый перевод)




HINTERNET

Это дескриптор, который создают и используют функции Wininet. Этот тип дескриптора не является взаимозаменяемым с другими дескрипторами. Поэтому он не может быть использован в таких функциях, как ReadFile или CloseHandle. Так же, кроме того, другие дескрипторы не могут быть использованы с функциями WinINet. Например, дескриптор полученный в результате работы CreateFile не может быть использован в InternetReadFile.




Функциями WinInet создающие дескрипторы HINTERNET