nsViewSourceChannel.cpp 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* vim:set ts=4 sw=4 sts=4 et: */
  3. /* This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. #include "nsViewSourceChannel.h"
  7. #include "nsIIOService.h"
  8. #include "nsMimeTypes.h"
  9. #include "nsNetUtil.h"
  10. #include "nsContentUtils.h"
  11. #include "nsIHttpHeaderVisitor.h"
  12. #include "nsContentSecurityManager.h"
  13. #include "nsNullPrincipal.h"
  14. #include "nsServiceManagerUtils.h"
  15. #include "nsIInputStreamChannel.h"
  16. #include "mozilla/DebugOnly.h"
  17. NS_IMPL_ADDREF(nsViewSourceChannel)
  18. NS_IMPL_RELEASE(nsViewSourceChannel)
  19. /*
  20. This QI uses NS_INTERFACE_MAP_ENTRY_CONDITIONAL to check for
  21. non-nullness of mHttpChannel, mCachingChannel, and mUploadChannel.
  22. */
  23. NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel)
  24. NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel)
  25. NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
  26. NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
  27. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
  28. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal)
  29. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel)
  30. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICacheInfoChannel, mCacheInfoChannel)
  31. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIApplicationCacheChannel, mApplicationCacheChannel)
  32. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
  33. NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFormPOSTActionChannel, mPostChannel)
  34. NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel)
  35. NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel)
  36. NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel)
  37. NS_INTERFACE_MAP_END
  38. nsresult
  39. nsViewSourceChannel::Init(nsIURI* uri)
  40. {
  41. mOriginalURI = uri;
  42. nsAutoCString path;
  43. nsresult rv = uri->GetPath(path);
  44. if (NS_FAILED(rv))
  45. return rv;
  46. nsCOMPtr<nsIIOService> pService(do_GetIOService(&rv));
  47. if (NS_FAILED(rv)) return rv;
  48. nsAutoCString scheme;
  49. rv = pService->ExtractScheme(path, scheme);
  50. if (NS_FAILED(rv))
  51. return rv;
  52. // prevent viewing source of javascript URIs (see bug 204779)
  53. if (scheme.LowerCaseEqualsLiteral("javascript")) {
  54. NS_WARNING("blocking view-source:javascript:");
  55. return NS_ERROR_INVALID_ARG;
  56. }
  57. // This function is called from within nsViewSourceHandler::NewChannel2
  58. // and sets the right loadInfo right after returning from this function.
  59. // Until then we follow the principal of least privilege and use
  60. // nullPrincipal as the loadingPrincipal and the least permissive
  61. // securityflag.
  62. nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create();
  63. rv = pService->NewChannel2(path,
  64. nullptr, // aOriginCharset
  65. nullptr, // aCharSet
  66. nullptr, // aLoadingNode
  67. nullPrincipal,
  68. nullptr, // aTriggeringPrincipal
  69. nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
  70. nsIContentPolicy::TYPE_OTHER,
  71. getter_AddRefs(mChannel));
  72. NS_ENSURE_SUCCESS(rv, rv);
  73. mIsSrcdocChannel = false;
  74. mChannel->SetOriginalURI(mOriginalURI);
  75. mHttpChannel = do_QueryInterface(mChannel);
  76. mHttpChannelInternal = do_QueryInterface(mChannel);
  77. mCachingChannel = do_QueryInterface(mChannel);
  78. mCacheInfoChannel = do_QueryInterface(mChannel);
  79. mApplicationCacheChannel = do_QueryInterface(mChannel);
  80. mUploadChannel = do_QueryInterface(mChannel);
  81. mPostChannel = do_QueryInterface(mChannel);
  82. return NS_OK;
  83. }
  84. nsresult
  85. nsViewSourceChannel::InitSrcdoc(nsIURI* aURI,
  86. nsIURI* aBaseURI,
  87. const nsAString &aSrcdoc,
  88. nsILoadInfo* aLoadInfo)
  89. {
  90. nsresult rv;
  91. nsCOMPtr<nsIURI> inStreamURI;
  92. // Need to strip view-source: from the URI. Hardcoded to
  93. // about:srcdoc as this is the only permissible URI for srcdoc
  94. // loads
  95. rv = NS_NewURI(getter_AddRefs(inStreamURI),
  96. NS_LITERAL_STRING("about:srcdoc"));
  97. NS_ENSURE_SUCCESS(rv, rv);
  98. rv = NS_NewInputStreamChannelInternal(getter_AddRefs(mChannel),
  99. inStreamURI,
  100. aSrcdoc,
  101. NS_LITERAL_CSTRING("text/html"),
  102. aLoadInfo,
  103. true);
  104. NS_ENSURE_SUCCESS(rv, rv);
  105. mOriginalURI = aURI;
  106. mIsSrcdocChannel = true;
  107. mChannel->SetOriginalURI(mOriginalURI);
  108. mHttpChannel = do_QueryInterface(mChannel);
  109. mHttpChannelInternal = do_QueryInterface(mChannel);
  110. mCachingChannel = do_QueryInterface(mChannel);
  111. mCacheInfoChannel = do_QueryInterface(mChannel);
  112. mApplicationCacheChannel = do_QueryInterface(mChannel);
  113. mUploadChannel = do_QueryInterface(mChannel);
  114. nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel);
  115. MOZ_ASSERT(isc);
  116. isc->SetBaseURI(aBaseURI);
  117. return NS_OK;
  118. }
  119. ////////////////////////////////////////////////////////////////////////////////
  120. // nsIRequest methods:
  121. NS_IMETHODIMP
  122. nsViewSourceChannel::GetName(nsACString &result)
  123. {
  124. return NS_ERROR_NOT_IMPLEMENTED;
  125. }
  126. NS_IMETHODIMP
  127. nsViewSourceChannel::GetTransferSize(uint64_t *aTransferSize)
  128. {
  129. return NS_ERROR_NOT_IMPLEMENTED;
  130. }
  131. NS_IMETHODIMP
  132. nsViewSourceChannel::GetDecodedBodySize(uint64_t *aDecodedBodySize)
  133. {
  134. return NS_ERROR_NOT_IMPLEMENTED;
  135. }
  136. NS_IMETHODIMP
  137. nsViewSourceChannel::GetEncodedBodySize(uint64_t *aEncodedBodySize)
  138. {
  139. return NS_ERROR_NOT_IMPLEMENTED;
  140. }
  141. NS_IMETHODIMP
  142. nsViewSourceChannel::IsPending(bool *result)
  143. {
  144. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  145. return mChannel->IsPending(result);
  146. }
  147. NS_IMETHODIMP
  148. nsViewSourceChannel::GetStatus(nsresult *status)
  149. {
  150. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  151. return mChannel->GetStatus(status);
  152. }
  153. NS_IMETHODIMP
  154. nsViewSourceChannel::Cancel(nsresult status)
  155. {
  156. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  157. return mChannel->Cancel(status);
  158. }
  159. NS_IMETHODIMP
  160. nsViewSourceChannel::Suspend(void)
  161. {
  162. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  163. return mChannel->Suspend();
  164. }
  165. NS_IMETHODIMP
  166. nsViewSourceChannel::Resume(void)
  167. {
  168. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  169. return mChannel->Resume();
  170. }
  171. ////////////////////////////////////////////////////////////////////////////////
  172. // nsIChannel methods:
  173. NS_IMETHODIMP
  174. nsViewSourceChannel::GetOriginalURI(nsIURI* *aURI)
  175. {
  176. NS_ASSERTION(aURI, "Null out param!");
  177. *aURI = mOriginalURI;
  178. NS_ADDREF(*aURI);
  179. return NS_OK;
  180. }
  181. NS_IMETHODIMP
  182. nsViewSourceChannel::SetOriginalURI(nsIURI* aURI)
  183. {
  184. NS_ENSURE_ARG_POINTER(aURI);
  185. mOriginalURI = aURI;
  186. return NS_OK;
  187. }
  188. NS_IMETHODIMP
  189. nsViewSourceChannel::GetURI(nsIURI* *aURI)
  190. {
  191. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  192. nsCOMPtr<nsIURI> uri;
  193. nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
  194. if (NS_FAILED(rv))
  195. return rv;
  196. // protect ourselves against broken channel implementations
  197. if (!uri) {
  198. NS_ERROR("inner channel returned NS_OK and a null URI");
  199. return NS_ERROR_UNEXPECTED;
  200. }
  201. nsAutoCString spec;
  202. rv = uri->GetSpec(spec);
  203. if (NS_FAILED(rv)) {
  204. return rv;
  205. }
  206. /* XXX Gross hack -- NS_NewURI goes into an infinite loop on
  207. non-flat specs. See bug 136980 */
  208. return NS_NewURI(aURI, nsAutoCString(NS_LITERAL_CSTRING("view-source:")+spec), nullptr);
  209. }
  210. NS_IMETHODIMP
  211. nsViewSourceChannel::Open(nsIInputStream **_retval)
  212. {
  213. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  214. nsresult rv = NS_MaybeOpenChannelUsingOpen2(mChannel, _retval);
  215. if (NS_SUCCEEDED(rv)) {
  216. mOpened = true;
  217. }
  218. return rv;
  219. }
  220. NS_IMETHODIMP
  221. nsViewSourceChannel::Open2(nsIInputStream** aStream)
  222. {
  223. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  224. nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
  225. if(!loadInfo) {
  226. MOZ_ASSERT(loadInfo, "can not enforce security without loadInfo");
  227. return NS_ERROR_UNEXPECTED;
  228. }
  229. // setting the flag on the loadInfo indicates that the underlying
  230. // channel will be openend using Open2() and hence performs
  231. // the necessary security checks.
  232. loadInfo->SetEnforceSecurity(true);
  233. return Open(aStream);
  234. }
  235. NS_IMETHODIMP
  236. nsViewSourceChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
  237. {
  238. #ifdef DEBUG
  239. {
  240. nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
  241. MOZ_ASSERT(!loadInfo || loadInfo->GetSecurityMode() == 0 ||
  242. loadInfo->GetEnforceSecurity(),
  243. "security flags in loadInfo but asyncOpen2() not called");
  244. }
  245. #endif
  246. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  247. mListener = aListener;
  248. /*
  249. * We want to add ourselves to the loadgroup before opening
  250. * mChannel, since we want to make sure we're in the loadgroup
  251. * when mChannel finishes and fires OnStopRequest()
  252. */
  253. nsCOMPtr<nsILoadGroup> loadGroup;
  254. mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
  255. if (loadGroup)
  256. loadGroup->AddRequest(static_cast<nsIViewSourceChannel*>
  257. (this), nullptr);
  258. nsresult rv = NS_OK;
  259. nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
  260. if (loadInfo && loadInfo->GetEnforceSecurity()) {
  261. rv = mChannel->AsyncOpen2(this);
  262. }
  263. else {
  264. rv = mChannel->AsyncOpen(this, ctxt);
  265. }
  266. if (NS_FAILED(rv) && loadGroup)
  267. loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>
  268. (this),
  269. nullptr, rv);
  270. if (NS_SUCCEEDED(rv)) {
  271. mOpened = true;
  272. }
  273. return rv;
  274. }
  275. NS_IMETHODIMP
  276. nsViewSourceChannel::AsyncOpen2(nsIStreamListener *aListener)
  277. {
  278. nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
  279. if(!loadInfo) {
  280. MOZ_ASSERT(loadInfo, "can not enforce security without loadInfo");
  281. return NS_ERROR_UNEXPECTED;
  282. }
  283. // setting the flag on the loadInfo indicates that the underlying
  284. // channel will be openend using AsyncOpen2() and hence performs
  285. // the necessary security checks.
  286. loadInfo->SetEnforceSecurity(true);
  287. return AsyncOpen(aListener, nullptr);
  288. }
  289. /*
  290. * Both the view source channel and mChannel are added to the
  291. * loadgroup. There should never be more than one request in the
  292. * loadgroup that has LOAD_DOCUMENT_URI set. The one that has this
  293. * flag set is the request whose URI is used to refetch the document,
  294. * so it better be the viewsource channel.
  295. *
  296. * Therefore, we need to make sure that
  297. * 1) The load flags on mChannel _never_ include LOAD_DOCUMENT_URI
  298. * 2) The load flags on |this| include LOAD_DOCUMENT_URI when it was
  299. * set via SetLoadFlags (mIsDocument keeps track of this flag).
  300. */
  301. NS_IMETHODIMP
  302. nsViewSourceChannel::GetLoadFlags(uint32_t *aLoadFlags)
  303. {
  304. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  305. nsresult rv = mChannel->GetLoadFlags(aLoadFlags);
  306. if (NS_FAILED(rv))
  307. return rv;
  308. // This should actually be just LOAD_DOCUMENT_URI but the win32 compiler
  309. // fails to deal due to amiguous inheritance. nsIChannel::LOAD_DOCUMENT_URI
  310. // also fails; the Win32 compiler thinks that's supposed to be a method.
  311. if (mIsDocument)
  312. *aLoadFlags |= ::nsIChannel::LOAD_DOCUMENT_URI;
  313. return rv;
  314. }
  315. NS_IMETHODIMP
  316. nsViewSourceChannel::SetLoadFlags(uint32_t aLoadFlags)
  317. {
  318. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  319. // "View source" always wants the currently cached content.
  320. // We also want to have _this_ channel, not mChannel to be the
  321. // 'document' channel in the loadgroup.
  322. // These should actually be just LOAD_FROM_CACHE and LOAD_DOCUMENT_URI but
  323. // the win32 compiler fails to deal due to amiguous inheritance.
  324. // nsIChannel::LOAD_DOCUMENT_URI/nsIRequest::LOAD_FROM_CACHE also fails; the
  325. // Win32 compiler thinks that's supposed to be a method.
  326. mIsDocument = (aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI) ? true : false;
  327. nsresult rv = mChannel->SetLoadFlags((aLoadFlags |
  328. ::nsIRequest::LOAD_FROM_CACHE) &
  329. ~::nsIChannel::LOAD_DOCUMENT_URI);
  330. if (NS_WARN_IF(NS_FAILED(rv))) {
  331. return rv;
  332. }
  333. if (mHttpChannel) {
  334. rv = mHttpChannel->SetIsMainDocumentChannel(aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI);
  335. MOZ_ASSERT(NS_SUCCEEDED(rv));
  336. }
  337. return NS_OK;
  338. }
  339. NS_IMETHODIMP
  340. nsViewSourceChannel::GetContentType(nsACString &aContentType)
  341. {
  342. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  343. aContentType.Truncate();
  344. if (mContentType.IsEmpty())
  345. {
  346. // Get the current content type
  347. nsresult rv;
  348. nsAutoCString contentType;
  349. rv = mChannel->GetContentType(contentType);
  350. if (NS_FAILED(rv)) return rv;
  351. // If we don't know our type, just say so. The unknown
  352. // content decoder will then kick in automatically, and it
  353. // will call our SetOriginalContentType method instead of our
  354. // SetContentType method to set the type it determines.
  355. if (!contentType.Equals(UNKNOWN_CONTENT_TYPE)) {
  356. contentType = VIEWSOURCE_CONTENT_TYPE;
  357. }
  358. mContentType = contentType;
  359. }
  360. aContentType = mContentType;
  361. return NS_OK;
  362. }
  363. NS_IMETHODIMP
  364. nsViewSourceChannel::SetContentType(const nsACString &aContentType)
  365. {
  366. // Our GetContentType() currently returns VIEWSOURCE_CONTENT_TYPE
  367. //
  368. // However, during the parsing phase the parser calls our
  369. // channel's GetContentType(). Returning the string above trips up
  370. // the parser. In order to avoid messy changes and not to have the
  371. // parser depend on nsIViewSourceChannel Vidur proposed the
  372. // following solution:
  373. //
  374. // The ViewSourceChannel initially returns a content type of
  375. // VIEWSOURCE_CONTENT_TYPE. Based on this type decisions to
  376. // create a viewer for doing a view source are made. After the
  377. // viewer is created, nsLayoutDLF::CreateInstance() calls this
  378. // SetContentType() with the original content type. When it's
  379. // time for the parser to find out the content type it will call
  380. // our channel's GetContentType() and it will get the original
  381. // content type, such as, text/html and everything is kosher from
  382. // then on.
  383. if (!mOpened) {
  384. // We do not take hints
  385. return NS_ERROR_NOT_AVAILABLE;
  386. }
  387. mContentType = aContentType;
  388. return NS_OK;
  389. }
  390. NS_IMETHODIMP
  391. nsViewSourceChannel::GetContentCharset(nsACString &aContentCharset)
  392. {
  393. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  394. return mChannel->GetContentCharset(aContentCharset);
  395. }
  396. NS_IMETHODIMP
  397. nsViewSourceChannel::SetContentCharset(const nsACString &aContentCharset)
  398. {
  399. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  400. return mChannel->SetContentCharset(aContentCharset);
  401. }
  402. // We don't forward these methods becacuse content-disposition isn't whitelisted
  403. // (see GetResponseHeader/VisitResponseHeaders).
  404. NS_IMETHODIMP
  405. nsViewSourceChannel::GetContentDisposition(uint32_t *aContentDisposition)
  406. {
  407. return NS_ERROR_NOT_AVAILABLE;
  408. }
  409. NS_IMETHODIMP
  410. nsViewSourceChannel::SetContentDisposition(uint32_t aContentDisposition)
  411. {
  412. return NS_ERROR_NOT_AVAILABLE;
  413. }
  414. NS_IMETHODIMP
  415. nsViewSourceChannel::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
  416. {
  417. return NS_ERROR_NOT_AVAILABLE;
  418. }
  419. NS_IMETHODIMP
  420. nsViewSourceChannel::SetContentDispositionFilename(const nsAString &aContentDispositionFilename)
  421. {
  422. return NS_ERROR_NOT_AVAILABLE;
  423. }
  424. NS_IMETHODIMP
  425. nsViewSourceChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
  426. {
  427. return NS_ERROR_NOT_AVAILABLE;
  428. }
  429. NS_IMETHODIMP
  430. nsViewSourceChannel::GetContentLength(int64_t *aContentLength)
  431. {
  432. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  433. return mChannel->GetContentLength(aContentLength);
  434. }
  435. NS_IMETHODIMP
  436. nsViewSourceChannel::SetContentLength(int64_t aContentLength)
  437. {
  438. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  439. return mChannel->SetContentLength(aContentLength);
  440. }
  441. NS_IMETHODIMP
  442. nsViewSourceChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
  443. {
  444. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  445. return mChannel->GetLoadGroup(aLoadGroup);
  446. }
  447. NS_IMETHODIMP
  448. nsViewSourceChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
  449. {
  450. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  451. return mChannel->SetLoadGroup(aLoadGroup);
  452. }
  453. NS_IMETHODIMP
  454. nsViewSourceChannel::GetOwner(nsISupports* *aOwner)
  455. {
  456. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  457. return mChannel->GetOwner(aOwner);
  458. }
  459. NS_IMETHODIMP
  460. nsViewSourceChannel::SetOwner(nsISupports* aOwner)
  461. {
  462. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  463. return mChannel->SetOwner(aOwner);
  464. }
  465. NS_IMETHODIMP
  466. nsViewSourceChannel::GetLoadInfo(nsILoadInfo* *aLoadInfo)
  467. {
  468. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  469. return mChannel->GetLoadInfo(aLoadInfo);
  470. }
  471. NS_IMETHODIMP
  472. nsViewSourceChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
  473. {
  474. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  475. return mChannel->SetLoadInfo(aLoadInfo);
  476. }
  477. NS_IMETHODIMP
  478. nsViewSourceChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
  479. {
  480. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  481. return mChannel->GetNotificationCallbacks(aNotificationCallbacks);
  482. }
  483. NS_IMETHODIMP
  484. nsViewSourceChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
  485. {
  486. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  487. return mChannel->SetNotificationCallbacks(aNotificationCallbacks);
  488. }
  489. NS_IMETHODIMP
  490. nsViewSourceChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
  491. {
  492. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  493. return mChannel->GetSecurityInfo(aSecurityInfo);
  494. }
  495. // nsIViewSourceChannel methods
  496. NS_IMETHODIMP
  497. nsViewSourceChannel::GetOriginalContentType(nsACString &aContentType)
  498. {
  499. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  500. return mChannel->GetContentType(aContentType);
  501. }
  502. NS_IMETHODIMP
  503. nsViewSourceChannel::SetOriginalContentType(const nsACString &aContentType)
  504. {
  505. NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
  506. // clear our cached content-type value
  507. mContentType.Truncate();
  508. return mChannel->SetContentType(aContentType);
  509. }
  510. NS_IMETHODIMP
  511. nsViewSourceChannel::GetIsSrcdocChannel(bool* aIsSrcdocChannel)
  512. {
  513. *aIsSrcdocChannel = mIsSrcdocChannel;
  514. return NS_OK;
  515. }
  516. NS_IMETHODIMP
  517. nsViewSourceChannel::GetBaseURI(nsIURI** aBaseURI)
  518. {
  519. if (mIsSrcdocChannel) {
  520. nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel);
  521. if (isc) {
  522. return isc->GetBaseURI(aBaseURI);
  523. }
  524. }
  525. *aBaseURI = mBaseURI;
  526. NS_IF_ADDREF(*aBaseURI);
  527. return NS_OK;
  528. }
  529. NS_IMETHODIMP
  530. nsViewSourceChannel::SetBaseURI(nsIURI* aBaseURI)
  531. {
  532. mBaseURI = aBaseURI;
  533. return NS_OK;
  534. }
  535. NS_IMETHODIMP
  536. nsViewSourceChannel::GetProtocolVersion(nsACString& aProtocolVersion)
  537. {
  538. return NS_ERROR_NOT_IMPLEMENTED;
  539. }
  540. // nsIRequestObserver methods
  541. NS_IMETHODIMP
  542. nsViewSourceChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
  543. {
  544. NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
  545. // The channel may have gotten redirected... Time to update our info
  546. mChannel = do_QueryInterface(aRequest);
  547. mHttpChannel = do_QueryInterface(aRequest);
  548. mCachingChannel = do_QueryInterface(aRequest);
  549. mCacheInfoChannel = do_QueryInterface(mChannel);
  550. mUploadChannel = do_QueryInterface(aRequest);
  551. return mListener->OnStartRequest(static_cast<nsIViewSourceChannel*>
  552. (this),
  553. aContext);
  554. }
  555. NS_IMETHODIMP
  556. nsViewSourceChannel::OnStopRequest(nsIRequest *aRequest, nsISupports* aContext,
  557. nsresult aStatus)
  558. {
  559. NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
  560. if (mChannel)
  561. {
  562. nsCOMPtr<nsILoadGroup> loadGroup;
  563. mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
  564. if (loadGroup)
  565. {
  566. loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>
  567. (this),
  568. nullptr, aStatus);
  569. }
  570. }
  571. return mListener->OnStopRequest(static_cast<nsIViewSourceChannel*>
  572. (this),
  573. aContext, aStatus);
  574. }
  575. // nsIStreamListener methods
  576. NS_IMETHODIMP
  577. nsViewSourceChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports* aContext,
  578. nsIInputStream *aInputStream,
  579. uint64_t aSourceOffset,
  580. uint32_t aLength)
  581. {
  582. NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
  583. return mListener->OnDataAvailable(static_cast<nsIViewSourceChannel*>
  584. (this),
  585. aContext, aInputStream,
  586. aSourceOffset, aLength);
  587. }
  588. // nsIHttpChannel methods
  589. // We want to forward most of nsIHttpChannel over to mHttpChannel, but we want
  590. // to override GetRequestHeader and VisitHeaders. The reason is that we don't
  591. // want various headers like Link: and Refresh: applying to view-source.
  592. NS_IMETHODIMP
  593. nsViewSourceChannel::GetChannelId(nsACString& aChannelId)
  594. {
  595. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  596. mHttpChannel->GetChannelId(aChannelId);
  597. }
  598. NS_IMETHODIMP
  599. nsViewSourceChannel::SetChannelId(const nsACString& aChannelId)
  600. {
  601. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  602. mHttpChannel->SetChannelId(aChannelId);
  603. }
  604. NS_IMETHODIMP
  605. nsViewSourceChannel::GetTopLevelContentWindowId(uint64_t *aWindowId)
  606. {
  607. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  608. mHttpChannel->GetTopLevelContentWindowId(aWindowId);
  609. }
  610. NS_IMETHODIMP
  611. nsViewSourceChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
  612. {
  613. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  614. mHttpChannel->SetTopLevelContentWindowId(aWindowId);
  615. }
  616. NS_IMETHODIMP
  617. nsViewSourceChannel::GetRequestMethod(nsACString & aRequestMethod)
  618. {
  619. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  620. mHttpChannel->GetRequestMethod(aRequestMethod);
  621. }
  622. NS_IMETHODIMP
  623. nsViewSourceChannel::SetRequestMethod(const nsACString & aRequestMethod)
  624. {
  625. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  626. mHttpChannel->SetRequestMethod(aRequestMethod);
  627. }
  628. NS_IMETHODIMP
  629. nsViewSourceChannel::GetReferrer(nsIURI * *aReferrer)
  630. {
  631. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  632. mHttpChannel->GetReferrer(aReferrer);
  633. }
  634. NS_IMETHODIMP
  635. nsViewSourceChannel::SetReferrer(nsIURI * aReferrer)
  636. {
  637. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  638. mHttpChannel->SetReferrer(aReferrer);
  639. }
  640. NS_IMETHODIMP
  641. nsViewSourceChannel::GetReferrerPolicy(uint32_t *aReferrerPolicy)
  642. {
  643. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  644. mHttpChannel->GetReferrerPolicy(aReferrerPolicy);
  645. }
  646. NS_IMETHODIMP
  647. nsViewSourceChannel::SetReferrerWithPolicy(nsIURI * aReferrer,
  648. uint32_t aReferrerPolicy)
  649. {
  650. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  651. mHttpChannel->SetReferrerWithPolicy(aReferrer, aReferrerPolicy);
  652. }
  653. NS_IMETHODIMP
  654. nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader,
  655. nsACString & aValue)
  656. {
  657. aValue.Truncate();
  658. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  659. mHttpChannel->GetRequestHeader(aHeader, aValue);
  660. }
  661. NS_IMETHODIMP
  662. nsViewSourceChannel::SetRequestHeader(const nsACString & aHeader,
  663. const nsACString & aValue,
  664. bool aMerge)
  665. {
  666. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  667. mHttpChannel->SetRequestHeader(aHeader, aValue, aMerge);
  668. }
  669. NS_IMETHODIMP
  670. nsViewSourceChannel::SetEmptyRequestHeader(const nsACString & aHeader)
  671. {
  672. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  673. mHttpChannel->SetEmptyRequestHeader(aHeader);
  674. }
  675. NS_IMETHODIMP
  676. nsViewSourceChannel::VisitRequestHeaders(nsIHttpHeaderVisitor *aVisitor)
  677. {
  678. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  679. mHttpChannel->VisitRequestHeaders(aVisitor);
  680. }
  681. NS_IMETHODIMP
  682. nsViewSourceChannel::VisitNonDefaultRequestHeaders(nsIHttpHeaderVisitor *aVisitor)
  683. {
  684. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  685. mHttpChannel->VisitNonDefaultRequestHeaders(aVisitor);
  686. }
  687. NS_IMETHODIMP
  688. nsViewSourceChannel::GetAllowPipelining(bool *aAllowPipelining)
  689. {
  690. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  691. mHttpChannel->GetAllowPipelining(aAllowPipelining);
  692. }
  693. NS_IMETHODIMP
  694. nsViewSourceChannel::SetAllowPipelining(bool aAllowPipelining)
  695. {
  696. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  697. mHttpChannel->SetAllowPipelining(aAllowPipelining);
  698. }
  699. NS_IMETHODIMP
  700. nsViewSourceChannel::GetAllowSTS(bool *aAllowSTS)
  701. {
  702. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  703. mHttpChannel->GetAllowSTS(aAllowSTS);
  704. }
  705. NS_IMETHODIMP
  706. nsViewSourceChannel::SetAllowSTS(bool aAllowSTS)
  707. {
  708. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  709. mHttpChannel->SetAllowSTS(aAllowSTS);
  710. }
  711. NS_IMETHODIMP
  712. nsViewSourceChannel::GetRedirectionLimit(uint32_t *aRedirectionLimit)
  713. {
  714. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  715. mHttpChannel->GetRedirectionLimit(aRedirectionLimit);
  716. }
  717. NS_IMETHODIMP
  718. nsViewSourceChannel::SetRedirectionLimit(uint32_t aRedirectionLimit)
  719. {
  720. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  721. mHttpChannel->SetRedirectionLimit(aRedirectionLimit);
  722. }
  723. NS_IMETHODIMP
  724. nsViewSourceChannel::GetResponseStatus(uint32_t *aResponseStatus)
  725. {
  726. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  727. mHttpChannel->GetResponseStatus(aResponseStatus);
  728. }
  729. NS_IMETHODIMP
  730. nsViewSourceChannel::GetResponseStatusText(nsACString & aResponseStatusText)
  731. {
  732. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  733. mHttpChannel->GetResponseStatusText(aResponseStatusText);
  734. }
  735. NS_IMETHODIMP
  736. nsViewSourceChannel::GetRequestSucceeded(bool *aRequestSucceeded)
  737. {
  738. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  739. mHttpChannel->GetRequestSucceeded(aRequestSucceeded);
  740. }
  741. NS_IMETHODIMP
  742. nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
  743. nsACString & aValue)
  744. {
  745. aValue.Truncate();
  746. if (!mHttpChannel)
  747. return NS_ERROR_NULL_POINTER;
  748. if (!aHeader.Equals(NS_LITERAL_CSTRING("Content-Type"),
  749. nsCaseInsensitiveCStringComparator()) &&
  750. !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy"),
  751. nsCaseInsensitiveCStringComparator()) &&
  752. !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy-Report-Only"),
  753. nsCaseInsensitiveCStringComparator()) &&
  754. !aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"),
  755. nsCaseInsensitiveCStringComparator())) {
  756. return NS_OK;
  757. }
  758. return mHttpChannel->GetResponseHeader(aHeader, aValue);
  759. }
  760. NS_IMETHODIMP
  761. nsViewSourceChannel::SetResponseHeader(const nsACString & header,
  762. const nsACString & value, bool merge)
  763. {
  764. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  765. mHttpChannel->SetResponseHeader(header, value, merge);
  766. }
  767. NS_IMETHODIMP
  768. nsViewSourceChannel::VisitResponseHeaders(nsIHttpHeaderVisitor *aVisitor)
  769. {
  770. if (!mHttpChannel)
  771. return NS_ERROR_NULL_POINTER;
  772. NS_NAMED_LITERAL_CSTRING(contentTypeStr, "Content-Type");
  773. nsAutoCString contentType;
  774. nsresult rv =
  775. mHttpChannel->GetResponseHeader(contentTypeStr, contentType);
  776. if (NS_SUCCEEDED(rv))
  777. aVisitor->VisitHeader(contentTypeStr, contentType);
  778. return NS_OK;
  779. }
  780. NS_IMETHODIMP
  781. nsViewSourceChannel::GetOriginalResponseHeader(const nsACString & aHeader,
  782. nsIHttpHeaderVisitor *aVisitor)
  783. {
  784. nsAutoCString value;
  785. nsresult rv = GetResponseHeader(aHeader, value);
  786. if (NS_FAILED(rv)) {
  787. return rv;
  788. }
  789. aVisitor->VisitHeader(aHeader, value);
  790. return NS_OK;
  791. }
  792. NS_IMETHODIMP
  793. nsViewSourceChannel::VisitOriginalResponseHeaders(nsIHttpHeaderVisitor *aVisitor)
  794. {
  795. return VisitResponseHeaders(aVisitor);
  796. }
  797. NS_IMETHODIMP
  798. nsViewSourceChannel::IsNoStoreResponse(bool *_retval)
  799. {
  800. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  801. mHttpChannel->IsNoStoreResponse(_retval);
  802. }
  803. NS_IMETHODIMP
  804. nsViewSourceChannel::IsNoCacheResponse(bool *_retval)
  805. {
  806. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  807. mHttpChannel->IsNoCacheResponse(_retval);
  808. }
  809. NS_IMETHODIMP
  810. nsViewSourceChannel::IsPrivateResponse(bool *_retval)
  811. {
  812. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  813. mHttpChannel->IsPrivateResponse(_retval);
  814. }
  815. NS_IMETHODIMP
  816. nsViewSourceChannel::RedirectTo(nsIURI *uri)
  817. {
  818. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  819. mHttpChannel->RedirectTo(uri);
  820. }
  821. NS_IMETHODIMP
  822. nsViewSourceChannel::GetRequestContextID(nsID *_retval)
  823. {
  824. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  825. mHttpChannel->GetRequestContextID(_retval);
  826. }
  827. NS_IMETHODIMP
  828. nsViewSourceChannel::SetRequestContextID(const nsID rcid)
  829. {
  830. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  831. mHttpChannel->SetRequestContextID(rcid);
  832. }
  833. NS_IMETHODIMP
  834. nsViewSourceChannel::GetIsMainDocumentChannel(bool* aValue)
  835. {
  836. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  837. mHttpChannel->GetIsMainDocumentChannel(aValue);
  838. }
  839. NS_IMETHODIMP
  840. nsViewSourceChannel::SetIsMainDocumentChannel(bool aValue)
  841. {
  842. return !mHttpChannel ? NS_ERROR_NULL_POINTER :
  843. mHttpChannel->SetIsMainDocumentChannel(aValue);
  844. }
  845. // Have to manually forward since these are [notxpcom]
  846. void
  847. nsViewSourceChannel::SetCorsPreflightParameters(const nsTArray<nsCString>& aUnsafeHeaders)
  848. {
  849. mHttpChannelInternal->SetCorsPreflightParameters(aUnsafeHeaders);
  850. }
  851. mozilla::net::nsHttpChannel *
  852. nsViewSourceChannel::QueryHttpChannelImpl()
  853. {
  854. return mHttpChannelInternal->QueryHttpChannelImpl();
  855. }