nsAHttpTransaction.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #ifndef nsAHttpTransaction_h__
  5. #define nsAHttpTransaction_h__
  6. #include "nsISupports.h"
  7. #include "nsTArray.h"
  8. #include "nsWeakReference.h"
  9. class nsIInterfaceRequestor;
  10. class nsITransport;
  11. class nsIRequestContext;
  12. namespace mozilla { namespace net {
  13. class nsAHttpConnection;
  14. class nsAHttpSegmentReader;
  15. class nsAHttpSegmentWriter;
  16. class nsHttpTransaction;
  17. class nsHttpPipeline;
  18. class nsHttpRequestHead;
  19. class nsHttpConnectionInfo;
  20. class NullHttpTransaction;
  21. class SpdyConnectTransaction;
  22. //----------------------------------------------------------------------------
  23. // Abstract base class for a HTTP transaction:
  24. //
  25. // A transaction is a "sink" for the response data. The connection pushes
  26. // data to the transaction by writing to it. The transaction supports
  27. // WriteSegments and may refuse to accept data if its buffers are full (its
  28. // write function returns NS_BASE_STREAM_WOULD_BLOCK in this case).
  29. //----------------------------------------------------------------------------
  30. // 2af6d634-13e3-494c-8903-c9dce5c22fc0
  31. #define NS_AHTTPTRANSACTION_IID \
  32. { 0x2af6d634, 0x13e3, 0x494c, {0x89, 0x03, 0xc9, 0xdc, 0xe5, 0xc2, 0x2f, 0xc0 }}
  33. class nsAHttpTransaction : public nsSupportsWeakReference
  34. {
  35. public:
  36. NS_DECLARE_STATIC_IID_ACCESSOR(NS_AHTTPTRANSACTION_IID)
  37. // called by the connection when it takes ownership of the transaction.
  38. virtual void SetConnection(nsAHttpConnection *) = 0;
  39. // used to obtain the connection associated with this transaction
  40. virtual nsAHttpConnection *Connection() = 0;
  41. // called by the connection to get security callbacks to set on the
  42. // socket transport.
  43. virtual void GetSecurityCallbacks(nsIInterfaceRequestor **) = 0;
  44. // called to report socket status (see nsITransportEventSink)
  45. virtual void OnTransportStatus(nsITransport* transport,
  46. nsresult status, int64_t progress) = 0;
  47. // called to check the transaction status.
  48. virtual bool IsDone() = 0;
  49. virtual nsresult Status() = 0;
  50. virtual uint32_t Caps() = 0;
  51. // called to notify that a requested DNS cache entry was refreshed.
  52. virtual void SetDNSWasRefreshed() = 0;
  53. // called to find out how much request data is available for writing.
  54. virtual uint64_t Available() = 0;
  55. // called to read request data from the transaction.
  56. virtual nsresult ReadSegments(nsAHttpSegmentReader *reader,
  57. uint32_t count, uint32_t *countRead) = 0;
  58. // called to write response data to the transaction.
  59. virtual nsresult WriteSegments(nsAHttpSegmentWriter *writer,
  60. uint32_t count, uint32_t *countWritten) = 0;
  61. // These versions of the functions allow the overloader to specify whether or
  62. // not it is safe to call *Segments() in a loop while they return OK.
  63. // The callee should turn again to false if it is not, otherwise leave untouched
  64. virtual nsresult ReadSegmentsAgain(nsAHttpSegmentReader *reader,
  65. uint32_t count, uint32_t *countRead, bool *again)
  66. {
  67. return ReadSegments(reader, count, countRead);
  68. }
  69. virtual nsresult WriteSegmentsAgain(nsAHttpSegmentWriter *writer,
  70. uint32_t count, uint32_t *countWritten, bool *again)
  71. {
  72. return WriteSegments(writer, count, countWritten);
  73. }
  74. // called to close the transaction
  75. virtual void Close(nsresult reason) = 0;
  76. // called to indicate a failure with proxy CONNECT
  77. virtual void SetProxyConnectFailed() = 0;
  78. // called to retrieve the request headers of the transaction
  79. virtual nsHttpRequestHead *RequestHead() = 0;
  80. // determine the number of real http/1.x transactions on this
  81. // abstract object. Pipelines may have multiple, SPDY has 0,
  82. // normal http transactions have 1.
  83. virtual uint32_t Http1xTransactionCount() = 0;
  84. // called to remove the unused sub transactions from an object that can
  85. // handle multiple transactions simultaneously (i.e. pipelines or spdy).
  86. //
  87. // Returns NS_ERROR_NOT_IMPLEMENTED if the object does not implement
  88. // sub-transactions.
  89. //
  90. // Returns NS_ERROR_ALREADY_OPENED if the subtransactions have been
  91. // at least partially written and cannot be moved.
  92. //
  93. virtual nsresult TakeSubTransactions(
  94. nsTArray<RefPtr<nsAHttpTransaction> > &outTransactions) = 0;
  95. // called to add a sub-transaction in the case of pipelined transactions
  96. // classes that do not implement sub transactions
  97. // return NS_ERROR_NOT_IMPLEMENTED
  98. virtual nsresult AddTransaction(nsAHttpTransaction *transaction) = 0;
  99. // The total length of the outstanding pipeline comprised of transacations
  100. // and sub-transactions.
  101. virtual uint32_t PipelineDepth() = 0;
  102. // Used to inform the connection that it is being used in a pipelined
  103. // context. That may influence the handling of some errors.
  104. // The value is the pipeline position (> 1).
  105. virtual nsresult SetPipelinePosition(int32_t) = 0;
  106. virtual int32_t PipelinePosition() = 0;
  107. // Occasionally the abstract interface has to give way to base implementations
  108. // to respect differences between spdy, pipelines, etc..
  109. // These Query* (and IsNullTransaction()) functions provide a way to do
  110. // that without using xpcom or rtti. Any calling code that can't deal with
  111. // a null response from one of them probably shouldn't be using nsAHttpTransaction
  112. // If we used rtti this would be the result of doing
  113. // dynamic_cast<nsHttpPipeline *>(this).. i.e. it can be nullptr for
  114. // non pipeline implementations of nsAHttpTransaction
  115. virtual nsHttpPipeline *QueryPipeline() { return nullptr; }
  116. // equivalent to !!dynamic_cast<NullHttpTransaction *>(this)
  117. // A null transaction is expected to return BASE_STREAM_CLOSED on all of
  118. // its IO functions all the time.
  119. virtual bool IsNullTransaction() { return false; }
  120. virtual NullHttpTransaction *QueryNullTransaction() { return nullptr; }
  121. // If we used rtti this would be the result of doing
  122. // dynamic_cast<nsHttpTransaction *>(this).. i.e. it can be nullptr for
  123. // non nsHttpTransaction implementations of nsAHttpTransaction
  124. virtual nsHttpTransaction *QueryHttpTransaction() { return nullptr; }
  125. // If we used rtti this would be the result of doing
  126. // dynamic_cast<SpdyConnectTransaction *>(this).. i.e. it can be nullptr for
  127. // other types
  128. virtual SpdyConnectTransaction *QuerySpdyConnectTransaction() { return nullptr; }
  129. // return the request context associated with the transaction
  130. virtual nsIRequestContext *RequestContext() { return nullptr; }
  131. // return the connection information associated with the transaction
  132. virtual nsHttpConnectionInfo *ConnectionInfo() = 0;
  133. // The base definition of these is done in nsHttpTransaction.cpp
  134. virtual bool ResponseTimeoutEnabled() const;
  135. virtual PRIntervalTime ResponseTimeout();
  136. // Every transaction is classified into one of the types below. When using
  137. // HTTP pipelines, only transactions with the same type appear on the same
  138. // pipeline.
  139. enum Classifier {
  140. // Transactions that expect a short 304 (no-content) response
  141. CLASS_REVALIDATION,
  142. // Transactions for content expected to be CSS or JS
  143. CLASS_SCRIPT,
  144. // Transactions for content expected to be an image
  145. CLASS_IMAGE,
  146. // Transactions that cannot involve a pipeline
  147. CLASS_SOLO,
  148. // Transactions that do not fit any of the other categories. HTML
  149. // is normally GENERAL.
  150. CLASS_GENERAL,
  151. CLASS_MAX
  152. };
  153. // conceptually the security info is part of the connection, but sometimes
  154. // in the case of TLS tunneled within TLS the transaction might present
  155. // a more specific security info that cannot be represented as a layer in
  156. // the connection due to multiplexing. This interface represents such an
  157. // overload. If it returns NS_FAILURE the connection should be considered
  158. // authoritative.
  159. virtual nsresult GetTransactionSecurityInfo(nsISupports **)
  160. {
  161. return NS_ERROR_NOT_IMPLEMENTED;
  162. }
  163. virtual void DisableSpdy() { }
  164. virtual void ReuseConnectionOnRestartOK(bool) { }
  165. // Returns true if early-data is possible.
  166. virtual bool Do0RTT() {
  167. return false;
  168. }
  169. // This function will be called when a tls handshake has been finished and
  170. // we know whether early-data that was sent has been accepted or not, e.g.
  171. // do we need to restart a transaction. This will be called only if Do0RTT
  172. // returns true.
  173. // If aRestart parameter is true we need to restart the transaction,
  174. // otherwise the erly-data has been accepted and we can continue the
  175. // transaction.
  176. // If aAlpnChanged is true (and we were assuming http/2), we'll need to take
  177. // the transactions out of the session, rewind them all, and start them back
  178. // over as http/1 transactions
  179. // The function will return success or failure of the transaction restart.
  180. virtual nsresult Finish0RTT(bool aRestart, bool aAlpnChanged) {
  181. return NS_ERROR_NOT_IMPLEMENTED;
  182. }
  183. };
  184. NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpTransaction, NS_AHTTPTRANSACTION_IID)
  185. #define NS_DECL_NSAHTTPTRANSACTION \
  186. void SetConnection(nsAHttpConnection *) override; \
  187. nsAHttpConnection *Connection() override; \
  188. void GetSecurityCallbacks(nsIInterfaceRequestor **) override; \
  189. void OnTransportStatus(nsITransport* transport, \
  190. nsresult status, int64_t progress) override; \
  191. bool IsDone() override; \
  192. nsresult Status() override; \
  193. uint32_t Caps() override; \
  194. void SetDNSWasRefreshed() override; \
  195. uint64_t Available() override; \
  196. virtual nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *) override; \
  197. virtual nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *) override; \
  198. virtual void Close(nsresult reason) override; \
  199. nsHttpConnectionInfo *ConnectionInfo() override; \
  200. void SetProxyConnectFailed() override; \
  201. virtual nsHttpRequestHead *RequestHead() override; \
  202. uint32_t Http1xTransactionCount() override; \
  203. nsresult TakeSubTransactions(nsTArray<RefPtr<nsAHttpTransaction> > &outTransactions) override; \
  204. nsresult AddTransaction(nsAHttpTransaction *) override; \
  205. uint32_t PipelineDepth() override; \
  206. nsresult SetPipelinePosition(int32_t) override; \
  207. int32_t PipelinePosition() override;
  208. //-----------------------------------------------------------------------------
  209. // nsAHttpSegmentReader
  210. //-----------------------------------------------------------------------------
  211. class nsAHttpSegmentReader
  212. {
  213. public:
  214. // any returned failure code stops segment iteration
  215. virtual nsresult OnReadSegment(const char *segment,
  216. uint32_t count,
  217. uint32_t *countRead) = 0;
  218. // Ask the segment reader to commit to accepting size bytes of
  219. // data from subsequent OnReadSegment() calls or throw hard
  220. // (i.e. not wouldblock) exceptions. Implementations
  221. // can return NS_ERROR_FAILURE if they never make commitments of that size
  222. // (the default), NS_OK if they make the commitment, or
  223. // NS_BASE_STREAM_WOULD_BLOCK if they cannot make the
  224. // commitment now but might in the future and forceCommitment is not true .
  225. // (forceCommitment requires a hard failure or OK at this moment.)
  226. //
  227. // SpdySession uses this to make sure frames are atomic.
  228. virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment)
  229. {
  230. return NS_ERROR_FAILURE;
  231. }
  232. };
  233. #define NS_DECL_NSAHTTPSEGMENTREADER \
  234. nsresult OnReadSegment(const char *, uint32_t, uint32_t *) override;
  235. //-----------------------------------------------------------------------------
  236. // nsAHttpSegmentWriter
  237. //-----------------------------------------------------------------------------
  238. class nsAHttpSegmentWriter
  239. {
  240. public:
  241. // any returned failure code stops segment iteration
  242. virtual nsresult OnWriteSegment(char *segment,
  243. uint32_t count,
  244. uint32_t *countWritten) = 0;
  245. };
  246. #define NS_DECL_NSAHTTPSEGMENTWRITER \
  247. nsresult OnWriteSegment(char *, uint32_t, uint32_t *) override;
  248. } // namespace net
  249. } // namespace mozilla
  250. #endif // nsAHttpTransaction_h__