michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsAHttpTransaction_h__ michael@0: #define nsAHttpTransaction_h__ michael@0: michael@0: #include "nsISupports.h" michael@0: #include "nsTArray.h" michael@0: michael@0: class nsIInterfaceRequestor; michael@0: class nsIEventTarget; michael@0: class nsITransport; michael@0: class nsILoadGroupConnectionInfo; michael@0: michael@0: namespace mozilla { namespace net { michael@0: michael@0: class nsAHttpConnection; michael@0: class nsAHttpSegmentReader; michael@0: class nsAHttpSegmentWriter; michael@0: class nsHttpTransaction; michael@0: class nsHttpPipeline; michael@0: class nsHttpRequestHead; michael@0: michael@0: //---------------------------------------------------------------------------- michael@0: // Abstract base class for a HTTP transaction: michael@0: // michael@0: // A transaction is a "sink" for the response data. The connection pushes michael@0: // data to the transaction by writing to it. The transaction supports michael@0: // WriteSegments and may refuse to accept data if its buffers are full (its michael@0: // write function returns NS_BASE_STREAM_WOULD_BLOCK in this case). michael@0: //---------------------------------------------------------------------------- michael@0: michael@0: class nsAHttpTransaction : public nsISupports michael@0: { michael@0: public: michael@0: // called by the connection when it takes ownership of the transaction. michael@0: virtual void SetConnection(nsAHttpConnection *) = 0; michael@0: michael@0: // used to obtain the connection associated with this transaction michael@0: virtual nsAHttpConnection *Connection() = 0; michael@0: michael@0: // called by the connection to get security callbacks to set on the michael@0: // socket transport. michael@0: virtual void GetSecurityCallbacks(nsIInterfaceRequestor **) = 0; michael@0: michael@0: // called to report socket status (see nsITransportEventSink) michael@0: virtual void OnTransportStatus(nsITransport* transport, michael@0: nsresult status, uint64_t progress) = 0; michael@0: michael@0: // called to check the transaction status. michael@0: virtual bool IsDone() = 0; michael@0: virtual nsresult Status() = 0; michael@0: virtual uint32_t Caps() = 0; michael@0: michael@0: // called to notify that a requested DNS cache entry was refreshed. michael@0: virtual void SetDNSWasRefreshed() = 0; michael@0: michael@0: // called to find out how much request data is available for writing. michael@0: virtual uint64_t Available() = 0; michael@0: michael@0: // called to read request data from the transaction. michael@0: virtual nsresult ReadSegments(nsAHttpSegmentReader *reader, michael@0: uint32_t count, uint32_t *countRead) = 0; michael@0: michael@0: // called to write response data to the transaction. michael@0: virtual nsresult WriteSegments(nsAHttpSegmentWriter *writer, michael@0: uint32_t count, uint32_t *countWritten) = 0; michael@0: michael@0: // called to close the transaction michael@0: virtual void Close(nsresult reason) = 0; michael@0: michael@0: // called to indicate a failure with proxy CONNECT michael@0: virtual void SetProxyConnectFailed() = 0; michael@0: michael@0: // called to retrieve the request headers of the transaction michael@0: virtual nsHttpRequestHead *RequestHead() = 0; michael@0: michael@0: // determine the number of real http/1.x transactions on this michael@0: // abstract object. Pipelines may have multiple, SPDY has 0, michael@0: // normal http transactions have 1. michael@0: virtual uint32_t Http1xTransactionCount() = 0; michael@0: michael@0: // called to remove the unused sub transactions from an object that can michael@0: // handle multiple transactions simultaneously (i.e. pipelines or spdy). michael@0: // michael@0: // Returns NS_ERROR_NOT_IMPLEMENTED if the object does not implement michael@0: // sub-transactions. michael@0: // michael@0: // Returns NS_ERROR_ALREADY_OPENED if the subtransactions have been michael@0: // at least partially written and cannot be moved. michael@0: // michael@0: virtual nsresult TakeSubTransactions( michael@0: nsTArray > &outTransactions) = 0; michael@0: michael@0: // called to add a sub-transaction in the case of pipelined transactions michael@0: // classes that do not implement sub transactions michael@0: // return NS_ERROR_NOT_IMPLEMENTED michael@0: virtual nsresult AddTransaction(nsAHttpTransaction *transaction) = 0; michael@0: michael@0: // The total length of the outstanding pipeline comprised of transacations michael@0: // and sub-transactions. michael@0: virtual uint32_t PipelineDepth() = 0; michael@0: michael@0: // Used to inform the connection that it is being used in a pipelined michael@0: // context. That may influence the handling of some errors. michael@0: // The value is the pipeline position (> 1). michael@0: virtual nsresult SetPipelinePosition(int32_t) = 0; michael@0: virtual int32_t PipelinePosition() = 0; michael@0: michael@0: // Occasionally the abstract interface has to give way to base implementations michael@0: // to respect differences between spdy, pipelines, etc.. michael@0: // These Query* (and IsNUllTransaction()) functions provide a way to do michael@0: // that without using xpcom or rtti. Any calling code that can't deal with michael@0: // a null response from one of them probably shouldn't be using nsAHttpTransaction michael@0: michael@0: // If we used rtti this would be the result of doing michael@0: // dynamic_cast(this).. i.e. it can be nullptr for michael@0: // non pipeline implementations of nsAHttpTransaction michael@0: virtual nsHttpPipeline *QueryPipeline() { return nullptr; } michael@0: michael@0: // equivalent to !!dynamic_cast(this) michael@0: // A null transaction is expected to return BASE_STREAM_CLOSED on all of michael@0: // its IO functions all the time. michael@0: virtual bool IsNullTransaction() { return false; } michael@0: michael@0: // return the load group connection information associated with the transaction michael@0: virtual nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() { return nullptr; } michael@0: michael@0: // The base definition of these is done in nsHttpTransaction.cpp michael@0: virtual bool ResponseTimeoutEnabled() const; michael@0: virtual PRIntervalTime ResponseTimeout(); michael@0: michael@0: // Every transaction is classified into one of the types below. When using michael@0: // HTTP pipelines, only transactions with the same type appear on the same michael@0: // pipeline. michael@0: enum Classifier { michael@0: // Transactions that expect a short 304 (no-content) response michael@0: CLASS_REVALIDATION, michael@0: michael@0: // Transactions for content expected to be CSS or JS michael@0: CLASS_SCRIPT, michael@0: michael@0: // Transactions for content expected to be an image michael@0: CLASS_IMAGE, michael@0: michael@0: // Transactions that cannot involve a pipeline michael@0: CLASS_SOLO, michael@0: michael@0: // Transactions that do not fit any of the other categories. HTML michael@0: // is normally GENERAL. michael@0: CLASS_GENERAL, michael@0: michael@0: CLASS_MAX michael@0: }; michael@0: }; michael@0: michael@0: #define NS_DECL_NSAHTTPTRANSACTION \ michael@0: void SetConnection(nsAHttpConnection *); \ michael@0: nsAHttpConnection *Connection(); \ michael@0: void GetSecurityCallbacks(nsIInterfaceRequestor **); \ michael@0: void OnTransportStatus(nsITransport* transport, \ michael@0: nsresult status, uint64_t progress); \ michael@0: bool IsDone(); \ michael@0: nsresult Status(); \ michael@0: uint32_t Caps(); \ michael@0: void SetDNSWasRefreshed(); \ michael@0: uint64_t Available(); \ michael@0: nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *); \ michael@0: nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *); \ michael@0: void Close(nsresult reason); \ michael@0: void SetProxyConnectFailed(); \ michael@0: nsHttpRequestHead *RequestHead(); \ michael@0: uint32_t Http1xTransactionCount(); \ michael@0: nsresult TakeSubTransactions(nsTArray > &outTransactions); \ michael@0: nsresult AddTransaction(nsAHttpTransaction *); \ michael@0: uint32_t PipelineDepth(); \ michael@0: nsresult SetPipelinePosition(int32_t); \ michael@0: int32_t PipelinePosition(); michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // nsAHttpSegmentReader michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: class nsAHttpSegmentReader michael@0: { michael@0: public: michael@0: // any returned failure code stops segment iteration michael@0: virtual nsresult OnReadSegment(const char *segment, michael@0: uint32_t count, michael@0: uint32_t *countRead) = 0; michael@0: michael@0: // Ask the segment reader to commit to accepting size bytes of michael@0: // data from subsequent OnReadSegment() calls or throw hard michael@0: // (i.e. not wouldblock) exceptions. Implementations michael@0: // can return NS_ERROR_FAILURE if they never make commitments of that size michael@0: // (the default), NS_OK if they make the commitment, or michael@0: // NS_BASE_STREAM_WOULD_BLOCK if they cannot make the michael@0: // commitment now but might in the future and forceCommitment is not true . michael@0: // (forceCommitment requires a hard failure or OK at this moment.) michael@0: // michael@0: // SpdySession uses this to make sure frames are atomic. michael@0: virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: }; michael@0: michael@0: #define NS_DECL_NSAHTTPSEGMENTREADER \ michael@0: nsresult OnReadSegment(const char *, uint32_t, uint32_t *); michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // nsAHttpSegmentWriter michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: class nsAHttpSegmentWriter michael@0: { michael@0: public: michael@0: // any returned failure code stops segment iteration michael@0: virtual nsresult OnWriteSegment(char *segment, michael@0: uint32_t count, michael@0: uint32_t *countWritten) = 0; michael@0: }; michael@0: michael@0: #define NS_DECL_NSAHTTPSEGMENTWRITER \ michael@0: nsresult OnWriteSegment(char *, uint32_t, uint32_t *); michael@0: michael@0: }} // namespace mozilla::net michael@0: michael@0: #endif // nsAHttpTransaction_h__