# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved.
# License: New BSD License.
# Website: http://code.google.com/p/cefpython/
include "cefpython.pyx"
import weakref
# -----------------------------------------------------------------------------
# Globals
# -----------------------------------------------------------------------------
# See StoreUserCookieVisitor().
cdef object g_userResourceHandler = weakref.WeakValueDictionary()
cdef int g_userResourceHandlerMaxId = 0
# -----------------------------------------------------------------------------
# ResourceHandler
# -----------------------------------------------------------------------------
cdef py_void ValidateUserResourceHandler(object userResourceHandler):
cdef list methods = ["ProcessRequest", "GetResponseHeaders",
"ReadResponse", "CanGetCookie", "CanSetCookie", "Cancel"]
for method in methods:
if userResourceHandler and hasattr(userResourceHandler, method)\
and callable(getattr(userResourceHandler, method)):
# Okay.
continue
else:
raise Exception("ResourceHandler object is missing method: %s"\
% method)
cdef CefRefPtr[CefResourceHandler] CreateResourceHandler(
object userResourceHandler) except *:
ValidateUserResourceHandler(userResourceHandler)
cdef int resourceHandlerId = StoreUserResourceHandler(userResourceHandler)
cdef CefRefPtr[CefResourceHandler] resourceHandler =\
new ResourceHandler(
resourceHandlerId)
return resourceHandler
cdef int StoreUserResourceHandler(object userResourceHandler) except *:
global g_userResourceHandlerMaxId
global g_userResourceHandler
g_userResourceHandlerMaxId += 1
g_userResourceHandler[g_userResourceHandlerMaxId] = userResourceHandler
return g_userResourceHandlerMaxId
cdef PyResourceHandler GetPyResourceHandler(int resourceHandlerId):
global g_userResourceHandler
cdef object userResourceHandler
cdef PyResourceHandler pyResourceHandler
if resourceHandlerId in g_userResourceHandler:
userResourceHandler = g_userResourceHandler[resourceHandlerId]
pyResourceHandler = PyResourceHandler(userResourceHandler)
return pyResourceHandler
cdef class PyResourceHandler:
cdef object userResourceHandler
def __init__(self, object userResourceHandler):
self.userResourceHandler = userResourceHandler
cdef object GetCallback(self, str funcName):
if self.userResourceHandler and (
hasattr(self.userResourceHandler, funcName) and (
callable(getattr(self.userResourceHandler, funcName)))):
return getattr(self.userResourceHandler, funcName)
# ------------------------------------------------------------------------------
# ResourceHandler callbacks
# ------------------------------------------------------------------------------
cdef public cpp_bool ResourceHandler_ProcessRequest(
int resourceHandlerId,
CefRefPtr[CefRequest] cefRequest,
CefRefPtr[CefCallback] cefCallback
) except * with gil:
cdef PyResourceHandler pyResourceHandler
cdef object userCallback
cdef py_bool returnValue
cdef PyRequest pyRequest
cdef PyCallback pyCallback
try:
assert IsThread(TID_IO), "Must be called on the IO thread"
pyResourceHandler = GetPyResourceHandler(resourceHandlerId)
pyRequest = CreatePyRequest(cefRequest)
pyCallback = CreatePyCallback(cefCallback)
if pyResourceHandler:
userCallback = pyResourceHandler.GetCallback("ProcessRequest")
if userCallback:
returnValue = userCallback(pyRequest, pyCallback)
return bool(returnValue)
return False
except:
(exc_type, exc_value, exc_trace) = sys.exc_info()
sys.excepthook(exc_type, exc_value, exc_trace)
cdef public void ResourceHandler_GetResponseHeaders(
int resourceHandlerId,
CefRefPtr[CefResponse] cefResponse,
int64& cefResponseLength,
CefString& cefRedirectUrl
) except * with gil:
cdef PyResourceHandler pyResourceHandler
cdef object userCallback
cdef py_bool returnValue
cdef PyResponse pyResponse
cdef list responseLengthOut
cdef list redirectUrlOut
try:
assert IsThread(TID_IO), "Must be called on the IO thread"
pyResourceHandler = GetPyResourceHandler(resourceHandlerId)
pyResponse = CreatePyResponse(cefResponse)
responseLengthOut = [cefResponseLength]
redirectUrlOut = [CefToPyString(cefRedirectUrl)]
if pyResourceHandler:
userCallback = pyResourceHandler.GetCallback("GetResponseHeaders")
if userCallback:
returnValue = userCallback(pyResponse, responseLengthOut,
redirectUrlOut)
(&cefResponseLength)[0] = long(responseLengthOut[0])
if redirectUrlOut[0]:
PyToCefString(redirectUrlOut[0], cefRedirectUrl)
return
return
except:
(exc_type, exc_value, exc_trace) = sys.exc_info()
sys.excepthook(exc_type, exc_value, exc_trace)
cdef public cpp_bool ResourceHandler_ReadResponse(
int resourceHandlerId,
void* cefDataOut,
int bytesToRead,
int& cefBytesRead,
CefRefPtr[CefCallback] cefCallback
) except * with gil:
cdef PyResourceHandler pyResourceHandler
cdef object userCallback
cdef py_bool returnValue
cdef list dataOut
cdef list bytesReadOut
cdef PyCallback pyCallback
cdef char* tempData
cdef int tempDataLength
cdef int pyBytesRead
try:
assert IsThread(TID_IO), "Must be called on the IO thread"
pyResourceHandler = GetPyResourceHandler(resourceHandlerId)
dataOut = [""]
bytesReadOut = [0]
pyCallback = CreatePyCallback(cefCallback)
if pyResourceHandler:
userCallback = pyResourceHandler.GetCallback("ReadResponse")
if userCallback:
returnValue = userCallback(dataOut, bytesToRead, bytesReadOut,
pyCallback)
pyBytesRead = int(bytesReadOut[0])
if dataOut[0] and IsString(dataOut[0]):
# The tempData pointer is tied to the lifetime
# of dataOut[0] string.
tempData = dataOut[0]
memcpy(cefDataOut, tempData, len(dataOut[0]))
assert pyBytesRead >= 0, "bytesReadOut