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 nsAHttpConnection_h__ michael@0: #define nsAHttpConnection_h__ michael@0: michael@0: #include "nsISupports.h" michael@0: #include "nsAHttpTransaction.h" michael@0: michael@0: class nsISocketTransport; michael@0: class nsIAsyncInputStream; michael@0: class nsIAsyncOutputStream; michael@0: michael@0: namespace mozilla { namespace net { michael@0: michael@0: class nsHttpConnectionInfo; michael@0: class nsHttpConnection; michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: // Abstract base class for a HTTP connection michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: class nsAHttpConnection : public nsISupports michael@0: { michael@0: public: michael@0: //------------------------------------------------------------------------- michael@0: // NOTE: these methods may only be called on the socket thread. michael@0: //------------------------------------------------------------------------- michael@0: michael@0: // michael@0: // called by a transaction when the response headers have all been read. michael@0: // the connection can force the transaction to reset it's response headers, michael@0: // and prepare for a new set of response headers, by setting |*reset=TRUE|. michael@0: // michael@0: // @return failure code to close the transaction. michael@0: // michael@0: virtual nsresult OnHeadersAvailable(nsAHttpTransaction *, michael@0: nsHttpRequestHead *, michael@0: nsHttpResponseHead *, michael@0: bool *reset) = 0; michael@0: michael@0: // michael@0: // called by a transaction to resume either sending or receiving data michael@0: // after a transaction returned NS_BASE_STREAM_WOULD_BLOCK from its michael@0: // ReadSegments/WriteSegments methods. michael@0: // michael@0: virtual nsresult ResumeSend() = 0; michael@0: virtual nsresult ResumeRecv() = 0; michael@0: michael@0: // called by a transaction to force a "read from network" iteration michael@0: // even if not scheduled by socket associated with connection michael@0: virtual nsresult ForceRecv() = 0; michael@0: michael@0: // After a connection has had ResumeSend() called by a transaction, michael@0: // and it is ready to write to the network it may need to know the michael@0: // transaction that has data to write. This is only an issue for michael@0: // multiplexed protocols like SPDY - plain HTTP or pipelined HTTP michael@0: // implicitly have this information in a 1:1 relationship with the michael@0: // transaction(s) they manage. michael@0: virtual void TransactionHasDataToWrite(nsAHttpTransaction *) michael@0: { michael@0: // by default do nothing - only multiplexed protocols need to overload michael@0: return; michael@0: } michael@0: // michael@0: // called by the connection manager to close a transaction being processed michael@0: // by this connection. michael@0: // michael@0: // @param transaction michael@0: // the transaction being closed. michael@0: // @param reason michael@0: // the reason for closing the transaction. NS_BASE_STREAM_CLOSED michael@0: // is equivalent to NS_OK. michael@0: // michael@0: virtual void CloseTransaction(nsAHttpTransaction *transaction, michael@0: nsresult reason) = 0; michael@0: michael@0: // get a reference to the connection's connection info object. michael@0: virtual void GetConnectionInfo(nsHttpConnectionInfo **) = 0; michael@0: michael@0: // get the transport level information for this connection. This may fail michael@0: // if it is in use. michael@0: virtual nsresult TakeTransport(nsISocketTransport **, michael@0: nsIAsyncInputStream **, michael@0: nsIAsyncOutputStream **) = 0; michael@0: michael@0: // called by a transaction to get the security info from the socket. michael@0: virtual void GetSecurityInfo(nsISupports **) = 0; michael@0: michael@0: // called by a transaction to determine whether or not the connection is michael@0: // persistent... important in determining the end of a response. michael@0: virtual bool IsPersistent() = 0; michael@0: michael@0: // called to determine or set if a connection has been reused. michael@0: virtual bool IsReused() = 0; michael@0: virtual void DontReuse() = 0; michael@0: michael@0: // called by a transaction when the transaction reads more from the socket michael@0: // than it should have (eg. containing part of the next pipelined response). michael@0: virtual nsresult PushBack(const char *data, uint32_t length) = 0; michael@0: michael@0: // Used to determine if the connection wants read events even though michael@0: // it has not written out a transaction. Used when a connection has issued michael@0: // a preamble such as a proxy ssl CONNECT sequence. michael@0: virtual bool IsProxyConnectInProgress() = 0; michael@0: michael@0: // Used by a transaction to manage the state of previous response bodies on michael@0: // the same connection and work around buggy servers. michael@0: virtual bool LastTransactionExpectedNoContent() = 0; michael@0: virtual void SetLastTransactionExpectedNoContent(bool) = 0; michael@0: michael@0: // Transfer the base http connection object along with a michael@0: // reference to it to the caller. michael@0: virtual nsHttpConnection *TakeHttpConnection() = 0; michael@0: michael@0: // Get the nsISocketTransport used by the connection without changing michael@0: // references or ownership. michael@0: virtual nsISocketTransport *Transport() = 0; michael@0: michael@0: // Cancel and reschedule transactions deeper than the current response. michael@0: // Returns the number of canceled transactions. michael@0: virtual uint32_t CancelPipeline(nsresult originalReason) = 0; michael@0: michael@0: // Read and write class of transaction that is carried on this connection michael@0: virtual nsAHttpTransaction::Classifier Classification() = 0; michael@0: virtual void Classify(nsAHttpTransaction::Classifier newclass) = 0; michael@0: michael@0: // The number of transaction bytes written out on this HTTP Connection, does michael@0: // not count CONNECT tunnel setup michael@0: virtual int64_t BytesWritten() = 0; michael@0: michael@0: // Update the callbacks used to provide security info. May be called on michael@0: // any thread. michael@0: virtual void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) = 0; michael@0: }; michael@0: michael@0: #define NS_DECL_NSAHTTPCONNECTION(fwdObject) \ michael@0: nsresult OnHeadersAvailable(nsAHttpTransaction *, nsHttpRequestHead *, nsHttpResponseHead *, bool *reset); \ michael@0: void CloseTransaction(nsAHttpTransaction *, nsresult); \ michael@0: nsresult TakeTransport(nsISocketTransport **, \ michael@0: nsIAsyncInputStream **, \ michael@0: nsIAsyncOutputStream **); \ michael@0: bool IsPersistent(); \ michael@0: bool IsReused(); \ michael@0: void DontReuse(); \ michael@0: nsresult PushBack(const char *, uint32_t); \ michael@0: nsHttpConnection *TakeHttpConnection(); \ michael@0: uint32_t CancelPipeline(nsresult originalReason); \ michael@0: nsAHttpTransaction::Classifier Classification(); \ michael@0: /* \ michael@0: Thes methods below have automatic definitions that just forward the \ michael@0: function to a lower level connection object \ michael@0: */ \ michael@0: void GetConnectionInfo(nsHttpConnectionInfo **result) \ michael@0: { \ michael@0: if (!(fwdObject)) { \ michael@0: *result = nullptr; \ michael@0: return; \ michael@0: } \ michael@0: return (fwdObject)->GetConnectionInfo(result); \ michael@0: } \ michael@0: void GetSecurityInfo(nsISupports **result) \ michael@0: { \ michael@0: if (!(fwdObject)) { \ michael@0: *result = nullptr; \ michael@0: return; \ michael@0: } \ michael@0: return (fwdObject)->GetSecurityInfo(result); \ michael@0: } \ michael@0: nsresult ResumeSend() \ michael@0: { \ michael@0: if (!(fwdObject)) \ michael@0: return NS_ERROR_FAILURE; \ michael@0: return (fwdObject)->ResumeSend(); \ michael@0: } \ michael@0: nsresult ResumeRecv() \ michael@0: { \ michael@0: if (!(fwdObject)) \ michael@0: return NS_ERROR_FAILURE; \ michael@0: return (fwdObject)->ResumeRecv(); \ michael@0: } \ michael@0: nsresult ForceRecv() \ michael@0: { \ michael@0: if (!(fwdObject)) \ michael@0: return NS_ERROR_FAILURE; \ michael@0: return (fwdObject)->ForceRecv(); \ michael@0: } \ michael@0: nsISocketTransport *Transport() \ michael@0: { \ michael@0: if (!(fwdObject)) \ michael@0: return nullptr; \ michael@0: return (fwdObject)->Transport(); \ michael@0: } \ michael@0: bool IsProxyConnectInProgress() \ michael@0: { \ michael@0: return (fwdObject)->IsProxyConnectInProgress(); \ michael@0: } \ michael@0: bool LastTransactionExpectedNoContent() \ michael@0: { \ michael@0: return (fwdObject)->LastTransactionExpectedNoContent(); \ michael@0: } \ michael@0: void SetLastTransactionExpectedNoContent(bool val) \ michael@0: { \ michael@0: return (fwdObject)->SetLastTransactionExpectedNoContent(val); \ michael@0: } \ michael@0: void Classify(nsAHttpTransaction::Classifier newclass) \ michael@0: { \ michael@0: if (fwdObject) \ michael@0: return (fwdObject)->Classify(newclass); \ michael@0: } \ michael@0: int64_t BytesWritten() \ michael@0: { return fwdObject ? (fwdObject)->BytesWritten() : 0; } \ michael@0: void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) \ michael@0: { \ michael@0: if (fwdObject) \ michael@0: (fwdObject)->SetSecurityCallbacks(aCallbacks); \ michael@0: } michael@0: michael@0: }} // namespace mozilla::net michael@0: michael@0: #endif // nsAHttpConnection_h__