@@ -513,6 +513,8 @@ cdef class Connection:
513513 * ``dtime``
514514 ABAP DATE and TIME strings are returned as Python datetime date and time objects,
515515 instead of ABAP date and time strings (default is False)
516+ The plausiblity of time string sent to function container is checked in PyRFC only
517+ if this option set to True. Otherwise validated by SAP NW RFC SDK and ABAP application
516518
517519 * ``rstrip``
518520 right strips strings returned from RFC call (default is True)
@@ -548,7 +550,7 @@ cdef class Connection:
548550 :raises: :exc:`~pyrfc.RFCError` or a subclass
549551 thereof if the connection attempt fails.
550552 """
551- cdef unsigned __bconfig
553+ cdef unsigned bconfig
552554 cdef public dict __config
553555 cdef bint active_transaction
554556 cdef bint active_unit
@@ -609,13 +611,13 @@ cdef class Connection:
609611 self .__config[' timeout' ] = config.get(' timeout' , None )
610612
611613 # set internal configuration
612- self .__bconfig = 0
614+ self .bconfig = 0
613615 if self .__config[' dtime' ]:
614- self .__bconfig |= _MASK_DTIME
616+ self .bconfig |= _MASK_DTIME
615617 if self .__config[' return_import_params' ]:
616- self .__bconfig |= _MASK_RETURN_IMPORT_PARAMS
618+ self .bconfig |= _MASK_RETURN_IMPORT_PARAMS
617619 if self .__config[' rstrip' ]:
618- self .__bconfig |= _MASK_RSTRIP
620+ self .bconfig |= _MASK_RSTRIP
619621
620622 self ._connection = ConnectionParameters(** params)
621623 self ._handle = NULL
@@ -913,7 +915,7 @@ cdef class Connection:
913915 cancel_timer = Timer(timeout, cancel_connection, (self ,))
914916 cancel_timer.start()
915917 for name, value in params.iteritems():
916- fillFunctionParameter (funcDesc, funcCont, name, value)
918+ functionContainerSet (funcDesc, funcCont, name, value, self .bconfig )
917919 # save old handle for troubleshooting
918920 with nogil:
919921 rc = RfcInvoke(self ._handle, funcCont, & errorInfo)
@@ -941,10 +943,10 @@ cdef class Connection:
941943 elif errorInfo.code == RFC_CANCELED:
942944 errorInfo.message = fillString(f" Connection was canceled: {closed_handle}. New handle: {self.handle}" )
943945 self ._error(& errorInfo)
944- if self .__bconfig & _MASK_RETURN_IMPORT_PARAMS:
945- return wrapResult (funcDesc, funcCont, < RFC_DIRECTION> 0 , self .__bconfig )
946+ if self .bconfig & _MASK_RETURN_IMPORT_PARAMS:
947+ return functionContainerGet (funcDesc, funcCont, < RFC_DIRECTION> 0 , self .bconfig )
946948 else :
947- return wrapResult (funcDesc, funcCont, RFC_IMPORT, self .__bconfig )
949+ return functionContainerGet (funcDesc, funcCont, RFC_IMPORT, self .bconfig )
948950 finally :
949951 RfcDestroyFunction(funcCont, NULL )
950952
@@ -1061,7 +1063,7 @@ cdef class Connection:
10611063 self ._error(& errorInfo)
10621064 try :
10631065 for name, value in params.iteritems():
1064- fillFunctionParameter (funcDesc, funcCont, name, value)
1066+ functionContainerSet (funcDesc, funcCont, name, value, self .bconfig )
10651067 # Add RFC call to transaction
10661068 rc = RfcInvokeInTransaction(self ._tHandle, funcCont, & errorInfo)
10671069 if rc != RFC_OK:
@@ -1238,7 +1240,7 @@ cdef class Connection:
12381240 self ._error(& errorInfo)
12391241 try :
12401242 for name, value in params.iteritems():
1241- fillFunctionParameter (funcDesc, funcCont, name, value)
1243+ functionContainerSet (funcDesc, funcCont, name, value, self .bconfig )
12421244 # Add RFC call to unit
12431245 rc = RfcInvokeInUnit(self ._uHandle, funcCont, & errorInfo)
12441246 if rc != RFC_OK:
@@ -1615,15 +1617,15 @@ cdef RFC_RC genericHandler(RFC_CONNECTION_HANDLE rfcHandle, RFC_FUNCTION_HANDLE
16151617
16161618 # Filter out variables that are of direction u'RFC_EXPORT'
16171619 # (these will be set by the callback function)
1618- func_handle_variables = wrapResult (funcDesc, funcHandle, RFC_EXPORT, server.rstrip )
1620+ func_handle_variables = functionContainerGet (funcDesc, funcHandle, RFC_EXPORT, server.bconfig )
16191621
16201622 # Invoke callback function
16211623 result = callback(request_context, ** func_handle_variables)
16221624
16231625 # Return results
16241626 if context[" call_type" ] != UnitCallType.background_unit:
16251627 for name, value in result.iteritems():
1626- fillFunctionParameter (funcDesc, funcHandle, name, value)
1628+ functionContainerSet (funcDesc, funcHandle, name, value, server.bconfig )
16271629
16281630 # Server exception handling: cf. SAP NetWeaver RFC SDK 7.50
16291631 # 5.1 Preparing a Server Program for Receiving RFC Requests
@@ -1687,9 +1689,16 @@ cdef class Server:
16871689
16881690 :type server_params: dict
16891691
1690- :param config: Configuration of the instance. Allowed keys are:
1692+ :param config: Configuration of server instance. Allowed keys are:
16911693
1692- ``debug``
1694+ * ``dtime``
1695+ ABAP DATE and TIME strings are returned as Python datetime date and time objects,
1696+ instead of ABAP date and time strings (default is False)
1697+
1698+ * ``rstrip``
1699+ right strips strings returned from RFC call (default is True)
1700+
1701+ * ``debug``
16931702 For testing/debugging operations. If True, the server
16941703 behaves more permissive, e.g. allows incoming calls without a
16951704 valid connection handle. (default is False)
@@ -1700,7 +1709,9 @@ cdef class Server:
17001709 thereof if the connection attempt fails.
17011710 """
17021711 cdef public bint debug
1712+ cdef public bint dtime
17031713 cdef public bint rstrip
1714+ cdef public unsigned bconfig
17041715 cdef Connection _client_connection
17051716 cdef ConnectionParameters _server_handle_params
17061717 cdef RFC_SERVER_HANDLE _server_handle
@@ -1746,14 +1757,21 @@ cdef class Server:
17461757 return self .alive
17471758
17481759 def __cinit__ (self , server_params , client_params , config = None ):
1749- # config parsing
1760+ # check and set server configuration
17501761 config = config or {}
1762+ self .dtime = config.get(' dtime' , False )
17511763 self .debug = config.get(' debug' , False )
17521764 self .rstrip = config.get(' rstrip' , True )
17531765 server_context[" server_log" ] = config.get(" server_log" , False )
17541766 server_context[" auth_check" ] = config.get(" auth_check" , default_auth_check)
17551767 server_context[" port" ] = config.get(" port" , 8080 )
17561768
1769+ self .bconfig = 0
1770+ if self .dtime:
1771+ self .bconfig |= _MASK_DTIME
1772+ if self .rstrip:
1773+ self .bconfig |= _MASK_RSTRIP
1774+
17571775 self ._server_handle_params = ConnectionParameters(** server_params)
17581776 self ._client_connection = Connection(** client_params)
17591777 self ._server_thread= Thread(target = self .serve)
@@ -2391,7 +2409,7 @@ cdef class Throughput:
23912409# FILL FUNCTIONS #
23922410# ###############################################################################
23932411
2394- cdef fillFunctionParameter (RFC_FUNCTION_DESC_HANDLE funcDesc, RFC_FUNCTION_HANDLE container, name, value):
2412+ cdef functionContainerSet (RFC_FUNCTION_DESC_HANDLE funcDesc, RFC_FUNCTION_HANDLE container, name, value, unsigned config ):
23952413 cdef RFC_RC rc
23962414 cdef RFC_ERROR_INFO errorInfo
23972415 cdef RFC_PARAMETER_DESC paramDesc
@@ -2400,9 +2418,9 @@ cdef fillFunctionParameter(RFC_FUNCTION_DESC_HANDLE funcDesc, RFC_FUNCTION_HANDL
24002418 free(cName)
24012419 if rc != RFC_OK:
24022420 raise wrapError(& errorInfo)
2403- fillVariable(paramDesc.type, container, paramDesc.name, value, paramDesc.typeDescHandle)
2421+ fillVariable(paramDesc.type, container, paramDesc.name, value, paramDesc.typeDescHandle, config )
24042422
2405- cdef fillStructureField(RFC_TYPE_DESC_HANDLE typeDesc, RFC_STRUCTURE_HANDLE container, name, value):
2423+ cdef fillStructureField(RFC_TYPE_DESC_HANDLE typeDesc, RFC_STRUCTURE_HANDLE container, name, value, unsigned config ):
24062424 cdef RFC_RC rc
24072425 cdef RFC_ERROR_INFO errorInfo
24082426 cdef RFC_FIELD_DESC fieldDesc
@@ -2411,9 +2429,9 @@ cdef fillStructureField(RFC_TYPE_DESC_HANDLE typeDesc, RFC_STRUCTURE_HANDLE cont
24112429 free(cName)
24122430 if rc != RFC_OK:
24132431 raise wrapError(& errorInfo)
2414- fillVariable(fieldDesc.type, container, fieldDesc.name, value, fieldDesc.typeDescHandle)
2432+ fillVariable(fieldDesc.type, container, fieldDesc.name, value, fieldDesc.typeDescHandle, config )
24152433
2416- cdef fillTable(RFC_TYPE_DESC_HANDLE typeDesc, RFC_TABLE_HANDLE container, lines):
2434+ cdef fillTable(RFC_TYPE_DESC_HANDLE typeDesc, RFC_TABLE_HANDLE container, lines, unsigned config ):
24172435 cdef RFC_ERROR_INFO errorInfo
24182436 cdef RFC_STRUCTURE_HANDLE lineHandle
24192437 cdef unsigned int rowCount = int (len (lines))
@@ -2425,12 +2443,12 @@ cdef fillTable(RFC_TYPE_DESC_HANDLE typeDesc, RFC_TABLE_HANDLE container, lines)
24252443 line = lines[i]
24262444 if type (line) is dict :
24272445 for name, value in line.iteritems():
2428- fillStructureField(typeDesc, lineHandle, name, value)
2446+ fillStructureField(typeDesc, lineHandle, name, value, config )
24292447 else :
2430- fillStructureField(typeDesc, lineHandle, ' ' , line)
2448+ fillStructureField(typeDesc, lineHandle, ' ' , line, config )
24312449 i += 1
24322450
2433- cdef fillVariable(RFCTYPE typ, RFC_FUNCTION_HANDLE container, SAP_UC* cName, value, RFC_TYPE_DESC_HANDLE typeDesc):
2451+ cdef fillVariable(RFCTYPE typ, RFC_FUNCTION_HANDLE container, SAP_UC* cName, value, RFC_TYPE_DESC_HANDLE typeDesc, unsigned config ):
24342452 cdef RFC_RC rc
24352453 cdef RFC_ERROR_INFO errorInfo
24362454 cdef RFC_STRUCTURE_HANDLE struct
@@ -2447,14 +2465,14 @@ cdef fillVariable(RFCTYPE typ, RFC_FUNCTION_HANDLE container, SAP_UC* cName, val
24472465 if rc != RFC_OK:
24482466 raise wrapError(& errorInfo)
24492467 for name, value in value.iteritems():
2450- fillStructureField(typeDesc, struct , name, value)
2468+ fillStructureField(typeDesc, struct , name, value, config )
24512469 elif typ == RFCTYPE_TABLE:
24522470 if type (value) is not list :
24532471 raise TypeError (' list required for table parameter, received' , str (type (value)))
24542472 rc = RfcGetTable(container, cName, & table, & errorInfo)
24552473 if rc != RFC_OK:
24562474 raise wrapError(& errorInfo)
2457- fillTable(typeDesc, table, value)
2475+ fillTable(typeDesc, table, value, config )
24582476 elif typ == RFCTYPE_BYTE:
24592477 bValue = fillBytes(value)
24602478 rc = RfcSetBytes(container, cName, bValue, int (len (value)), & errorInfo)
@@ -2549,8 +2567,10 @@ cdef fillVariable(RFCTYPE typ, RFC_FUNCTION_HANDLE container, SAP_UC* cName, val
25492567 if len (value) != 6 :
25502568 format_ok = False
25512569 else :
2552- if len (value.rstrip()) > 0 :
2553- time(int (value[:2 ]), int (value[2 :4 ]), int (value[4 :6 ]))
2570+ # plausability check if Python datetime format used
2571+ if config & _MASK_DTIME:
2572+ if len (value.rstrip()) > 0 :
2573+ time(int (value[:2 ]), int (value[2 :4 ]), int (value[4 :6 ]))
25542574 cValue = fillString(value)
25552575 except Exception as ex:
25562576 format_ok = False
@@ -2773,11 +2793,11 @@ cdef wrapFunctionDescription(RFC_FUNCTION_DESC_HANDLE funcDesc):
27732793 return func_desc
27742794
27752795
2776- cdef wrapResult (
2796+ cdef functionContainerGet (
27772797 RFC_FUNCTION_DESC_HANDLE funcDesc,
27782798 RFC_FUNCTION_HANDLE container,
27792799 RFC_DIRECTION filter_parameter_direction,
2780- config
2800+ unsigned config
27812801 ):
27822802 """
27832803 :param funcDesc: a C pointer to a function description.
@@ -2826,7 +2846,7 @@ cdef wrapUnitAttributes(RFC_UNIT_ATTRIBUTES *uattr):
28262846 unit_attributes[' sending_time' ] = wrapString(uattr.sendingTime, 6 , True )
28272847 return unit_attributes
28282848
2829- cdef wrapStructure(RFC_TYPE_DESC_HANDLE typeDesc, RFC_STRUCTURE_HANDLE container, config):
2849+ cdef wrapStructure(RFC_TYPE_DESC_HANDLE typeDesc, RFC_STRUCTURE_HANDLE container, unsigned config):
28302850 cdef unsigned i, fieldCount
28312851 cdef RFC_FIELD_DESC fieldDesc
28322852 RfcGetFieldCount(typeDesc, & fieldCount, NULL )
@@ -2857,7 +2877,7 @@ cdef wrapStructure(RFC_TYPE_DESC_HANDLE typeDesc, RFC_STRUCTURE_HANDLE container
28572877# RfcMoveTo(self.container, i, &errorInfo)
28582878# return wrapStructure(self.typeDesc, self.container)
28592879
2860- cdef wrapTable(RFC_TYPE_DESC_HANDLE typeDesc, RFC_TABLE_HANDLE container, config):
2880+ cdef wrapTable(RFC_TYPE_DESC_HANDLE typeDesc, RFC_TABLE_HANDLE container, unsigned config):
28612881 cdef RFC_ERROR_INFO errorInfo
28622882 cdef unsigned rowCount
28632883 # # For debugging in tables (cf. class TableCursor)
@@ -2880,7 +2900,7 @@ cdef wrapVariable(
28802900 SAP_UC* cName,
28812901 unsigned cLen,
28822902 RFC_TYPE_DESC_HANDLE typeDesc,
2883- config
2903+ unsigned config
28842904 ):
28852905 cdef RFC_RC rc
28862906 cdef RFC_ERROR_INFO errorInfo
0 commit comments