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
|