Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

Protocol handler in Gecko

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Nächste SlideShare
Ownership System in Rust
Ownership System in Rust
Wird geladen in …3
×

Hier ansehen

1 von 40 Anzeige

Weitere Verwandte Inhalte

Diashows für Sie (20)

Andere mochten auch (20)

Anzeige

Ähnlich wie Protocol handler in Gecko (20)

Weitere von Chih-Hsuan Kuo (20)

Anzeige

Aktuellste (20)

Protocol handler in Gecko

  1. 1. PROTOCOL HANDLER in Gecko Tommy Kuo [:KuoE0] kuoe0@mozilla.com 2015.03.03 @Mozilla Taiwan
  2. 2. Outline • What Protocol Handlers Can Do • The Walkthrough from Awesome Bar to Protocol Handlers • The Brief Introduction to Channels
  3. 3. What Protocol Handlers Can Do
  4. 4. URI Syntax <scheme name> : <hierarchical part> [ ? <query> ] [ # <fragment> ] http : //google.com/search ? q=Mozilla https : //www.facebook.com/pages/郝神好神/871866229523862 file : ///Downloads/郝神好帥.jpg about : config mailto : kuoe0@mozilla.com chrome : //browser/skin/Info.png line : //shop/detail/xxx
  5. 5. Protocol Handler Format the URI Create the channel Get flags NewChannel2(…) NewProxiedChannel2(…) NewURI(…) GetProtocolFlags(…)
  6. 6. nsresult nsIOService::NewURI(const nsACString &aSpec, const char *aCharset, nsIURI *aBaseURI, nsIURI **result) { NS_ASSERTION(NS_IsMainThread(), "wrong thread"); static uint32_t recursionCount = 0; if (recursionCount >= MAX_RECURSION_COUNT) return NS_ERROR_MALFORMED_URI; AutoIncrement inc(&recursionCount); nsAutoCString scheme; nsresult rv = ExtractScheme(aSpec, scheme); if (NS_FAILED(rv)) { // then aSpec is relative if (!aBaseURI) return NS_ERROR_MALFORMED_URI; rv = aBaseURI->GetScheme(scheme); if (NS_FAILED(rv)) return rv; } // now get the handler for this scheme nsCOMPtr<nsIProtocolHandler> handler; rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler)); if (NS_FAILED(rv)) return rv; return handler->NewURI(aSpec, aCharset, aBaseURI, result); } nsIOService::NewURI (netwerk/base/nsIOService.cpp)
  7. 7. nsCOMPtr<nsIProtocolHandler> handler; rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler)); if (NS_FAILED(rv)) return rv; uint32_t protoFlags; rv = handler->GetProtocolFlags(&protoFlags); if (NS_FAILED(rv)) return rv; bool newChannel2Succeeded = true; nsCOMPtr<nsIProxiedProtocolHandler> pph = do_QueryInterface(handler); if (pph) { rv = pph->NewProxiedChannel2(aURI, nullptr, aProxyFlags, aProxyURI, aLoadInfo, result); // if calling NewProxiedChannel2() fails we try to fall back to // creating a new proxied channel by calling NewProxiedChannel(). if (NS_FAILED(rv)) { newChannel2Succeeded = false; rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, result); } } else { rv = handler->NewChannel2(aURI, aLoadInfo, result); // if calling newChannel2() fails we try to fall back to // creating a new channel by calling NewChannel(). if (NS_FAILED(rv)) { newChannel2Succeeded = false; rv = handler->NewChannel(aURI, result); } } nsIOService::NewChannelFromURIWithProxyFlagsInternal (netwerk/base/nsIOService.cpp)
  8. 8. nsCOMPtr<nsIProtocolHandler> handler; rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler)); if (NS_FAILED(rv)) return rv; uint32_t protoFlags; rv = handler->GetProtocolFlags(&protoFlags); if (NS_FAILED(rv)) return rv; bool newChannel2Succeeded = true; nsCOMPtr<nsIProxiedProtocolHandler> pph = do_QueryInterface(handler); if (pph) { rv = pph->NewProxiedChannel2(aURI, nullptr, aProxyFlags, aProxyURI, aLoadInfo, result); // if calling NewProxiedChannel2() fails we try to fall back to // creating a new proxied channel by calling NewProxiedChannel(). if (NS_FAILED(rv)) { newChannel2Succeeded = false; rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, result); } } else { rv = handler->NewChannel2(aURI, aLoadInfo, result); // if calling newChannel2() fails we try to fall back to // creating a new channel by calling NewChannel(). if (NS_FAILED(rv)) { newChannel2Succeeded = false; rv = handler->NewChannel(aURI, result); } } nsIOService::NewChannelFromURIWithProxyFlagsInternal (netwerk/base/nsIOService.cpp)
  9. 9. Create An Protocol Handler • Implementation • NewURI • NewChannel2 / NewChannel (not recommended) • GetProtocolFlags • Registration • See 謀智菜逼⼋八談 XPCOM 實務⼊入⾨門
  10. 10. ./extensions/gnomevfs/nsGnomeVFSProtocolHandler.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MOZ_GNOMEVFS_SCHEME, &kNS_GNOMEVFSPROTOCOLHANDLER_CID }, ./extensions/gio/nsGIOProtocolHandler.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MOZ_GIO_SCHEME, &kNS_GIOPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "file", &kNS_FILEPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &kNS_HTTPPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "https", &kNS_HTTPSPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &kNS_FTPPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "resource", &kNS_RESPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "about", &kNS_ABOUTPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-safe-about", &kNS_SAFEABOUTPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "app", &kNS_APPPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "data", &kNS_DATAPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-device", &kNS_DEVICEPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "view-source", &kNS_VIEWSOURCEHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "wyciwyg", &kNS_WYCIWYGPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ws", &kNS_WEBSOCKETPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "wss", &kNS_WEBSOCKETSSLPROTOCOLHANDLER_CID }, ./netwerk/build/nsNetModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "rtsp", &kNS_RTSPPROTOCOLHANDLER_CID }, ./image/decoders/icon/nsIconModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-icon", &kNS_ICONPROTOCOL_CID }, ./xpcom/build/XPCOMInit.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID }, ./toolkit/components/places/nsPlacesModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-anno", &kNS_ANNOPROTOCOLHANDLER_CID }, ./widget/android/nsWidgetFactory.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "android", &kNS_ANDROIDPROTOCOLHANDLER_CID }, ./layout/build/nsLayoutModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_CID }, ./layout/build/nsLayoutModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASTREAMURI_SCHEME, &kNS_MEDIASTREAMPROTOCOLHANDLER_CID }, ./layout/build/nsLayoutModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASOURCEURI_SCHEME, &kNS_MEDIASOURCEPROTOCOLHANDLER_CID }, ./layout/build/nsLayoutModule.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX FONTTABLEURI_SCHEME, &kNS_FONTTABLEPROTOCOLHANDLER_CID }, ./modules/libjar/nsJARFactory.cpp: { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "jar", &kNS_JARPROTOCOLHANDLER_CID }, $ grep -ir -E "{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX [^,]+,[^}]+ }" .
  11. 11. Awesome Bar to Protocol Handlers
  12. 12. http://google.com/
  13. 13. http://google.com/ How to interact to HTTP protocol?
  14. 14. handleCommand openUILinkIn openLinkIn loadURIWithFlags (tabbrowser) loadURIWithFlags (browser) LoadURI(char16_t*, …) LoadURIWithBase LoadURI(nsIURI*, …) InternalLoad DoURILoad DoChannelLoad NS_NewURI NS_NewChannelInternal Browser UI (XUL) DocShell Necko GetProtocolHandler GetProtocolHandler nsIURI nsIChannel NewURI NewChannel2
  15. 15. Browser UI
  16. 16. <textbox id=“urlbar"></text> browser/base/content/browser.xul <tabbrowser />
  17. 17. <textbox id="urlbar" flex="1" placeholder="&urlbar.placeholder2;" type="autocomplete" autocompletesearch="urlinline history" autocompletesearchparam="enable-actions" autocompletepopup="PopupAutoCompleteRichResult" completeselectedindex="true" tabscrolling="true" showcommentcolumn="true" showimagecolumn="true" enablehistory="true" maxrows="6" newlines="stripsurroundingwhitespace" ontextentered="this.handleCommand(param);" ontextreverted="return this.handleRevert();" pageproxystate="invalid" onfocus="document.getElementById('identity- box').style.MozUserFocus= 'normal'" onblur="setTimeout(() => { document.getElementById('identity-box').style.MozUserFocus = ''; }, 0);”> . . . . . . </textbox> browser/base/content/urlbarBindings.xml
  18. 18. handleCommand 1.Canonize URI 2.Detect target in the current tab or a new tab 3.Call openUILinkIn browser/base/content/urlbarBindings.xml google mozilla https://www.google.com.tw/search?q=mozilla search engine tv http://tv.atmovies.com.tw/tv/attv.cfm?action=todaytime bookmark keyword google http://www.google.com hotkey (Ctrl/Cmd+Enter) google http://www.google.net hotkey (Shift+Enter)
  19. 19. openUILinkIn 1. Set parameters • third-party fix-up permission • post data • referrer URI 2. Call openLinkIn browser/base/content/utilityOverlay.js
  20. 20. openLinkIn 1. Set target to open URI • current tab • new tab • new window 2. Call loadURIWithFlags (tabbrowser) browser/base/content/utilityOverlay.js
  21. 21. loadURIWithFlags (tabbrowser) 1. Call loadURIWithFlags of its member browser object browser/base/content/tabbrowser.xml
  22. 22. loadURIWithFlags (browser) 1. Set “about:blank” for empty URI 2. Call loadURI • Call nsDocShell::LoadURI actually source/toolkit/content/widgets/browser.xml
  23. 23. DocShell
  24. 24. LoadURI(char16_t*, …) 1. Call LoadURIWithBase docshell/base/nsDocShell.cpp
  25. 25. LoadURIWithBase 1. Check navigatable or not 2. Call NS_NewURI to create an instance of nsIURI 3. Fix up URI if allowed 4. Call LoadURI docshell/base/nsDocShell.cpp ttp → http ps → https le → file
  26. 26. LoadURI(nsIURI*, …) 1. Check navigatable or not 2. Redirect if needed 3. Call LoadHistoryEntry to load from history if shEntry exists 4. Call InternalLoad docshell/base/nsDocShell.cpp session history
  27. 27. InternalLoad 1. Get content policy 2. Decide to load or not according to the content policy 3. Do shortcut loading if only hash tags are different 4. Call DoURILoad docshell/base/nsDocShell.cpp
  28. 28. DoURILoad 1. URI is not a source document • Call NS_NewChannelInternal to create channel 2. URI is a source document • Get “view-source” channel if protocol is “view-source” • Call NS_NewInputStreamChannelInternal to create channel for “text/html” 3. Setup some data for specific protocols 4. Call DoChannelLoad to load channel docshell/base/nsDocShell.cpp
  29. 29. Necko
  30. 30. NS_NewURI NS_NewChannelInternal (7 parameter) nsIOService::NewURI GetProtocolHandler NS_NewChannelInternal (11 parameter) NewChannelFromURI2 NewChannelFromURIWithProxyFlagsInternal GetProtocolHandler DoURILoadLoadURIWithBase Call Stack
  31. 31. GetProtocolHandler 1.Return protocol handler if the protocol handler was cached 2.For internal protocol • Cache the protocol handler and return 3.For external protocol • Get default external protocol handler for external protocol netwerk/base/nsIOService.cpp Protocols are not provided in gecko.
  32. 32. The Brief Introduction to Channels
  33. 33. Channel (nsIChannel) AsyncOpen() (Non-blocking IO) Asynchronously open this channel. Data is fed to the specified stream listener as it becomes available. Open() (Blocking IO) Synchronously open the channel.
  34. 34. Listener (nsIStreamListener) OnStartRequest() Called to signify the beginning of an asynchronous request. OnStopRequest() Called to signify the end of an asynchronous request. OnDataAvailable() Called when the next chunk of data may be read without blocking the calling thread.
  35. 35. nsDocShell::DoChannelLoad nsURILoader::OpenURI nsDocumentOpenInfo nsIChannel::AsyncOpen nsIChannel create call call nsIAsyncInputStream create nsInputStreamPump::AsyncRead call
  36. 36. nsDocShell nsIChannel nsIAsyncStream listen by nsDocmentOpenInfo listen by self (nsIChannel)
  37. 37. nsDocShell nsIChannel nsIAsyncStream OnStartRequest OnDataAvailable OnStopRequest OnStartRequest OnDataAvailable OnStopRequest Read
  38. 38. Thank you!

×