зеркало из https://github.com/mozilla/gecko-dev.git
173 строки
7.4 KiB
C++
173 строки
7.4 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_net_WebTransportProxy_h
|
|
#define mozilla_net_WebTransportProxy_h
|
|
|
|
#include "nsIChannelEventSink.h"
|
|
#include "nsIInterfaceRequestor.h"
|
|
#include "nsIRedirectResultListener.h"
|
|
#include "nsIStreamListener.h"
|
|
#include "nsIWebTransport.h"
|
|
|
|
/*
|
|
* WebTransportSessionProxy is introduced to enable the creation of a
|
|
* Http3WebTransportSession and coordination of actions that are performed on
|
|
* the main thread and on the socket thread.
|
|
*
|
|
* mChannel, mRedirectChannel, and mListener are used only on the main thread.
|
|
*
|
|
* mWebTransportSession is used only on the socket thread.
|
|
*
|
|
* mState and mSessionId are used on both threads, socket and main thread and it
|
|
* is only used with a lock.
|
|
*
|
|
*
|
|
* WebTransportSessionProxyState:
|
|
* - INIT: before AsyncConnect is called.
|
|
*
|
|
* - NEGOTIATING: It is set during AsyncConnect. During this state HttpChannel
|
|
* is open but OnStartRequest has not been called yet. This state can
|
|
* transfer into:
|
|
* - NEGOTIATING_SUCCEEDED: when a Http3WebTransportSession has been
|
|
* negotiated.
|
|
* - DONE: when a WebTransport session has been canceled.
|
|
*
|
|
* - NEGOTIATING_SUCCEEDED: It is set during parsing of
|
|
* Http3WebTransportSession response when the response has been successful.
|
|
* mWebTransport is set to the Http3WebTransportSession at the same time the
|
|
* session changes to this state. This state can transfer into:
|
|
* - ACTIVE: during the OnStopRequest call if the WebTransport has not been
|
|
* canceled or failed for other reason, e.g. a browser shutdown or content
|
|
* blocking policies.
|
|
* - SESSION_CLOSE_PENDING: if the WebTransport has been canceled via an API
|
|
* call or content blocking policies. (the main thread initiated close).
|
|
* - CLOSE_CALLBACK_PENDING: if Http3WebTransportSession has been canceled
|
|
* due to a shutdown or a server closing a session. (the socket thread
|
|
* initiated close).
|
|
*
|
|
* - ACTIVE: In this state the session is negotiated and ready to use. This
|
|
* state can transfer into:
|
|
* - SESSION_CLOSE_PENDING: if the WebTransport has been canceled via an API
|
|
* call(nsIWebTransport::closeSession) or content blocking policies. (the
|
|
* main thread initiated close).
|
|
* - CLOSE_CALLBACK_PENDING: if Http3WebTransportSession has been canceled
|
|
* due to a shutdown or a server closing a session. (the socket thread
|
|
* initiated close).
|
|
*
|
|
* - CLOSE_CALLBACK_PENDING: This is the socket thread initiated close. In this
|
|
* state, the Http3WebTransportSession has been closed and a
|
|
* CallOnSessionClosed call is dispatched to the main thread to call the
|
|
* appropriate listener.
|
|
*
|
|
* - SESSION_CLOSE_PENDING: This is the main thread initiated close. In this
|
|
* state, the WebTransport has been closed via an API call
|
|
* (nsIWebTransport::closeSession) and a CloseSessionInternal call is
|
|
* dispatched to the socket thread to close the appropriate
|
|
* Http3WebTransportSession.
|
|
*
|
|
* - DONE: everything has been cleaned up on both threads.
|
|
*
|
|
*
|
|
* AsyncConnect creates mChannel on the main thread. Redirect callbacks are also
|
|
* performed on the main thread (mRedirectChannel set and access only on the
|
|
* main thread). Before this point, there are no activities on the socket thread
|
|
* and Http3WebTransportSession is nullptr. mChannel is going to create a
|
|
* nsHttpTransaction. The transaction will be dispatched on a nsAHttpConnection,
|
|
* i.e. currently only the HTTP/3 version is implemented, therefore this will be
|
|
* a HttpConnectionUDP and a Http3Session. The Http3Session creates a
|
|
* Http3WebTransportSession. Until a response is received
|
|
* Http3WebTransportSession is only accessed by Http3Session. During parsing of
|
|
* a successful received from a server on the socket thread,
|
|
* WebTransportSessionProxy::mWebTransportSession will take a reference to
|
|
* Http3WebTransportSession and mState will be set to NEGOTIATING_SUCCEEDED.
|
|
* From now on WebTransportSessionProxy is responsible for closing
|
|
* Http3WebTransportSession if the closing of the session is initiated on the
|
|
* main thread. OnStartRequest and OnStopRequest will be called on the main
|
|
* thread. The session negotiation can have 2 outcomes:
|
|
* - If both calls, i.e. OnStartRequest an OnStopRequest, indicate that the
|
|
* request has succeeded and mState is NEGOTIATING_SUCCEEDED, the
|
|
* mListener->OnSessionReady will be called during OnStopRequest.
|
|
* - Otherwise, mListener->OnSessionClosed will be called, the state transferred
|
|
* into SESSION_CLOSE_PENDING, and CloseSessionInternal will be dispatched to
|
|
* the socket thread.
|
|
*
|
|
* CloseSession is called on the main thread. If the session is already closed
|
|
* it returns an error. If the session is in state NEGOTIATING or
|
|
* NEGOTIATING_SUCCEEDED mChannel will be canceled. If the session is in state
|
|
* NEGOTIATING_SUCCEEDED or ACTIVE the state transferred into
|
|
* SESSION_CLOSE_PENDING, and CloseSessionInternal will be dispatched to the
|
|
* socket thread
|
|
*
|
|
* OnSessionReadyInternal is called on the socket thread. If mState is
|
|
* NEGOTIATING the state will be set to NEGOTIATING_SUCCEEDED and mWebTransport
|
|
* will be set to the newly negotiated Http3WebTransportSession. If mState is
|
|
* DONE, the Http3WebTransportSession will be close.
|
|
*
|
|
* OnSessionClosed is called on the socket thread. mState will be set to
|
|
* CLOSE_CALLBACK_PENDING and CallOnSessionClosed will be dispatched to the main
|
|
* thread.
|
|
*
|
|
* mWebTransport is set during states NEGOTIATING_SUCCEEDED, ACTIVE and
|
|
* SESSION_CLOSE_PENDING.
|
|
*/
|
|
|
|
namespace mozilla::net {
|
|
|
|
class WebTransportStreamCallbackWrapper;
|
|
|
|
class WebTransportSessionProxy final : public nsIWebTransport,
|
|
public WebTransportSessionEventListener,
|
|
public nsIStreamListener,
|
|
public nsIChannelEventSink,
|
|
public nsIRedirectResultListener,
|
|
public nsIInterfaceRequestor {
|
|
public:
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
NS_DECL_NSIWEBTRANSPORT
|
|
NS_DECL_WEBTRANSPORTSESSIONEVENTLISTENER
|
|
NS_DECL_NSIREQUESTOBSERVER
|
|
NS_DECL_NSISTREAMLISTENER
|
|
NS_DECL_NSICHANNELEVENTSINK
|
|
NS_DECL_NSIREDIRECTRESULTLISTENER
|
|
NS_DECL_NSIINTERFACEREQUESTOR
|
|
|
|
WebTransportSessionProxy();
|
|
|
|
private:
|
|
~WebTransportSessionProxy();
|
|
|
|
void CloseSessionInternal();
|
|
void CallOnSessionClosed();
|
|
|
|
enum WebTransportSessionProxyState {
|
|
INIT,
|
|
NEGOTIATING,
|
|
NEGOTIATING_SUCCEEDED,
|
|
ACTIVE,
|
|
CLOSE_CALLBACK_PENDING,
|
|
SESSION_CLOSE_PENDING,
|
|
DONE,
|
|
};
|
|
mozilla::Mutex mMutex;
|
|
WebTransportSessionProxyState mState MOZ_GUARDED_BY(mMutex) =
|
|
WebTransportSessionProxyState::INIT;
|
|
void ChangeState(WebTransportSessionProxyState newState);
|
|
void CreateStreamInternal(WebTransportStreamCallbackWrapper* aCallback,
|
|
bool aBidi);
|
|
|
|
nsCOMPtr<nsIChannel> mChannel;
|
|
nsCOMPtr<nsIChannel> mRedirectChannel;
|
|
nsCOMPtr<WebTransportSessionEventListener> mListener;
|
|
RefPtr<Http3WebTransportSession> mWebTransportSession;
|
|
uint64_t mSessionId MOZ_GUARDED_BY(mMutex) = UINT64_MAX;
|
|
uint32_t mCloseStatus MOZ_GUARDED_BY(mMutex) = 0;
|
|
nsCString mReason MOZ_GUARDED_BY(mMutex);
|
|
};
|
|
|
|
} // namespace mozilla::net
|
|
|
|
#endif // mozilla_net_WebTransportProxy_h
|