hydrus/include/ClientNetworkingSessions.py

244 lines
7.1 KiB
Python
Raw Normal View History

2019-01-09 22:59:03 +00:00
import pickle
from . import ClientConstants as CC
from . import ClientNetworkingContexts
from . import ClientNetworkingDomain
from . import HydrusData
from . import HydrusSerialisable
from . import HydrusGlobals as HG
2018-04-18 22:10:15 +00:00
import requests
import threading
2018-11-21 22:22:36 +00:00
try:
import socket
import socks
SOCKS_PROXY_OK = True
except:
SOCKS_PROXY_OK = False
2018-04-18 22:10:15 +00:00
class NetworkSessionManager( HydrusSerialisable.SerialisableBase ):
SERIALISABLE_TYPE = HydrusSerialisable.SERIALISABLE_TYPE_NETWORK_SESSION_MANAGER
SERIALISABLE_NAME = 'Session Manager'
SERIALISABLE_VERSION = 1
SESSION_TIMEOUT = 60 * 60
def __init__( self ):
HydrusSerialisable.SerialisableBase.__init__( self )
self.engine = None
self._dirty = False
self._lock = threading.Lock()
self._network_contexts_to_sessions = {}
self._network_contexts_to_session_timeouts = {}
2018-11-21 22:22:36 +00:00
self._proxies_dict = {}
self._Reinitialise()
HG.client_controller.sub( self, 'Reinitialise', 'notify_new_options' )
2018-04-18 22:10:15 +00:00
def _CleanSessionCookies( self, network_context, session ):
if network_context not in self._network_contexts_to_session_timeouts:
self._network_contexts_to_session_timeouts[ network_context ] = 0
if HydrusData.TimeHasPassed( self._network_contexts_to_session_timeouts[ network_context ] ):
session.cookies.clear_session_cookies()
self._network_contexts_to_session_timeouts[ network_context ] = HydrusData.GetNow() + self.SESSION_TIMEOUT
session.cookies.clear_expired_cookies()
def _GenerateSession( self, network_context ):
session = requests.Session()
if network_context.context_type == CC.NETWORK_CONTEXT_HYDRUS:
session.verify = False
return session
def _GetSerialisableInfo( self ):
2019-01-09 22:59:03 +00:00
serialisable_network_contexts_to_sessions = [ ( network_context.GetSerialisableTuple(), pickle.dumps( session ).hex() ) for ( network_context, session ) in list(self._network_contexts_to_sessions.items()) ]
2018-04-18 22:10:15 +00:00
return serialisable_network_contexts_to_sessions
2018-10-24 21:34:02 +00:00
def _GetSessionNetworkContext( self, network_context ):
# just in case one of these slips through somehow
if network_context.context_type == CC.NETWORK_CONTEXT_DOMAIN:
second_level_domain = ClientNetworkingDomain.ConvertDomainIntoSecondLevelDomain( network_context.context_data )
network_context = ClientNetworkingContexts.NetworkContext( CC.NETWORK_CONTEXT_DOMAIN, second_level_domain )
return network_context
2018-04-18 22:10:15 +00:00
def _InitialiseFromSerialisableInfo( self, serialisable_info ):
serialisable_network_contexts_to_sessions = serialisable_info
2019-01-09 22:59:03 +00:00
for ( serialisable_network_context, pickled_session_hex ) in serialisable_network_contexts_to_sessions:
2018-04-18 22:10:15 +00:00
network_context = HydrusSerialisable.CreateFromSerialisableTuple( serialisable_network_context )
2018-10-24 21:34:02 +00:00
try:
2019-01-09 22:59:03 +00:00
session = pickle.loads( bytes.fromhex( pickled_session_hex ) )
2018-10-24 21:34:02 +00:00
except:
# new version of requests uses a diff format, wew
continue
2018-04-18 22:10:15 +00:00
session.cookies.clear_session_cookies()
self._network_contexts_to_sessions[ network_context ] = session
2018-11-21 22:22:36 +00:00
def _Reinitialise( self ):
self._proxies_dict = {}
http_proxy = HG.client_controller.new_options.GetNoneableString( 'http_proxy' )
https_proxy = HG.client_controller.new_options.GetNoneableString( 'https_proxy' )
if http_proxy is not None:
self._proxies_dict[ 'http' ] = http_proxy
if https_proxy is not None:
self._proxies_dict[ 'https' ] = https_proxy
2018-04-18 22:10:15 +00:00
def _SetDirty( self ):
self._dirty = True
def ClearSession( self, network_context ):
with self._lock:
2018-10-24 21:34:02 +00:00
network_context = self._GetSessionNetworkContext( network_context )
2018-04-18 22:10:15 +00:00
if network_context in self._network_contexts_to_sessions:
del self._network_contexts_to_sessions[ network_context ]
self._SetDirty()
def GetNetworkContexts( self ):
with self._lock:
2019-01-09 22:59:03 +00:00
return list(self._network_contexts_to_sessions.keys())
2018-04-18 22:10:15 +00:00
def GetSession( self, network_context ):
with self._lock:
2018-10-24 21:34:02 +00:00
network_context = self._GetSessionNetworkContext( network_context )
2018-04-18 22:10:15 +00:00
if network_context not in self._network_contexts_to_sessions:
self._network_contexts_to_sessions[ network_context ] = self._GenerateSession( network_context )
session = self._network_contexts_to_sessions[ network_context ]
2018-11-21 22:22:36 +00:00
if session.proxies != self._proxies_dict:
session.proxies = dict( self._proxies_dict )
2018-04-18 22:10:15 +00:00
#
self._CleanSessionCookies( network_context, session )
#
# tumblr can't into ssl for some reason, and the data subdomain they use has weird cert properties, looking like amazon S3
# perhaps it is inward-facing somehow? whatever the case, let's just say fuck it for tumblr
if network_context.context_type == CC.NETWORK_CONTEXT_DOMAIN and network_context.context_data == 'tumblr.com':
session.verify = False
#
self._SetDirty()
return session
2018-10-31 21:41:14 +00:00
def GetSessionForDomain( self, domain ):
network_context = ClientNetworkingContexts.NetworkContext( context_type = CC.NETWORK_CONTEXT_DOMAIN, context_data = domain )
return self.GetSession( network_context )
2018-04-18 22:10:15 +00:00
def IsDirty( self ):
with self._lock:
return self._dirty
2018-11-21 22:22:36 +00:00
def Reinitialise( self ):
with self._lock:
self._Reinitialise()
2018-04-18 22:10:15 +00:00
def SetClean( self ):
with self._lock:
self._dirty = False
HydrusSerialisable.SERIALISABLE_TYPES_TO_OBJECT_TYPES[ HydrusSerialisable.SERIALISABLE_TYPE_NETWORK_SESSION_MANAGER ] = NetworkSessionManager