• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            C++博客 聯(lián)系 聚合 管理  

            Blog Stats

            文章分類(17)

            收藏夾(2)

            文章檔案(18)

            相冊(cè)

            Blogs

            citywanderer

            一、讀取url





            以下內(nèi)容部分引自http://blog.csdn.net/dlmu2001/article/details/5936122
            http的協(xié)議細(xì)節(jié)實(shí)現(xiàn)并不需要WebCore來(lái)關(guān)注,WebCore要關(guān)注的是,如何設(shè)置請(qǐng)求的相關(guān)頭部信息,如何獲取服務(wù)器返回回來(lái)的響應(yīng)體部數(shù)據(jù)。
            WebKit中同http打交道的類主要是ResourceRequest,ResourceResonse,ResourceHandle*,ResourceHandleManager等,這里先介紹同請(qǐng)求信息維護(hù)相關(guān)的ResourceRequest.
            ResourceRequest類的作用比較好理解,基本上就是維護(hù)http請(qǐng)求相關(guān)的信息(app或者內(nèi)核都有可能設(shè)置這些信息),然后當(dāng)WebCore發(fā)起http請(qǐng)求的時(shí)候,可以獲取這些信息,調(diào)用curl的接口設(shè)置對(duì)應(yīng)的http請(qǐng)求字段。在這些信息中,最常用到的是url。
            ResourceRequest類繼承于ResourceRequestBase類,絕大部分功能在ResourceRequestBase類中實(shí)現(xiàn)。
            一)ResourceRequest構(gòu)造:構(gòu)造一個(gè)ResourceRequest對(duì)象只需要url參數(shù)就夠了,這是比較簡(jiǎn)單的一個(gè)類,沒(méi)有維護(hù)其它類的對(duì)象或者句柄。
            ResourceRequest(const String& url);
            ResourceRequest(const KURL& url);
            二)ResourceRequest對(duì)象的創(chuàng)建與維護(hù)
            1.當(dāng)用戶輸入網(wǎng)址,觸發(fā)qt事件,由MainWindow(WebKitBuild/Debug/QtTestBrowser/moc_mainwindow.cpp:87<--moc_launcherwindow.cpp:145)調(diào)用changeLocation函數(shù)(另有openLocation等)。
            MainWindow(Tools/QtTestBrowser/mainwindow.cpp:194)獲取地址欄中的url(QString類型/usr/include/QtCore/qstring.h),創(chuàng)建QUrl類型(/usr/include/QtCore/qurl.h url規(guī)格化類,包括host、port、scheme等成員變量),加載頁(yè)面(page()->mainFrame()->load(url) page()函數(shù)是全局函數(shù)?)。

            最終調(diào)用QWebFrame::load(Source/WebKit/qt/Api/qwebframe.cpp:885)函數(shù),在該函數(shù)中,會(huì)構(gòu)造出ResourceRequest(Source/WebCore/platform/network/qt/ResourceRequest.h繼承ResourceRequestBaseSource/WebCore/platform/network/ResourceRequestBase.cpp)對(duì)象,并將這個(gè)對(duì)象作為一個(gè)參數(shù),調(diào)用FrameLoader對(duì)象的load函數(shù)(Source/WebCore/loader/FrameLoader.cpp:1450)。

            FrameLoader類負(fù)責(zé)將documents加載到Frames。當(dāng)你點(diǎn)擊一個(gè)鏈接的時(shí)候,F(xiàn)rameLoader創(chuàng)建一個(gè)新的處于”policy”狀態(tài)的DocumentLoader對(duì)象,等待WebKit客戶端決定是否處理這個(gè)加載。通常WebKit客戶端會(huì)指示FrameLoader將這個(gè)加載視為一個(gè)導(dǎo)航(navigation),而不是阻止加載等。

            DocumentLoader類中會(huì)維護(hù)這個(gè)ResourceRequest(FrameLoader.cpp:1460),policyChecker()
            ——>checkNavigationPolicy(
            Source/WebCore/loader/FrameLoader.cpp:1585)
            1585         policyChecker()->checkNavigationPolicy(loader->request(), loader, formState,
            1586             callContinueLoadAfterNavigationPolicythis);//回調(diào)函數(shù)?如下調(diào)用

            ——>m_frame->loader()->client()->dispatchDecidePolicyForNavigationAction(Source/WebCore/loader/PolicyChecker.cpp:87)
             84     m_callback.set(request, formState.get(), function, argument);//callContinueLoadAfterNavigationPolicy


            一旦客戶端指示FrameLoader將本次加載視為一個(gè)導(dǎo)航,F(xiàn)rameLoader就推動(dòng)DocumentLoader進(jìn)入”provisional”狀態(tài),在該狀態(tài),DocumentLoader會(huì)發(fā)起一個(gè)網(wǎng)絡(luò)請(qǐng)求,并等待以確定網(wǎng)絡(luò)請(qǐng)求將發(fā)起一個(gè)下載還是一個(gè)新的document。
            ——>page->d->acceptNavigationRequestSource/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp:1271)
                    callPolicyFunction(Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp:1283)
                    回調(diào)函數(shù)?如上
                     //——>(m_frame->loader()->policyChecker()->*function)(action) (245)
            ——>callback.call(Source/WebCore/loader/PolicyChecker.cpp:160)
            ——>m_navigationFunction(Source/WebCore/loader/PolicyCallback.cpp:103)
            ——>loader->continueLoadAfterNavigationPolicy(Source/WebCore/loader/FrameLoader.cpp:2977)

            2974 void FrameLoader::callContinueLoadAfterNavigationPolicy(void* argument,
            2975     const ResourceRequest& request, PassRefPtr<FormState> formState, bool shouldContinue)
            2976 {
            2977     FrameLoader* loader = static_cast<FrameLoader*>(argument);
            2978     loader->continueLoadAfterNavigationPolicy(request, formState, shouldContinue);
            2979 }

            ——>continueLoadAfterWillSubmitForm(Source/WebCore/loader/FrameLoader.cpp:3105)
            ——>m_provisionalDocumentLoader->startLoadingMainResource(Source/WebCore/loader/FrameLoader.cpp:2572)

            接下去,DocumentLoader會(huì)創(chuàng)建一個(gè)MainResourceLoader對(duì)象,這個(gè)對(duì)象主要用來(lái)通過(guò)ResourceHandle接口同平臺(tái)網(wǎng)絡(luò)庫(kù)進(jìn)行交互。將MainResourceLoader和DocumentLoader分開(kāi)來(lái)主要有兩個(gè)目的:(1)MainResourceLoader讓DocumentLoader從處理ResourceHandle回調(diào)的細(xì)節(jié)中抽身出來(lái)(2)降低MainResourceLoader的生命周期和DocumentLoader的生命周期(同Document綁定)的耦合度。

            ——>m_mainResourceLoader->load(Source/WebCore/loader/DocumentLoader.cpp:798)
            ——>loadNow(Source/WebCore/loader/MainResourceLoader.cpp:612)
            ——>ResourceHandle::create(Source/WebCore/loader/MainResourceLoader.cpp:585)
            ——>newHandle->start(Source/WebCore/platform/network/ResourceHandle.cpp:71)
            ——>new QNetworkReplyHandler(Source/WebCore/platform/network/qt/ResourceHandleQt.cpp:100)
                   ——>r.toNetworkRequest(Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp:399) 設(shè)置http頭
            ——>m_queue.push 提交事件? (Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp:401)
            ——>flush();(Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp:164)         
            ——>(m_replyHandler->*(m_enqueuedCalls.takeFirst()))();Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp:195)
            ——>QNetworkReplyHandler::start() (Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp:659)
                    建立連接(ESTABLISHED)、發(fā)送請(qǐng)求 665QNetworkReply* reply = sendNetworkRequest(d->m_context->networkAccessManager(), d->m_firstRequest); 
                     ——>601 WebCore::QNetworkReplyHandler::sendNetworkRequest 
                           ——>626 manager->get(m_request)
                  665     QNetworkReply* reply = sendNetworkRequest(d->m_context->networkAccessManager(), d->m_firstRequest);
                  669     m_replyWrapper = new QNetworkReplyWrapper(&m_queue, reply, m_resourceHandle->shouldContentSniff() && d->m_context-
                >mimeSniffingEnabled(), this);
                           ——>208 QNetworkReplyWrapper::QNetworkReplyWrapper(QNetworkReplyHandlerCallQueue* queue, QNetworkReply* reply, bool
                sniffMIMETypes, QObject* parent)
                              209     : QObject(parent)
                              210     , m_reply(reply)
                              211     , m_queue(queue)
                              212     , m_responseContainsData(false)
                              213     , m_sniffMIMETypes(sniffMIMETypes)
                              214 {
                               215     Q_ASSERT(m_reply);
                              216 
                              217     // setFinished() must be the first that we connect, so isFinished() is updated when running other slots.
                               //QT通過(guò)此種方式異步回調(diào)??(yes, 信號(hào)、槽機(jī)制,http://www.ibm.com/developerworks/cn/linux/guitoolkit/qt/signal-slot/ )
                              218     connect(m_reply, SIGNAL(finished()), this, SLOT(setFinished()));
                              219     connect(m_reply, SIGNAL(finished()), this, SLOT(receiveMetaData()));
                              220     connect(m_reply, SIGNAL(readyRead()), this, SLOT(receiveMetaData()));
                              221 }

            一旦加載系統(tǒng)接收到足夠的信息可以確定資源確實(shí)代表了document,F(xiàn)rameLoader就將DocumentLoader推向”committed”狀態(tài),在該狀態(tài)中,frame將顯示document。



            下載完了之后
            ——>QtMIMETypeSniffer::qt_metacall() (WebKitBuild/Debug/WebCore/moc_QtMIMETypeSniffer.cpp:77)
            ——>trySniffing()(Source/WebCore/platform/network/qt/QtMIMETypeSniffer.cpp:59
                  ——>m_sniffer.sniff(data.constData(), data.size())(Source/WebCore/platform/network/qt/QtMIMETypeSniffer.cpp:51)

             50     QByteArray data = m_reply->peek(m_sniffer.dataSize());
             
            51     const char* sniffedMimeType = m_sniffer.sniff(data.constData(), data.size());
                   data.constData()保存著網(wǎng)頁(yè)內(nèi)容,涉及的變量包括m_replym_sniffer

                  ——>emit finished (Source/WebCore/platform/network/qt/QtMIMETypeSniffer.cpp:65)    
                  ——>QMetaObject::activate(WebKitBuild/Debug/WebCore/moc_QtMIMETypeSniffer.cpp:88)
                  ……
                  WebCore::QNetworkReplyWrapper::qt_metacall (WebKitBuild/Debug/WebCore/moc_QNetworkReplyHandler.cpp)
            77     if (_c == QMetaObject::InvokeMetaMethod) {
             
            78         switch (_id) {
             
            79         case 0: receiveMetaData(); break;
             
            80         case 1: didReceiveFinished(); break;
             
            81         case 2: didReceiveReadyRead(); break;
             
            82         case 3: receiveSniffedMIMEType(); break;
             
            83         case 4: setFinished(); break;
             
            84         default: ;
             
            85         }

             
            86         _id -= 5;
             
            87     }

                  ——>receiveSniffedMIMEType()(WebKitBuild/Debug/WebCore/moc_QNetworkReplyHandler.cpp:82)
                  ——>emitMetaDataChanged()(Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp:305)
                     ——>QueueLocker lock(m_queue)(Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp)
                     ——>~QueueLocker() { m_queue->unlock(); } (203)
                     ——>flush();(178)
                     ——>(m_replyHandler->*(m_enqueuedCalls.takeFirst()))(); (195)
                     
                     ——>1、QNetworkReplyHandler::forwardData (572)
                     ——>client->didReceiveData(m_resourceHandle, data.constData(), data.length(), -1); (586)
                  ——>ResourceLoader::didReceiveData(ResourceHandle*, const char* data, int length, int encodedDataLength) (Source/WebCore/loader/ResourceLoader.cpp:427)
                           data指向保存頁(yè)面內(nèi)容
                  ——>MainResourceLoader::didReceiveData (Source/WebCore/loader/MainResourceLoader.cpp:431)
                  ——>ResourceLoader::didReceiveData (Source/WebCore/loader/ResourceLoader.cpp:267)
            279     addData(data, length, allAtOnce);
            280     // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
            281     // However, with today's computers and networking speeds, this won't happen in practice.
            282     // Could be an issue with a giant local file.
            283     if (m_sendResourceLoadCallbacks && m_frame)
            284         frameLoader()->notifier()->didReceiveData(this, data, length, static_cast<int>(encodedDataLength));
                        保存頁(yè)面到cache 函數(shù): addData()
                  ——>ResourceLoadNotifier::didReceiveData (Source/WebCore/loader/ResourceLoadNotifier.cpp:77)
                     ——>ResourceLoadNotifier::dispatchDidReceiveContentLength (133)
                  ——>InspectorInstrumentation::didReceiveContentLengthSource/WebCore/inspector/InspectorInstrumentation.h:713)
                  ——>InspectorInstrumentation::didReceiveContentLengthImplSource/WebCore/inspector/InspectorInstrumentation.cpp:487)
             
            html解析     
                  ——>2、QNetworkReplyHandler::finish(Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp:437)
                  ——>ResourceLoader::didFinishLoading (Source/WebCore/loader/ResourceLoader.cpp:434)
                  ——>MainResourceLoader::didFinishLoading (Source/WebCore/loader/MainResourceLoader.cpp:466)
                  ——>FrameLoader::finishedLoading (Source/WebCore/loader/FrameLoader.cpp:2287)
                  ——>DocumentLoader::finishedLoading (Source/WebCore/loader/DocumentLoader.cpp:282)
                     ——>FrameLoader::finishedLoadingDocument(DocumentLoader* loader) (Source/WebCore/loader/FrameLoader.cpp:2333)
                        ——>FrameLoaderClientQt::finishedLoading(DocumentLoader* loader) (Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp:626)
                     ——>DocumentWriter::end() (Source/WebCore/loader/DocumentWriter.cpp:211)
            211 void DocumentWriter::end()
            212 {
            213     m_frame->loader()->didEndDocument();
            214     endIfNotLoadingMainResource();
            215 }
                        213 ——>Document::finishParsing() (Source/WebCore/dom/Document.cpp:2246)
                        214: DocumentWriter::endIfNotLoadingMainResource() (Source/WebCore/loader/DocumentWriter.cpp  228
            228     addData(00true);
            229     m_frame->document()->finishParsing();
                           ——>DocumentWriter::addData() (208)               
                              ——>DecodedDataDocumentParser::appendBytes(DocumentWriter* writer , const char* data, int length, bool shouldFlush)Source/WebCore/dom/DecodedDataDocumentParser.cpp:40)
                              ——> HTMLDocumentParser::append(const SegmentedString& source) (Source/WebCore/html/parser/HTMLDocumentParser.cpp:367)
                              ——> HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode) (175)
                              ——> HTMLDocumentParser::pumpTokenizer(SynchronousMode mode) (261)
                              解析、執(zhí)行script
                                 ——> HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& session) (223)
                                 ——> HTMLDocumentParser::runScriptsForPausedTreeBuilder() (205)
                                 ——> HTMLScriptRunner::execute(PassRefPtr<Element> scriptElement, const TextPosition1& scriptStartPosition) Source/WebCore/html/parser/HTMLScriptRunner.cpp:167)
                                 ——> WebCore::HTMLScriptRunner::runScript(this=0x81e2a58, script=0x832c040, scriptStartPosition=...) (296)
                                 ——> WebCore::ScriptElement::prepareScript (this=0x832c084, scriptStartPosition=...,     supportLegacyTypes=WebCore::ScriptElement::DisallowLegacyTypeInTypeAttribute) (Source/WebCore/dom/ScriptElement.cpp:240)
                                 ——> WebCore::ScriptElement::executeScript (this=0x832c084, sourceCode=...) (283)
                                 ——> WebCore::ScriptController::evaluate (this=0x828d1a4, sourceCode=...) (Source/WebCore/bindings/js/ScriptController.cpp:166)
                                 ——> WebCore::ScriptController::evaluateInWorld (143)
                                 ——> WebCore::JSMainThreadExecState::evaluate (Source/WebCore/bindings/js/JSMainThreadExecState.h:54)
                                 ——> JSC::evaluate(exec=0xae3f499c, scopeChain=0xae3ee5c8, source=..., thisValue=...) (Source/JavaScriptCore/runtime/Completion.cpp:64)
                                 ——> JSC::Interpreter::execute (Source/JavaScriptCore/interpreter/Interpreter.cpp:767)
                                 ——> JSC::JITCode::execute (Source/JavaScriptCore/jit/JITCode.h:77)
                                 ——> ?? ()
                                 ——> WebCore::jsHTMLDocumentPrototypeFunctionWrite(WebCore/generated/JSHTMLDocument.cpp:445)
                                 ——> WebCore::JSHTMLDocument::write (Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp:161)
                                 ——> WebCore::documentWrite (156)
                                 ——> WebCore::Document::write (Source/WebCore/dom/Document.cpp:2227)
                                       ——> WebCore::HTMLDocumentParser::insert (Source/WebCore/html/parser/HTMLDocumentParser.cpp:324)
                                          回到了html的解析
                                       ——> WebCore::HTMLDocumentParser::pumpTokenizerIfPossible (175)
                                       ——> WebCore::HTMLDocumentParser::pumpTokenizer  (299)
                                                查看是否有script,1、如果有,轉(zhuǎn)到“ 解析、執(zhí)行script”;2、如果沒(méi)有轉(zhuǎn)到下面“”
                              完成解析html
                              InspectorInstrumentation::didWriteHTML(cookie, m_tokenizer->lineNumber());
                              ——> InspectorInstrumentation::didWriteHTML  (Source/WebCore/inspector/InspectorInstrumentation.h:803)
                              ——> 
                        ——> Document::finishParsing() (Source/WebCore/dom/Document.cpp:2259)
                              ——>HTMLDocumentParser::finish()  (Source/WebCore/html/parser/HTMLDocumentParser.cpp:427)
                              ——>HTMLDocumentParser::attemptToEnd() (399)
                              ——> 
                              
             生成dom樹(shù)     
                  


            附件(js)下載、解析



                  


            二、下載
            三、加載

            參考文檔
            1.官方文檔:http://www.webkit.org/blog/1188/how-webkit-loads-a-web-page/
            2.dlmu2001的譯文:http://blog.csdn.net/dlmu2001/article/details/5941432
            3.dlmu200:WebCore中的http請(qǐng)求信息維護(hù) http://blog.csdn.net/dlmu2001/article/details/59361221
            4.其他技術(shù)性文章:Introduction to WebKit Objective-C Programming Guide http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DisplayWebContent/DisplayWebContent.html
            5.其他技術(shù)性文章:Introduction to WebKit DOM Programming Topics http://developer.apple.com/library/mac/#documentation/AppleApplications/Conceptual/SafariJSProgTopics/WebKitJavaScript.html
            6. http://www.webkit.org/coding/technical-articles.html

            相關(guān)技巧
            1.cscope查找類的定義:cs find e class.*QString[^;]*($|{)

             

            posted on 2013-08-22 14:25 citywanderer 閱讀(2566) 評(píng)論(0)  編輯 收藏 引用 所屬分類: webkit
            99久久久国产精品免费无卡顿| www.久久热| 亚洲中文字幕无码久久2017| 久久成人小视频| 久久天堂AV综合合色蜜桃网| 国产精品久久波多野结衣| 91精品婷婷国产综合久久| 久久人人爽人爽人人爽av| 亚洲欧美国产精品专区久久| 久久综合噜噜激激的五月天| 一级做a爱片久久毛片| 午夜福利91久久福利| 亚洲va久久久噜噜噜久久狠狠 | 久久人做人爽一区二区三区 | 嫩草影院久久99| 久久久久亚洲av毛片大| 国产色综合久久无码有码| 久久成人国产精品二三区| 亚洲国产成人久久一区久久| 久久99亚洲网美利坚合众国| 久久99精品国产99久久6| 久久久久亚洲AV片无码下载蜜桃| 久久精品国产亚洲AV无码娇色| 精品免费久久久久国产一区| 一本色道久久99一综合| 国产精品免费久久久久影院| 亚洲熟妇无码另类久久久| 久久久久亚洲精品无码网址| 久久夜色精品国产网站| 很黄很污的网站久久mimi色| 久久精品国产2020| 久久国产V一级毛多内射| 久久婷婷激情综合色综合俺也去| 久久精品18| 久久亚洲欧美日本精品| 人人狠狠综合久久88成人| 久久亚洲精品无码播放| 老司机国内精品久久久久| 亚洲国产精品无码久久一区二区 | 久久久久久一区国产精品| 国产91色综合久久免费分享|