осознал насколько это интересная штука. Можно брать данные откуда хочешь, а WebBrowser их отобразит. Однако в статье не описано как проинформировать WebBrowser в каком формате передаются данные. Поэтому прошу помочь разобраться со следующими вопросами:
1. Как сообщить WebBrowser, что данные это страница html или картинка png, или xml? В протоколе http это делает соответствующий заголовок — Content-type. Как передать такой заголовок (да и другие заголовки http-протокола) в WebBrowser?
2. Как получить полностью заголовок запроса http-протокола, который отправляет WebBrowser и POST, PUT данные? Тут я докопался, что эту информацию можно узнать через IInternetBindInfo, но например, GetBindString не возвращает полный заголовок и некоторые отдельные, такие как UserAgent или версию OS. Что касается GetBindInfo, то выяснил, что POST и PUT данные находятся в поле stgmedData структуры BINDINFO, а дальше темный лес.
Re: Asynchronous Pluggable Protocol http-заголовки, post и put данные
Здравствуйте, east, Вы писали:
E>1. Как сообщить WebBrowser, что данные это страница html или картинка png, или xml? В протоколе http это делает соответствующий заголовок — Content-type. Как передать такой заголовок (да и другие заголовки http-протокола) в WebBrowser?
IProtocolSink.ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, MIMEType). IProtocolSink передается в IInternetProtocolRoot.Start
E>2. Как получить полностью заголовок запроса http-протокола, который отправляет WebBrowser и POST, PUT данные? Тут я докопался, что эту информацию можно узнать через IInternetBindInfo, но например, GetBindString не возвращает полный заголовок и некоторые отдельные, такие как UserAgent или версию OS. Что касается GetBindInfo, то выяснил, что POST и PUT данные находятся в поле stgmedData структуры BINDINFO, а дальше темный лес.
Imho, WebBrowser не обязан отдавать строку BINDSTRING_USERAGENT. Всякие UserAgent-ы — это специфика http(s). У тебя ведь не http(s)?
Re[2]: Asynchronous Pluggable Protocol http-заголовки, post и put данные
Здравствуйте, Aniskin, Вы писали:
A>Здравствуйте, east, Вы писали:
E>>1. Как сообщить WebBrowser, что данные это страница html или картинка png, или xml? В протоколе http это делает соответствующий заголовок — Content-type. Как передать такой заголовок (да и другие заголовки http-протокола) в WebBrowser?
A>IProtocolSink.ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, MIMEType). IProtocolSink передается в IInternetProtocolRoot.Start
Спасибо!
Главное уже в каком-то коде видел это и не разобрался.
E>>2. Как получить полностью заголовок запроса http-протокола, который отправляет WebBrowser и POST, PUT данные? Тут я докопался, что эту информацию можно узнать через IInternetBindInfo, но например, GetBindString не возвращает полный заголовок и некоторые отдельные, такие как UserAgent или версию OS. Что касается GetBindInfo, то выяснил, что POST и PUT данные находятся в поле stgmedData структуры BINDINFO, а дальше темный лес.
A>Imho, WebBrowser не обязан отдавать строку BINDSTRING_USERAGENT. Всякие UserAgent-ы — это специфика http(s). У тебя ведь не http(s)?
Это не критично, я для общего образования спрашивал, т.к. не понятно зачем вводить некоторые перечисления, если их не использовать. Могу ошибаться, но для ИЕ и контролов на основе ИЕ заголовок устанавливается в интернет-сессии из реестра.
Спасибо за помощь.
Re[3]: Asynchronous Pluggable Protocol http-заголовки, post и put данные
Здравствуйте, east, Вы писали:
A>>Imho, WebBrowser не обязан отдавать строку BINDSTRING_USERAGENT. Всякие UserAgent-ы — это специфика http(s). У тебя ведь не http(s)?
E>Это не критично, я для общего образования спрашивал, т.к. не понятно зачем вводить некоторые перечисления, если их не использовать.
Не проверял, но возможно если ты напишешь и перекроешь стандартный http протокол, то тебе будут передаваться UserAgent-ы и прочая атрибутика http протокола.
Re: Asynchronous Pluggable Protocol http-заголовки, post и put данные
В общем начал делать протокол и столкнулся с такой ситуацией. В методе Start загружаю данные в буфер и сообщаю браузеру, что есть данные. В методе Read отдаю данные. Однако после нескольких вызовов Read браузер вновь создает объект протокола и по новому вызывает метод Start. Получается, что данные полностью не загрузились в браузер и началась новая сессия. Что может быть?
Может кто подскажет хорошую инфу по асинхронным протоколам, чтобы все мелочи описывались.
Re[2]: Asynchronous Pluggable Protocol http-заголовки, post и put данные
Здравствуйте, east, Вы писали:
E>В методе Start загружаю данные в буфер и сообщаю браузеру, что есть данные. В методе Read отдаю данные. Однако после нескольких вызовов Read браузер вновь создает объект протокола и по новому вызывает метод Start. Получается, что данные полностью не загрузились в браузер и началась новая сессия. Что может быть?
А что и в какой последовательности передаешь в ProtocolSink.ReportProgress?
Re[3]: Asynchronous Pluggable Protocol http-заголовки, post и put данные
Здравствуйте, Aniskin, Вы писали:
A>Здравствуйте, east, Вы писали:
E>>В методе Start загружаю данные в буфер и сообщаю браузеру, что есть данные. В методе Read отдаю данные. Однако после нескольких вызовов Read браузер вновь создает объект протокола и по новому вызывает метод Start. Получается, что данные полностью не загрузились в браузер и началась новая сессия. Что может быть?
A>А что и в какой последовательности передаешь в ProtocolSink.ReportProgress?
Просто передаю mime-тип. Код примерно такой, точно не помню, т.к. проект на другом компьютере.
HRESULT STDMETHODCALLTYPE CMyProtocol::Start(
/* [in] */ LPCWSTR szUrl,
/* [in] */ IInternetProtocolSink __RPC_FAR *pOIProtSink,
/* [in] */ IInternetBindInfo __RPC_FAR *pOIBindInfo,
/* [in] */ DWORD grfPI,
/* [in] */ DWORD dwReserved)
{
ATLTRACE(_T("CMyProtocol::Start ()\n"));
//загружаем данные
m_BD.Load(szUrl);
pOIProtSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, m_BD.m_sMimeType);
//информируем о том что есть что отображать
pOIProtSink->ReportData(BSCF_FIRSTDATANOTIFICATION, 0, m_BD.m_DataLen);
return S_OK;
}
Re[4]: Asynchronous Pluggable Protocol http-заголовки, post и put данные
Здравствуйте, east, Вы писали:
E>Код примерно такой.
BindInfo может содержать флаг BINDF_NEEDFILE. В этом случае требуется создавать временный файл, в который нужно записывать передаваемые данные. Я обычно пишу в кэш Эксплорера (CreateUrlCacheEntry/CommitUrlCacheEntry).
Re[5]: Asynchronous Pluggable Protocol http-заголовки, post и put данные
Здравствуйте, Aniskin, Вы писали:
A>BindInfo может содержать флаг BINDF_NEEDFILE. В этом случае требуется создавать временный файл, в который нужно записывать передаваемые данные. Я обычно пишу в кэш Эксплорера (CreateUrlCacheEntry/CommitUrlCacheEntry).
Т.е. записать данные в кеш и не сообщать, что данные готовы, чтобы не вызывался Read? Или как?
Хотя судя по статье
все должно быть просто, как я сделал. Все работает нормально когда данных мало, но когда их 20К, появляется ситуация описанная выше.
Где вообще можно почитать о работе асинхронного протокола по подробней? Может у кого есть код нормально работающего протокола? А то в сети нашел пару вариантов, ничего там не понял и разбираться нет возможности, т.к. не работают, выдают ошибки.
Re[6]: Asynchronous Pluggable Protocol http-заголовки, post и put данные
Здравствуйте, east, Вы писали:
E>Т.е. записать данные в кеш и не сообщать, что данные готовы, чтобы не вызывался Read?
Сообщить, что есть файл вызовом ProtocolSink.ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE), и при поступлении данных писать их в этот файл. При этом если Read вызывается, то и отдавать полученные данные.
Я делаю следующие вызовы:
ProtocolSink.ReportProgress(BINDSTATUS_FINDINGRESOURCE, PWideChar(Url));
ProtocolSink.ReportProgress(BINDSTATUS_CONNECTING, PWideChar(Url));
ProtocolSink.ReportProgress(BINDSTATUS_SENDINGREQUEST, PWideChar(Url));
ProtocolSink.ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, PWideChar(Response.MIMEType));
ProtocolSink.ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE, PWideChar(Stream.FileName));
ProtocolSink.ReportData(BSCF_FIRSTDATANOTIFICATION, 0, 0);
ProtocolSink.ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, Saved, Size); // Много раз
ProtocolSink.ReportData(BSCF_LASTDATANOTIFICATION or BSCF_DATAFULLYAVAILABLE, Saved, Size);
ProtocolSink.ReportResult(S_OK, Response.Status, nil);
Все это происходит из отдельного потока.
Re[7]: Asynchronous Pluggable Protocol http-заголовки, post и put данные
Здравствуйте, Aniskin, Вы писали:
A>Сообщить, что есть файл вызовом ProtocolSink.ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE), и при поступлении данных писать их в этот файл. При этом если Read вызывается, то и отдавать полученные данные.
A>Я делаю следующие вызовы:
A>ProtocolSink.ReportProgress(BINDSTATUS_FINDINGRESOURCE, PWideChar(Url)); A>ProtocolSink.ReportProgress(BINDSTATUS_CONNECTING, PWideChar(Url)); A>ProtocolSink.ReportProgress(BINDSTATUS_SENDINGREQUEST, PWideChar(Url)); A>ProtocolSink.ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, PWideChar(Response.MIMEType)); A>ProtocolSink.ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE, PWideChar(Stream.FileName)); A>ProtocolSink.ReportData(BSCF_FIRSTDATANOTIFICATION, 0, 0); A>ProtocolSink.ReportData(BSCF_INTERMEDIATEDATANOTIFICATION, Saved, Size); // Много раз A>ProtocolSink.ReportData(BSCF_LASTDATANOTIFICATION or BSCF_DATAFULLYAVAILABLE, Saved, Size); A>ProtocolSink.ReportResult(S_OK, Response.Status, nil);
A>Все это происходит из отдельного потока.
Как и следовало ожидать, ничего не изменилось. Все равно браузер два раза вызывает метод Start в разных потоках. Наблюдается такая ситуация, если в Start просто вернуть S_OK, то браузер виснет. Если вызвать ReportData или ReportResult, то Start вызывается второй раз в другом потоке и следовательно вызываются все остальные методы и как следствие страница не найдена и ошибки.
Может у кого есть рабочий код асинхронного протокола?
Re[8]: Asynchronous Pluggable Protocol http-заголовки, post и put данные
E>Как и следовало ожидать, ничего не изменилось. Все равно браузер два раза вызывает метод Start в разных потоках. Наблюдается такая ситуация, если в Start просто вернуть S_OK, то браузер виснет. Если вызвать ReportData или ReportResult, то Start вызывается второй раз в другом потоке и следовательно вызываются все остальные методы и как следствие страница не найдена и ошибки. E>Может у кого есть рабочий код асинхронного протокола?
Как не стыдно признавать, но ошибка у меня была в другом месте. Неправильно получал mime-тип. Вот из-за этого и вылазили ошибки. Вышеприведенный код работает нормально, пока глюков не замечал. Можно выводить его как в отдельный поток, так и в методе Start.