Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.01.2017, 00:08   #1
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию [WinInet] Странная ошибка при HttpSendRequest

Классическая функция, стыренная для http и по справкам переделанная по мере возможностей под https, никогда не отказывающая мне на урезанном Delphi 7 portable на работе, почему-то отказала дома на нормально установленной Delphi 7... В чём может быть дело и как справиться с ситуацией?...
Код:
function GetSiteCode(URL:String):String;
var
  URL_Base,URL_Page:String;
//========== для получения кода страницы ==========
  hInet, hCon, hReq: HINTERNET;
  Status, StatusSize, Index: DWORD;
  bytes, b, posi: Cardinal;
  ResponseString: AnsiString;
//=================================================

begin

  if pos('https://',URL)>0 then delete(URL,1,length('https://'));
  URL_Base:=PChar(copy(URL,1,pos('/',URL)-1));
  URL_Page:=PChar(copy(URL,pos('/',URL)+1,length(URL)-pos('/',URL)));
  ShowMessage(URL_Base+#13+URL_Page);

  begin
//========== получение кода страницы ==========
    hInet := InternetOpen('My Agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
    if not Assigned(hInet) then
      raise Exception.Create('Ошибка при выполнении функции InternetOpen' + sLineBreak + SysErrorMessage(GetLastError));
    try
      hCon := InternetConnect(hInet, PChar(URL_Base), INTERNET_DEFAULT_HTTPS_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
//      hCon := InternetConnect(hInet, PChar(URL_Base), INTERNET_DEFAULT_HTTP_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
      if not Assigned(hCon) then
        raise Exception.Create('Ошибка при выполнении функции InternetConnect' + sLineBreak + SysErrorMessage(GetLastError));
      try
        hReq := HttpOpenRequest(hCon, 'GET', PChar(URL_Page), HTTP_VERSION, nil, nil, INTERNET_FLAG_SECURE, 0);
//        hReq := HttpOpenRequest(hCon, 'GET', PChar(URL_Page), HTTP_VERSION, nil, nil, INTERNET_FLAG_KEEP_CONNECTION or INTERNET_FLAG_RELOAD, 0);
        if not Assigned(hReq) then
          raise Exception.Create('Ошибка при выполнении функции HttpOpenRequest' + sLineBreak + SysErrorMessage(GetLastError));
        try
          HttpSendRequest(hReq,'', 0, nil, 0);
          StatusSize := SizeOf(Status);
          Index := 0;
          HttpQueryInfo(hReq, HTTP_QUERY_FLAG_NUMBER or HTTP_QUERY_STATUS_CODE, @Status, StatusSize, Index);
          if Status <> HTTP_STATUS_OK then
            raise Exception.Create('Ошибка при выполнении функции HttpSendRequest' + sLineBreak + 'Статус: ' + IntToStr(Status) + sLineBreak + SysErrorMessage(GetLastError));
          posi := 1;
          b := 1;
          ResponseString := '';
          while b > 0 do begin
            if not InternetQueryDataAvailable( hReq, bytes, 0, 0 ) then
              raise Exception.Create('Ошибка при выполнении функции InternetQueryDataAvailable' + sLineBreak + SysErrorMessage(GetLastError));
            SetLength( ResponseString, Length(ResponseString) + bytes );
            InternetReadFile( hReq, @ResponseString[Posi], bytes, b );
            Inc(Posi, b);
          end;
        finally
          InternetCloseHandle(hReq);
        end;
      finally
        InternetCloseHandle(hCon);
      end;
    finally
      InternetCloseHandle(hInet);
    end;
//========== конец получения кода страницы ==========

    Result:=ResponseString;

//    ShowMessage('Результат: '+Result);
  end;

end;
Выдаёт ошибку при выполнении функции HttpSendRequest, статус 0.

UPD: и, почему-то, скомпилированная на компьютере, где не хочет работать, нормально отработала на другом домашнем компьютере... Странное совпадение: на компьютере, где не хотела работать - WinXP, а оба компьютера, где заработала - с Win7. В винде всё дело? Правкой кода можно от этого отвязаться?

Последний раз редактировалось Ship_1; 24.01.2017 в 01:37.
Ship_1 вне форума Ответить с цитированием
Старый 24.01.2017, 06:18   #2
igh0st
Форумчанин
 
Аватар для igh0st
 
Регистрация: 05.07.2010
Сообщений: 136
По умолчанию

Сложно сказать, хорошо бы поместить функцию в обертку try ... except и почитать сообщение, с которым вызывается исключение.
igh0st вне форума Ответить с цитированием
Старый 24.01.2017, 09:47   #3
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

igh0st, а можно немного подробнее? Какую именно функцию и какое (как) почитать сообщение?
Ship_1 вне форума Ответить с цитированием
Старый 24.01.2017, 09:55   #4
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

А не проще взять библиотеку для работы с HTTP?

Synapse, Indy
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 24.01.2017, 10:29   #5
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Alex11223, проще, если сайт не https или Delphi > 7. В моём случае результат условия false. Здесь это не проще. Как я прочитал, для Indy в работе с https нужен ещё один компонент кроме IdHTTP, который в седьмом отсутствовал. Может (то ли встречал, то ли не про это) проблему можно решить, обновив Indy. Но мне больше нравится когда у меня получается меньше зависеть от компонентов. Тем более на рабочей урезанной Дельфи у меня их и нет вообще (и установить нельзя).
Ship_1 вне форума Ответить с цитированием
Старый 24.01.2017, 10:37   #6
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Для Synapse не надо никакие компоненты ставить, просто подключить юниты, для HTTPS положить в папку exe ssleay32.dll и libeay32.dll (OpenSSL), и указать в коде использование SSL (как-то так http://stackoverflow.com/a/17480548/964478)
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 24.01.2017, 10:51   #7
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Хм... Спасибо за инфу, возьму на заметку, гляну при случае. Может, пригодится когда-нибудь. Но в целом для моего текущего случая таскать за маленькой программкой dll'ки - таки минус. Мне тут всего-то файлы по списку с сайта скачать надо.
Если время найдётся, а решение проблемы с WinInet нет, то проверю дома на своём XP этот Synapse. И что-то мне подсказывает, что решение проблемы таки не найдётся...
Ship_1 вне форума Ответить с цитированием
Старый 24.01.2017, 11:14   #8
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

А как искали-то? При работе с винапи надо проверять возвращаемые значения функций и смотреть GetLastError и т.п., в соответствии с документацией функции
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 24.01.2017, 12:06   #9
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Я-то? В яндексе "Delphi WinInet ошибка HttpSendRequest" Ничего не нашёл. Понадеялся, что здесь, может, помогут... Моего уровня знаний не хватает на то, чтобы "проверять возвращаемые значения функций и смотреть GetLastError".... Спасибо за ссылку. Яндекс что-то там меняет и поиск работает фигово... Попробую дома глянуть и понять чего-нибудь. Если получится...
Ship_1 вне форума Ответить с цитированием
Старый 24.01.2017, 16:13   #10
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Вот переделанный рабочий

Код:
function GetSiteCode(URL:String):String;
var
URL_Base,URL_Page:String;

  hInet, hCon, hReq: HINTERNET;
  Status, StatusSize, Index: DWORD;
  bytes, b, posi: Cardinal;
  ResponseString: AnsiString;
//=================================================
begin

  if pos('https://',URL)>0 then delete(URL,1,length('https://'));
  URL_Base:=PChar(copy(URL,1,pos('/',URL)-1));
  URL_Page:=PChar(copy(URL,pos('/',URL)+1,length(URL)-pos('/',URL)));
  ShowMessage(URL_Base+#13+URL_Page);


  begin
    hInet := InternetOpen('My Agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
    if not Assigned(hInet) then
      raise Exception.Create('Error InternetOpen' + sLineBreak + SysErrorMessage(GetLastError));
    try
      hCon := InternetConnect(hInet, PChar(URL_Base), INTERNET_DEFAULT_HTTPS_PORT , nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
      if not Assigned(hCon) then
        raise Exception.Create('Error InternetConnect' + sLineBreak + SysErrorMessage(GetLastError));
      try
        hReq := HttpOpenRequest(hCon, 'GET', PChar(URL_Page), HTTP_VERSION, nil, nil,  INTERNET_FLAG_SECURE, 0);
        if not Assigned(hReq) then
          raise Exception.Create('Error HttpOpenRequest' + sLineBreak + SysErrorMessage(GetLastError));
        try
          HttpSendRequest(hReq,'', 0, nil, 0);
          StatusSize := SizeOf(Status);
          Index := 0;
          HttpQueryInfo(hReq, HTTP_QUERY_FLAG_NUMBER or HTTP_QUERY_STATUS_CODE , @Status, StatusSize, Index);

          posi := 1;
          b := 1;
          ResponseString := '';
          while b > 0 do begin
            if not InternetQueryDataAvailable( hReq, bytes, 0, 0 ) then
              raise Exception.Create('Error InternetQueryDataAvailable' + sLineBreak
                      + SysErrorMessage(GetLastError));
            SetLength( ResponseString, Length(ResponseString) + bytes );
            InternetReadFile( hReq, @ResponseString[Posi], bytes, b );
            Inc(Posi, b);
          end;
        finally
          InternetCloseHandle(hReq);
        end;
      finally
        InternetCloseHandle(hCon);
      end;
    finally
      InternetCloseHandle(hInet);
    end;

    Result:=ResponseString;
  end;
У меня работает
Есть еще небольшая информация на эту тему здесь http://www.programmersforum.ru/showthread.php?t=302008

Последний раз редактировалось Aliens_wolfs; 24.01.2017 в 22:54.
Aliens_wolfs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Странная ошибка при записи в XML Юрий+ Windows Forms 0 14.06.2016 08:30
Странная ошибка при удалении пункта popupmenu в рантайм frte Общие вопросы Delphi 2 09.12.2014 21:13
Странная ошибка при обработке строки Didim Помощь студентам 31 08.11.2011 16:35
Странная ошибка при работе с вводом значения (dev C++) Николай ПН Помощь студентам 2 21.06.2011 11:56
Странная ошибка при выполнении okolobaxa Общие вопросы Delphi 2 03.07.2007 00:47