Hi,
пытаюсь написать либу под ие для мониторинга трафика протекающего. написал. -все работает, вижу все странички, жава скрипты, картинки — ие радуется что все на месте. Но тут, попал на один сайтец http://gcl.ncl.novostimira.biz/52704/434 с ним както все очень странно выходит...
1. первым делом качаем редирект ответ от сервака на http://60seconds.com.ua/index.php?page=shop.product_details&category_id=14&flypage=flypage.tpl&product_id=64&option=com_virtuemart&Itemid=118
2. на той страничке есть прописана подгрузка стилей
link rel="stylesheet" href="/components/com_jcomments/tpl/default/style.css?v=12" type="text/css"
как видно она относительна от текущей локации(?)
без моих хуков грузит стиль с 60seconds.com.ua, но как только включаю хуки ИЕ пытается подгрузить стиль с gcl.ncl.novostimira.biz... и + к всему в адресной строке не меняется адресс локации.
как таке может быть? если по логам HttpAnalyzer вижу картину
GET http://gcl.ncl.novostimira.biz/52704/434 - REDIRECT TO http://60seconds.com.ua/index.php?page=shop.product_details&category_id=14&flypage=flypage.tpl&product_id=64&option=com_virtuemart&Itemid=118
GET http://60seconds.com.ua/index.php?page=shop.product_details&category_id=14&flypage=flypage.tpl&product_id=64&option=com_virtuemart&Itemid=118
GET http://60seconds.com.ua/modules/mod_callback/tmpl/style.css (один единственный стиль грузим с "правильного" сайта)
//а дальше
GET http://gcl.ncl.novostimira.biz/components/com_jcomments/tpl/default/style.css?v=12 //и получаем в ответ 302 Found, т.к. данный стиль должен был бы грузится с 60seconds.com.ua
смотрю по дебаг принтам со своих хуков — все вроде проходит нормально (не вижу я по крайней мере ничего подозрительного)
поставил бряк на InternetConnect() когда коннестимся мы на "невалидный" хост (gcl.ncl.novostimira.biz вместо 60seconds.com.ua), посмотрел каллстек
посмотрел что передаем в urlmon!CINet::Start() — наш кривой адресок, выходит mshtml я заставил запутаться и не понимает она что пора редиректится (не сморя на то что страничку после редиректа + один стиль мы скачали удачно)
мож кто-нибудь подтолкнет в нужном направлении,а то сижу и второй день — просто смотрю на логи и ничего понять не могу.
спасиб!
типичный паттерн фикса — убираем максимум хуков пока воспроизводится проблема, потом убираем из оставшихся хуков максимум кода, пока воспроизводится проблема, и если все еще самому непонятна причина — толково пишем на RSDN как устроены и что делают хуки
Как много веселых ребят, и все делают велосипед...
Выкинуть хуки сразу подумалось, но там кода — необходимый минимум, т.е. если чтото убрать — общая картина перестает полностью работать.
Решил пересобрать логи, пересмотреть по новому и подготовить что-то для поста сюда. Во время подготовки логов было замечено что я упустил один немаловажный момент — INTERNET_STATUS_RESPONSE_RECEIVED в каллбеке. Как его правильно обрабатывать я так и не понял,у меня еррор (ERROR_INTERNET_INCORRECT_HANDLE_STATE) валится при попытке вычитать данные при помощи как InternetReadFile так и pInternetReadFileEx. Читал заметки одного "Хакер"-а_телепата..лучше бы его не читал, а то запутал полностью. Вот как я обрабатываю данное событие:
BOOL
IeReadData (
IN PCONNECTION hConn,
IN OUT PULONG DataSize
)
{
ULONG size;
BYTE buff [MAX_PATH];
PVOID Buffer;
ULONG TotalSize;
BOOL result;
/*
Read data from wininet
return TRUE only if all data was received
otherwise return FALSE
*/
DPRINT( "<IeReadData BEGIN> for [%X]\n\tInetHandle: %X\n\tStage: %X\n\tDataSize: %X\n\n",
hConn,
hConn->InetHandle,
hConn->Stage,
*DataSize );
size = *DataSize;
Buffer = Alloc( isd,
size,
NULL,
hConn );
if (!Buffer)
return 0;
result = FALSE;
TotalSize = 0;
while (TRUE) {
if (!isd->vpt.pInternetReadFile( hConn->InetHandle, Buffer, size, &size )) {
if (Buffer != buff)
Free( isd,
Buffer,
NULL,
hConn );
break;
}
if (!size) {
/* all data has been readed from wininet */
result = TRUE;
break;
}
TotalSize += size;
if (Buffer == buff) {
Buffer = Alloc( isd,
size,
NULL,
hConn );
if (!Buffer) {
TotalSize -= size;
break;
}
MemCpy( Buffer,
buff,
size );
}
Buffer = buff;
size = sizeof( buff );
}
DPRINT( "<IeReadData DONE> for [%X]\n\tInetHandle: %X\n\tStage: %X\n\tTotalSize: %X\n\tError: %X\n\n",
hConn,
hConn->InetHandle,
hConn->Stage,
TotalSize,
GetLastError() );
*DataSize = TotalSize;
return result;
}
VOID
CALLBACK
InternetStatusCallbackHook (
IN HINTERNET hInternet,
IN DWORD_PTR Context,
IN DWORD InternetStatus,
IN PVOID StatusInformation,
IN DWORD StatusInformationLength
)
{
PCONNECTION hConn;
BOOL SkipOrigCall;
hConn = SearchConnection( hInternet );
if (hConn) {
SkipOrigCall = TRUE;
switch (InternetStatus) {
case INTERNET_STATUS_RESPONSE_RECEIVED:
if (StatusInformation && StatusInformationLength == sizeof(DWORD)) {
/* try read data from wininet buffer */
size = *(PDWORD)StatusInformation;
result = IeReadData( hConn,
&size );
if (result) {
/* all data received - return data to ie */
SkipOrigCall = FALSE;
}
} else
SkipOrigCall = FALSE;
break;
}
} else
SkipOrigCall = FALSE;
if (!SkipOrigCall)
((INTERNET_STATUS_CALLBACK)InternetStatusCallbackOrig)( hInternet,
Context,
InternetStatus,
StatusInformation,
StatusInformationLength );
}
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Здравствуйте, linkoln, Вы писали:
J>странные у вас хуки... вот вы в логи пишите а где GetLastError/SetLastError ?
В данном хуке не вижу смысла устанавливать последний еррор. Чтение, прошу заметить есть
DPRINT( "<IeReadData DONE> for [%X]\n\tInetHandle: %X\n\tStage: %X\n\tTotalSize: %X\n\tError: %X\n\n",
hConn,
hConn->InetHandle,
hConn->Stage,
TotalSize, GetLastError() );
еще где нужно обрабатывать еррор код — в данном хуке не вижу.
Здравствуйте, ononim, Вы писали:
J>угу, + еще и не thread-safe'овые
тут малость не все рассказал — Alloc\Free, это мои внутренние функи, которые выделяет\освобождает память в мемори_стриме для данного коннекшина. Сразу не сказал — извиняюсь.
L>еще где нужно обрабатывать еррор код — в данном хуке не вижу.
Дело не в том чтоб вы обрабатывали ластеррор, а в том чтобы ваш код обработчика хука его не исказил.
J>>угу, + еще и не thread-safe'овые L>прошу прощения, а что тут не thread-safe'овое?
Сори, показалось что SkipOrigCall — глобальная переменная. Как выяснилось — она локальная. Мимимизируйте Минимизируйте свой код дальше...
Как много веселых ребят, и все делают велосипед...
подровнял кодез, внедрил наконецто референс_каунт + еррор_коды сохраняю-востанавливаю.
НО это не дал решения моей трабле с
<IeReadData BEGIN> for [3A0FC4]
InetHandle: CC000C
Stage: 0
DataSize: 2FA
тестанул еще разок, с ретурном при данном каллбеке — тож самое.
я умудрился заставить ИЕ игнорировать редиректы, т.к. пошел на google.com а редирект на google.com.ua не произошел в аддресной строке) хотя подгрузило контент с гугл_украина...
=может я чет с каллбеками недоучитываю..может нужно каллбекать ИЕ при какихто условиях помимо как "вычитал все данные"???
Здравствуйте, Kubyshev Andrey, Вы писали:
KA>Ну вот ты вычитал все данные в своем коллбеке, а что прочтет оригинальный коллбек ?
если все вычитать получилось в каллбеке (будь то INTERNET_STATUS_RESPONSE_RECEIVED или INTERNET_STATUS_REQUEST_COMPLETE) — сразу же вызываю калбек оригинальный по этому поводу... Если не вышло сейчас — то пробую закачать еще на хуках InternetQueryDataAvailable | InternetReadFile | InternetReadFileEx, если же там вышло закачать все данные то мы колаем оригинальный прок каллбека и по хуку возвращаем все данные что остались, т.е. если в каллбеке оригинальный прок решит все выкачать — пусть, в хуке тогда уже отдадим что недокачал..
НО суть не в этом — ПОЧЕМУ МНЕ ВОЗВРАЩАЕТ ЕРРОР ПРИ ЧТЕНИИ ДАННЫХ В КАЛЛБЕКЕ?????
INTERNET_STATUS_RESPONSE_RECEIVED — InternetReadFile() возвращает ошибку ERROR_INTERNET_INCORRECT_HANDLE_STATE -почему стет инкоррект, как правильнор вычитвать в этом каллбеке???