crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> wxHTTP - отображение html содержимого
Гость_wxFan_*
сообщение 12.9.2011, 16:00
Сообщение #1





Гости








    


Привет всем! Проблема заключается в отображении содержимого страницы с инета на консоль. Запрос успешно проходит, но вот попытка распаковать содержимое и впихать его в wxString приводит к переполнению wxString объекта. Без отладки это выглядит как пустая консолька, которая через некоторое время валится с ошибкой SIGSEGV. Валится прога после вызова Read. Сам вызов при отлаживании около 5сек происходит (курсор текущей строки отладки пропадает, после чего появляется вместе с SIGSEGV ошибкой на следующей после ...Read строки)
Функция, занимающаяся коннектом
#include заголовок
wxString MyClass::GetPageContent()
{
    wxHTTP *con = new wxHTTP();
    con->SetHeader("User-Agent", юзер агент);
    con->SetHeader("Host", хост);
    con->SetHeader("Accept", "text/html");
    con->SetHeader("Accept-Language", "ru-RU,ru;q=0.9,en;q=0.8");
    con->SetHeader("Accept-Encoding", "gzip, deflate");
              con->SetHeader("Connection", "Keep-Alive");
    con->Connect(хост);
    
    //wxFileOutputStream fileStream("C:\\1.gzip");
    //fileStream.Write(*(con->GetInputStream("/")));
    //fileStream.Close();

    wxByte buf[30000];
    wxZlibInputStream inStream(con->GetInputStream("/"), wxZLIB_GZIP);
    inStream.Read(buf, 30000);
    wxString resp(buf);
    con->GetResponse();
    
    wxDELETE(con);
    return resp;
}


Консолька
#include "App.h"
bool MyApp::OnInit()
{
    MyClass *client = new MyClass();
    wxPuts(client->GetPageContent());
    return true;
}


Если убрать код, занимающийся распаковкой gzip и записью распакованного содержимого в буфер, а взамен раскомментировать 3 строчки, то на хард успешно запишется файл 1.gzip (5кб), распаковав который архиватором получается файл без расширения (11кб), который содержит в себе нужную страницу. Несмотря на это запись файла в 5кб происходит подозрительно небыстро (может, около 5 сек +-): почти мгновенно появляется файл в 4кб и уже под конец еще кб добавляется и консолька завершает свою работу.
MinGW, Win7 Sp1 Pro, CodeLite IDE 3.0.5045, wxWidgets 2.9.2 (unicode=on)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 12.9.2011, 20:18
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


тут возможны тонкости с кодировкой. почему бы не использовать wxChar вместо wxByte? он, по крайней мере, не будет зависеть от настроек компиляции проекта.
я вот даже навскидку не могу сказать, к чему он приведёт wxByte в конструкторе wxString и как он будет вычислять длину, которая в этом конструкторе не указана явно. а неявно там применяются методы преобразования строк, расписанные в документации на wxString и соответственно, разные методы вычисления длины строки. скорее всего, его заглючивает в этом месте и он не может преобразовать строки.
я думаю, всё это отлично можно поглядеть в дебаге или хотя бы проверить длину полученной строки.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_wxFan_*
сообщение 17.9.2011, 11:51
Сообщение #3





Гости








    


Сменил код на следующий, тоже самое. Вероятно, какой-либо баг, либо я по-прежнему что-то упускаю.

Code
wxString SomeFunc()
{
    wxHTTP *con = new wxHTTP();
    con->SetHeader("User-Agent", "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.9.168 Version/11.51");
    con->SetHeader("Host", "some url");
    con->SetHeader("Accept", "text/html");
    con->SetHeader("Accept-Language", "ru-RU,ru;q=0.9,en;q=0.8");
    con->SetHeader("Accept-Encoding", "gzip, deflate");
              con->SetHeader("Connection", "Keep-Alive");
    wxZlibInputStream inStream(con->GetInputStream("/"), wxZLIB_GZIP);
    wxTextInputStream txtStream(inStream);
    wxString resp = txtStream.ReadWord();
    
    wxDELETE(con);
    return resp;
}

Успешно проходит запрос, после чего получаю ошибку, как можно увидеть на скриншоте ниже на функции OnSysRead:

Функция OnSysRead:
size_t wxZlibInputStream::OnSysRead(void *buffer, size_t size)
{
  wxASSERT_MSG(m_inflate && m_z_buffer, wxT("Inflate stream not open"));

  if (!m_inflate || !m_z_buffer)
    m_lasterror = wxSTREAM_READ_ERROR;
  if (!IsOk() || !size)
    return 0;

  int err = Z_OK;
  m_inflate->next_out = (unsigned char *)buffer;
  m_inflate->avail_out = size;

  while (err == Z_OK && m_inflate->avail_out > 0) {
    if (m_inflate->avail_in == 0 && m_parent_i_stream->IsOk()) {
      m_parent_i_stream->Read(m_z_buffer, m_z_size);
      m_inflate->next_in = m_z_buffer;
      m_inflate->avail_in = m_parent_i_stream->LastRead();
    }
    err = inflate(m_inflate, Z_SYNC_FLUSH);
  }

  switch (err) {
    case Z_OK:
        break;

    case Z_STREAM_END:
      if (m_inflate->avail_out) {
        // Unread any data taken from past the end of the deflate stream, so that
        // any additional data can be read from the underlying stream (the crc
        // in a gzip for example)
        if (m_inflate->avail_in) {
          m_parent_i_stream->Reset();
          m_parent_i_stream->Ungetch(m_inflate->next_in, m_inflate->avail_in);
          m_inflate->avail_in = 0;
        }
        m_lasterror = wxSTREAM_EOF;
      }
      break;

    case Z_BUF_ERROR:
      // Indicates that zlib was expecting more data, but the parent stream
      // has none. Other than Eof the error will have been already reported
      // by the parent strean,
      m_lasterror = wxSTREAM_READ_ERROR;
      if (m_parent_i_stream->Eof())
      {
          wxLogError(_("Can't read inflate stream: unexpected EOF in underlying stream."));
      }
      break;

    default:
      wxString msg(m_inflate->msg, *wxConvCurrent);
      if (!msg)
        msg = wxString::Format(_("zlib error %d"), err);
      wxLogError(_("Can't read from inflate stream: %s"), msg.c_str());
      m_lasterror = wxSTREAM_READ_ERROR;
  }

  size -= m_inflate->avail_out;
  m_pos += size;
  return size;
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Sokoloff
  опции профиля:
сообщение 18.9.2011, 9:19
Сообщение #4


Участник
**

Группа: Участник
Сообщений: 237
Регистрация: 1.4.2009
Из: Москва
Пользователь №: 654

Спасибо сказали: 50 раз(а)




Репутация:   11  


Может вам поиграться с заголовком "Accept-Encoding"? Или сменить метод, или даже отключить сжатие совсем.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 18.9.2011, 23:30
Сообщение #5


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


с wxWiki по wxHTTP:
Цитата
wxInputStream *GetInputStream(const wxString& path)
Get a page from the server specified by the last call to Connect(...). Path is path to a resource on the server not a full URL.
Note: You must call one of the Connect functions at least once before using this function or the result will be NULL.

Внимательно читаем документацию
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_wxFan_*
сообщение 21.9.2011, 8:57
Сообщение #6





Гости








    


Доки читал, оказалось по енвнимательности забыл этот коннект. Всем спасибо, проблема решена)))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 25.11.2024, 5:18