SendMail Fails in 6.02 from ISAPI DLL.

Post bugreports for the Windows version here
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

SendMail Fails in 6.02 from ISAPI DLL.

Post by swhite »

Hi

When I try to send an email from an ISAPI dll using version 6.02 64bit it fails (i.e. SendMail returns 0). If I re-compile my dll using version 5.73 64 bit it works correctly.

Simon
Simon White
dCipher Computing
Fred
Administrator
Administrator
Posts: 16619
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: SendMail Fails in 6.02 from ISAPI DLL.

Post by Fred »

Any chance to get a snippet to test?
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: SendMail Fails in 6.02 from ISAPI DLL.

Post by swhite »

Hi

I will strip down my dll to just the email function so you can have a working file. It may take me several days before I can do that as I have other work that must be done.

Simon
Simon White
dCipher Computing
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: SendMail Fails in 6.02 from ISAPI DLL.

Post by swhite »

Hi Fred

Here is my stripped down ISAPI extension. I use POSTMan to POST my requests (http://myhost/test.pb). I use a script map (*.pb) to trigger it to send an email. It works fine with PB v5.73 but fails using PB v6.02.

Code: Select all

;  dCFusionREST_Test.dll - FusionPro REST API Test
EnableExplicit
#dC_HeaderBufSize       = 512
#dC_StatusBufSize       = 512
#dCRXBufLen             = 5000
#dCSMTPHost            = "?" ; My host is a SendGrid but I cannot supply my credentials so you will have to use another host.
#dCSMTPPwd             = "?"
#dCSMTPUsr             = "?"
#dCSMTPPort            = 465
#dCSMTPSSL             = #PB_Mail_UseSSL
#dCLogFile             ="c:\tmp\dCFusionRest_Test.log" ; This is my log file which you can change.
#dC_DateTimeFmt        = "%yyyy-%mm-%dd %hh:%ii:%ss"

;===========================Freak's ISAPI_U.pbi===========================

Macro MAKELONG(a, b) : ((a & $FFFF) + b << 16) : EndMacro

#HSE_VERSION_MAJOR                                            = 8
#HSE_VERSION_MINOR                                            = 0
#HSE_LOG_BUFFER_LEN                                           = 80
#HSE_MAX_EXT_DLL_NAME_LEN                                     = 256
#HSE_VERSION                                                  = MAKELONG(#HSE_VERSION_MINOR, #HSE_VERSION_MAJOR)

#HSE_STATUS_SUCCESS                                           = 1
#HSE_STATUS_SUCCESS_AND_KEEP_CONN                             = 2
#HSE_STATUS_PENDING                                           = 3
#HSE_STATUS_ERROR                                             = 4

#HSE_REQ_BASE                                                 = 0
#HSE_REQ_SEND_URL_REDIRECT_RESP                               = (#HSE_REQ_BASE + 1)
#HSE_REQ_SEND_URL                                             = (#HSE_REQ_BASE + 2)
#HSE_REQ_SEND_RESPONSE_HEADER                                 = (#HSE_REQ_BASE + 3)
#HSE_REQ_DONE_WITH_SESSION                                    = (#HSE_REQ_BASE + 4)
#HSE_REQ_END_RESERVED                                         = 1000

#HSE_REQ_MAP_URL_TO_PATH                                      = (#HSE_REQ_END_RESERVED + 1)
#HSE_REQ_GET_SSPI_INFO                                        = (#HSE_REQ_END_RESERVED + 2)
#HSE_APPEND_LOG_PARAMETER                                     = (#HSE_REQ_END_RESERVED + 3)
#HSE_REQ_IO_COMPLETION                                        = (#HSE_REQ_END_RESERVED + 5)
#HSE_REQ_TRANSMIT_FILE                                        = (#HSE_REQ_END_RESERVED + 6)
#HSE_REQ_REFRESH_ISAPI_ACL                                    = (#HSE_REQ_END_RESERVED + 7)
#HSE_REQ_IS_KEEP_CONN                                         = (#HSE_REQ_END_RESERVED + 8)
#HSE_REQ_ASYNC_READ_CLIENT                                    = (#HSE_REQ_END_RESERVED + 10)
#HSE_REQ_GET_IMPERSONATION_TOKEN                              = (#HSE_REQ_END_RESERVED + 11)
#HSE_REQ_MAP_URL_TO_PATH_EX                                   = (#HSE_REQ_END_RESERVED + 12)
#HSE_REQ_ABORTIVE_CLOSE                                       = (#HSE_REQ_END_RESERVED + 14)
#HSE_REQ_GET_CERT_INFO_EX                                     = (#HSE_REQ_END_RESERVED + 15)
#HSE_REQ_SEND_RESPONSE_HEADER_EX                              = (#HSE_REQ_END_RESERVED + 16)
#HSE_REQ_CLOSE_CONNECTION                                     = (#HSE_REQ_END_RESERVED + 17)
#HSE_REQ_IS_CONNECTED                                         = (#HSE_REQ_END_RESERVED + 18)
#HSE_REQ_MAP_UNICODE_URL_TO_PATH                              = (#HSE_REQ_END_RESERVED + 23)
#HSE_REQ_MAP_UNICODE_URL_TO_PATH_EX                           = (#HSE_REQ_END_RESERVED + 24)
#HSE_REQ_EXEC_UNICODE_URL                                     = (#HSE_REQ_END_RESERVED + 25)
#HSE_REQ_EXEC_URL                                             = (#HSE_REQ_END_RESERVED + 26)
#HSE_REQ_GET_EXEC_URL_STATUS                                  = (#HSE_REQ_END_RESERVED + 27)
#HSE_REQ_SEND_CUSTOM_ERROR                                    = (#HSE_REQ_END_RESERVED + 28)
#HSE_REQ_IS_IN_PROCESS                                        = (#HSE_REQ_END_RESERVED + 30)
#HSE_REQ_REPORT_UNHEALTHY                                     = (#HSE_REQ_END_RESERVED + 32)
#HSE_REQ_NORMALIZE_URL                                        = (#HSE_REQ_END_RESERVED + 33)
#HSE_REQ_VECTOR_SEND                                          = (#HSE_REQ_END_RESERVED + 37)
#HSE_REQ_GET_ANONYMOUS_TOKEN                                  = (#HSE_REQ_END_RESERVED + 38)
#HSE_REQ_GET_CACHE_INVALIDATION_CALLBACK                      = (#HSE_REQ_END_RESERVED + 40)
#HSE_REQ_GET_UNICODE_ANONYMOUS_TOKEN                          = (#HSE_REQ_END_RESERVED + 41)
#HSE_REQ_GET_TRACE_INFO                                       = (#HSE_REQ_END_RESERVED + 42)
#HSE_REQ_SET_FLUSH_FLAG                                       = (#HSE_REQ_END_RESERVED + 43)
#HSE_REQ_GET_TRACE_INFO_EX                                    = (#HSE_REQ_END_RESERVED + 44)
#HSE_REQ_RAISE_TRACE_EVENT                                    = (#HSE_REQ_END_RESERVED + 45)
#HSE_REQ_GET_CONFIG_OBJECT                                    = (#HSE_REQ_END_RESERVED + 46)
#HSE_REQ_GET_WORKER_PROCESS_SETTINGS                          = (#HSE_REQ_END_RESERVED + 47)
#HSE_REQ_GET_PROTOCOL_MANAGER_CUSTOM_INTERFACE_CALLBACK       = (#HSE_REQ_END_RESERVED + 48)
#HSE_REQ_CANCEL_IO                                            = (#HSE_REQ_END_RESERVED + 49)
#HSE_REQ_GET_CHANNEL_BINDING_TOKEN                            = (#HSE_REQ_END_RESERVED + 50)

#HSE_TERM_ADVISORY_UNLOAD                                     = $00000001
#HSE_TERM_MUST_UNLOAD                                         = $00000002

#HSE_IO_SYNC                                                  = $00000001
#HSE_IO_ASYNC                                                 = $00000002
#HSE_IO_DISCONNECT_AFTER_SEND                                 = $00000004
#HSE_IO_SEND_HEADERS                                          = $00000008
#HSE_IO_NODELAY                                               = $00001000

#HSE_IO_FINAL_SEND                                            = $00000010
#HSE_IO_CACHE_RESPONSE                                        = $00000020
#HSE_IO_TRY_SKIP_CUSTOM_ERRORS                                = $00000040

#HSE_URL_FLAGS_READ                                           = $00000001
#HSE_URL_FLAGS_WRITE                                          = $00000002
#HSE_URL_FLAGS_EXECUTE                                        = $00000004
#HSE_URL_FLAGS_SSL                                            = $00000008
#HSE_URL_FLAGS_DONT_CACHE                                     = $00000010
#HSE_URL_FLAGS_NEGO_CERT                                      = $00000020
#HSE_URL_FLAGS_REQUIRE_CERT                                   = $00000040
#HSE_URL_FLAGS_MAP_CERT                                       = $00000080
#HSE_URL_FLAGS_SSL128                                         = $00000100
#HSE_URL_FLAGS_SCRIPT                                         = $00000200

#HSE_URL_FLAGS_MASK                                           = $000003ff

#HSE_EXEC_URL_NO_HEADERS                                      = $02
#HSE_EXEC_URL_IGNORE_CURRENT_INTERCEPTOR                      = $04
#HSE_EXEC_URL_IGNORE_VALIDATION_AND_RANGE                     = $10
#HSE_EXEC_URL_DISABLE_CUSTOM_ERROR                            = $20
#HSE_EXEC_URL_SSI_CMD                                         = $40
#HSE_EXEC_URL_HTTP_CACHE_ELIGIBLE                             = $80

#HSE_VECTOR_ELEMENT_TYPE_MEMORY_BUFFER                        = 0
#HSE_VECTOR_ELEMENT_TYPE_FILE_HANDLE                          = 1

#HSE_APP_FLAG_IN_PROCESS                                      = 0
#HSE_APP_FLAG_ISOLATED_OOP                                    = 1
#HSE_APP_FLAG_POOLED_OOP                                      = 2

Structure _HSE_VERSION_INFO
  dwExtensionVersion.l
  lpszExtensionDesc.a[#HSE_MAX_EXT_DLL_NAME_LEN]
EndStructure

Prototype GetServerVariable(hConn, *lpszVariableName, *lpvBuffer, *lpdwSize)
Prototype WriteClient(ConnID, *Buffer, *lpdwBytes, dwReserved.l)
Prototype ReadClient(ConnID, *lpvBuffer, *lpdwSize)
Prototype ServerSupportFunction(hConn, dwHSERequest.l, *lpvBuffer, *lpdwSize, *lpdwDataType)

Structure _EXTENSION_CONTROL_BLOCK
  cbSize.l
  dwVersion.l
  ConnID.i
  dwHttpStatusCode.l
  lpszLogData.a[#HSE_LOG_BUFFER_LEN]
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    padding.l
  CompilerEndIf
  *lpszMethod
  *lpszQueryString
  *lpszPathInfo
  *lpszPathTranslated
  cbTotalBytes.l
  cbAvailable.l
  *lpbData
  *lpszContentType
  GetServerVariable.GetServerVariable
  WriteClient.WriteClient
  ReadClient.ReadClient
  ServerSupportFunction.ServerSupportFunction
EndStructure

Structure _HSE_URL_MAPEX_INFO
  lpszPath.a[#MAX_PATH]
  dwFlags.l
  cchMatchingPath.l
  cchMatchingURL.l
  dwReserved1.l
  dwReserved2.l
EndStructure

Structure _HSE_UNICODE_URL_MAPEX_INFO
  lpszPath.u[#MAX_PATH]
  dwFlags.l
  cchMatchingPath.l
  cchMatchingURL.l
EndStructure

Prototype PFN_HSE_IO_COMPLETION(*pECB._EXTENSION_CONTROL_BLOCK, *pContect, cbIO.l, dwError.l)

Structure _HSE_TF_INFO
  pfnHseIO.PFN_HSE_IO_COMPLETION
  *pContext
  hFile.i
  *pszStatusCode
  BytesToWrite.l
  Offset.l
  *pHead
  HeadLength.l
  *pTail
  TailLength.l
  dwFlags.l
EndStructure

Structure _HSE_SEND_HEADER_EX_INFO
  *pszStatus
  *pszHeader
  cchStatus.l
  cchHeader.l
  fKeepConn.l
EndStructure

Structure _HSE_EXEC_URL_USER_INFO
  hImpersonationToken.i
  *pszCustomUserName
  *pszCustomAuthType
EndStructure

Structure _HSE_EXEC_URL_ENTITY_INFO
  cbAvailable.l
  *lpbData
EndStructure

Structure _HSE_EXEC_URL_STATUS
  uHttpStatusCode.u
  uHttpSubStatus.u
  dwWin32Error.l
EndStructure

Structure _HSE_EXEC_URL_INFO
  *pszUrl
  *pszMethod
  *pszChildHeaders
  *pUserInfo._HSE_EXEC_URL_USER_INFO
  *pEntity._HSE_EXEC_URL_ENTITY_INFO
  dwExecUrlFlags.l
EndStructure

Structure _HSE_EXEC_UNICODE_URL_USER_INFO
  hImpersonationToken.i
  *pszCustomUserName
  *pszCustomAuthType
EndStructure

Structure _HSE_EXEC_UNICODE_URL_INFO
  *pszUrl
  *pszMethod
  *pszChildHeaders
  *pUserInfo.HSE_EXEC_UNICODE_URL_USER_INFO
  *pEntity.HSE_EXEC_URL_ENTITY_INFO
  dwExecUrlFlags.l
EndStructure

Structure _HSE_CUSTOM_ERROR_INFO
  pszStatus.a
  uHttpSubError.u
  fAsync.l
EndStructure

Structure _HSE_VECTOR_ELEMENT
  ElementType.l
  *pvContext
  cbOffset.q
  cbSize.q
EndStructure

Structure _HSE_RESPONSE_VECTOR
  dwFlags.l
  *pszStatus
  *pszHeaders
  nElementCount.l
  *lpElementArray.HSE_VECTOR_ELEMENT
EndStructure

Structure _HSE_TRACE_INFO
  fTraceRequest.l
  TraceContextId.b[16]
  dwReserved1.l
  dwReserved2.l
EndStructure

Prototype PFN_HSE_CACHE_INVALIDATION_CALLBACK(*pszUrl)
Prototype PFN_HSE_GET_PROTOCOL_MANAGER_CUSTOM_INTERFACE_CALLBACK(*pszProtocolManagerDll, *pszProtocolManagerDllInitFunction,dwCustomInterfaceId.l, *ppCustomInterface)

;======================================

Procedure.i WriteToLog(tcText.s,tcLogFile.s=#dCLogFile,tnLog.i=1)
   If IsFile(2) Or OpenFile(2,tcLogFile,#PB_File_SharedRead | #PB_File_SharedWrite | #PB_File_Append | #PB_Ascii)
      WriteStringN(2, FormatDate(#dC_DateTimeFmt, Date())+" "+tcText,#PB_Ascii)
      FlushFileBuffers(2)
   EndIf
   ProcedureReturn 1
EndProcedure
Procedure eHandler()
   Select ErrorCode()
      Case #PB_OnError_InvalidMemory
         WriteToLog("Error: Invalid Memory Location on line "+Str(ErrorLine())+" in "+ErrorFile())
      Case #PB_OnError_Floatingpoint
         WriteToLog("Error: Floating-point error on line "+Str(ErrorLine()))
      Case #PB_OnError_Breakpoint
         WriteToLog("Error: Debugger breakpoint reached (non-PureBasic breakpoints) on line "+Str(ErrorLine())+" in "+ErrorFile())
      Case #PB_OnError_IllegalInstruction
         WriteToLog("Error: Attempt To execute an illegal instruction on line "+Str(ErrorLine())+" in "+ErrorFile())
      Case #PB_OnError_PriviledgedInstruction
         WriteToLog("Attempt To execute a privileged (system-) instruction on line "+Str(ErrorLine())+" in "+ErrorFile())
      Case #PB_OnError_DivideByZero
         WriteToLog("Error: Division by zero on line "+Str(ErrorLine())+" in "+ErrorFile())
      Default
         WriteToLog("Error : "+Hex(ErrorCode(),#PB_Long)+" on line "+Str(ErrorLine())+" in "+ErrorFile())
   EndSelect
EndProcedure

Procedure.s SendeMail(tcMsg.s)
   If CreateMail(1,"test@dciphercomputing.com","FusionPro ISAPI Error - "+ComputerName())
      AddMailRecipient(1,"simonwhite@dciphercomputing.com",#PB_Mail_Cc)
      SetMailBody(1,tcMsg)
      If SendMail(1,#dCSMTPHost,#dCSMTPPort,#dCSMTPSSL,#dCSMTPUsr,#dCSMTPPwd)
         WriteToLog("The message was sent successfully")
         ProcedureReturn ~"{\"msg\":\"The message was sent successfully\"}"
      Else
         WriteToLog("The message was NOT sent successfully")
         ProcedureReturn ~"{\"msg\":\"The message was NOT sent successfully\"}"
      EndIf
      FreeMail(1)
   Else
      WriteToLog("CreateMail failed")
      ProcedureReturn ~"{\"msg\":\"CreateMail failed\"}"
   EndIf
EndProcedure
ProcedureDLL GetExtensionVersion(*pver._HSE_VERSION_INFO)
   
   *pver\dwExtensionVersion = #HSE_VERSION                        ; set the version info 
   PokeS(@*pver\lpszExtensionDesc, "ISAPI extension ver. "+FormatDate("%yyyy.%mm.%dd,%hh.%ii",#PB_Compiler_Date)+" in PureBasic", -1, #PB_Ascii)
   ProcedureReturn #True  ; return success. returning False will cause the dll to be unloaded again
EndProcedure

Procedure SetHeader(*Header._HSE_SEND_HEADER_EX_INFO,*HBuf,tcName.s,tcValue.s)
   *Header\cchHeader = StringByteLength(tcName+": "+tcValue,#PB_Ascii) + 2
   PokeS(*HBuf,tcName+": "+tcValue + #CRLF$,*Header\cchHeader, #PB_Ascii)      
EndProcedure
Procedure AddHeader(*Header._HSE_SEND_HEADER_EX_INFO,*HBuf,tcName.s,tcValue.s)
   Define ln.i
   ln = StringByteLength(tcName+": "+tcValue,#PB_Ascii) + 2
   PokeS(*HBuf + *Header\cchHeader, tcName+": "+tcValue + #CRLF$,ln, #PB_Ascii)      
   *Header\cchStatus + ln
EndProcedure
Procedure EndHeader(*Header._HSE_SEND_HEADER_EX_INFO,*HBuf)
   PokeS(*HBuf + *Header\cchHeader,#CRLF$,2, #PB_Ascii)      
   *Header\cchStatus + 2
EndProcedure
Procedure SetStatus(*Header._HSE_SEND_HEADER_EX_INFO,*SBuf,tcStatus.s)
   *Header\cchStatus = StringByteLength(tcStatus,#PB_Ascii)
   PokeS(*SBuf,tcStatus,*Header\cchStatus,#PB_Ascii)
EndProcedure
Procedure.s ServerVariable(*pECB._EXTENSION_CONTROL_BLOCK, tcName.s)
   Define lcVal.s,lnSize.i,*rxBuffer,*Ascii
   lnSize = #dCRXBufLen
   *rxBuffer = AllocateMemory(lnSize)
   *Ascii = Ascii(tcName)
   lcVal = ""
   If *pECB\GetServerVariable(*pECB\ConnID,*Ascii,*rxBuffer,@lnSize) = #True
      lcVal = PeekS(*rxBuffer, lnSize,#PB_Ascii)
   EndIf
   FreeMemory(*rxBuffer)
   FreeMemory(*Ascii)
   ProcedureReturn lcVal
EndProcedure   
; This is the main function that is called for each client request
; *pECB contains all needed data
;
ProcedureDLL HttpExtensionProc(*pECB._EXTENSION_CONTROL_BLOCK)
   
   Define lcJSON.s,lnLen.i,*Ascii,*Header,*Status
   Define Header._HSE_SEND_HEADER_EX_INFO
   
   WriteToLog("HTTPExtensionProc "+ServerVariable(*pECB,"REMOTE_ADDR"))
   
   
   ;
   ; Send the response header with the ServerSupportFunction() callback
   ;       
   Header._HSE_SEND_HEADER_EX_INFO
   *Status = AllocateMemory(#dC_StatusBufSize) 
   *Header = AllocateMemory(#dC_HeaderBufSize)
   Header\pszStatus = *Status
   Header\pszHeader = *Header
   SetStatus(@Header,*Status, "200 OK")
   SetHeader(@Header,*Header, "Content-Type","application/json")
   
   Header\fKeepConn = 0 
   
   
   lcJSON=SendeMail("This is a test message from PB version "+#PB_Compiler_Version)
   
   EndHeader(@Header,*Header)
   *pECB\ServerSupportFunction(*pECB\ConnID, #HSE_REQ_SEND_RESPONSE_HEADER_EX, @Header, 0, 0)
   
   WriteToLog(lcJSON)
   
   ;
   ; Send the html data with the WriteClient() callback:
   ;
   lnLen = StringByteLength(lcJSON,#PB_Ascii)
   *Ascii = Ascii(lcJSON)
   *pECB\WriteClient(*pECB\ConnID,*Ascii, @lnLen, 0)
   FreeMemory(*Ascii)
   FreeMemory(*Header)
   FreeMemory(*Status)
   ProcedureReturn #HSE_STATUS_SUCCESS
EndProcedure
;
; TerminateExtension is called before unloading the dll.
;
ProcedureDLL TerminateExtension(dwFlags)
   ProcedureReturn #True
EndProcedure
ProcedureDLL AttachProcess(Instance)
   OnErrorCall(@EHandler())
      
   SetCurrentDirectory(GetPathPart(ProgramFilename()))
   WriteToLog("AttachProcess("+GetCurrentDirectory()+"dCFusionREST_Test.dll ver. "+FormatDate("%yyyy.%mm.%dd.%hh.%ii",#PB_Compiler_Date)+" loaded successfully.)")
   
EndProcedure

Simon White
dCipher Computing
Fred
Administrator
Administrator
Posts: 16619
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: SendMail Fails in 6.02 from ISAPI DLL.

Post by Fred »

Could you try to use #PB_Mail_UseSMTPS instead of #PB_Mail_SSL or a combination of both (#PB_Mail_UseSMTPS | #PB_Mail_SSL) ?
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: SendMail Fails in 6.02 from ISAPI DLL.

Post by swhite »

Hi Fred

Sorry for the late response but I missed the fact that you had replied to this message.

I tried both #PB_Mail_UseSMTPS | #PB_Mail_UseSSL and #PB_Mail_UseSMTPS but in both cases the email was not sent.

Simon
Simon White
dCipher Computing
swhite
Enthusiast
Enthusiast
Posts: 726
Joined: Thu May 21, 2009 6:56 pm

Re: SendMail Fails in 6.02 from ISAPI DLL.

Post by swhite »

Hi Fred

Is there anything more you would like me to test?

Simon
Simon White
dCipher Computing
Post Reply