METHOD WriteFromFile( cFile ) CLASS tIPClient
LOCAL nFin
LOCAL cData
LOCAL nLen
LOCAL nSize, nSent, nBufSize
::nWrite := 0
::nStatus := 0
nFin := FOpen( cFile, FO_READ )
IF nFin < 0
RETURN .F.
ENDIF
nSize := FSeek( nFin, 0, FS_END )
FSeek( nFin, 0 )
nBufSize := SND_BUF_SIZE
// allow initialization of the gauge
nSent := 0
IF ! Empty( ::exGauge )
hb_ExecFromArray( ::exGauge, { nSent, nSize, Self } )
ENDIF
::nStatus := 1
cData := Space( nBufSize )
nLen := FRead( nFin, @cData, nBufSize )
DO WHILE nLen > 0
IF ::Write( @cData, nLen ) != nLen
FClose( nFin )
RETURN .F.
ENDIF
nSent += nLen
IF ! Empty( ::exGauge )
hb_ExecFromArray( ::exGauge, {nSent, nSize, Self} )
ENDIF
nLen := FRead( nFin, @cData, nBufSize )
/* 14-04-2012 javier lloris, añado el SysRefresh() para intentar evitar el "no responde" */
SysRefresh()
ENDDO
// it may happen that the file has length 0
IF nSent > 0
::Commit()
ENDIF
::nStatus := 2
FClose( nFin )
RETURN .T.
METHOD Write( cData, nLen, bCommit ) CLASS tIPClient
IF Empty( nLen )
nLen := Len( cData )
ENDIF
::nLastWrite := ::InetSendall( ::SocketCon, cData, nLen )
IF ! Empty( bCommit ) .AND. bCommit
::Commit()
ENDIF
::nWrite += ::nLastWrite
RETURN ::nLastWrite
/*
* $Id: client.prg 15233 2010-07-30 07:56:36Z vszakats $
*/
/*
* xHarbour Project source code:
* TIP Class oriented Internet protocol library
*
* Copyright 2003 Giancarlo Niccolai <gian@niccolai.ws>
* Copyright 2009 Viktor Szakats (harbour.01 syenar.hu) (SSL support)
* www - http://harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
*
* As a special exception, the Harbour Project gives permission for
* additional uses of the text contained in its release of Harbour.
*
* The exception is that, if you link the Harbour libraries with other
* files to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the Harbour library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the Harbour
* Project under the name Harbour. If you copy code from other
* Harbour Project or Free Software Foundation releases into a copy of
* Harbour, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for Harbour, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice.
*
*/
/* 2004-01-13
Enhanced tip cliente to conenct to secure smtp servers by Luiz Rafael Culik
2007-03-29, Hannes Ziegler
Adapted all :new() method(s) so that tIPClient becomes the
abstract super class for TIpClientFtp, TIpClientHttp, TIpClientPop and TIpClientSmtp
Added Methods :INetErrorDesc(), :lastErrorCode() and :lastErrorMessage()
Removed method :data() since it calls an undeclared method :getOk()
:data() is used in TIpClientSmtp
Fixed bug in :readToFile()
2007-06-01, Toninho@fwi
Added data ::nWrite to work like ::nRead
2009-06-29, Luiz Rafael Culik (luiz at xharbour dot com dot br)
Added support for proxy connection
*/
#INCLUDE "FiveWin.ch"
#include "hbclass.ch"
#include "common.ch"
#include "error.ch"
#include "fileio.ch"
#if defined( _SSL_DEBUG_TEMP )
#include "simpleio.ch"
#endif
#if defined( HB_HAS_OPENSSL )
#include "hbssl.ch"
#endif
#define RCV_BUF_SIZE Int( ::InetRcvBufSize( ::SocketCon ) / 2 )
#define SND_BUF_SIZE Int( ::InetSndBufSize( ::SocketCon ) / 2 )
/**
* Inet Client class
*/
CREATE CLASS tIPClient
CLASSDATA bInitSocks INIT .F.
CLASSDATA cCRLF INIT tip_CRLF()
VAR oUrl /* url to wich to connect */
VAR oCredentials /* credential needed to access the service */
VAR nStatus INIT 0 /* basic status */
VAR SocketCon
VAR bTrace
VAR nDefaultRcvBuffSize
VAR nDefaultSndBuffSize
VAR nLength INIT -1 /* Input stream length */
VAR nRead INIT 0 /* Input stream data read by the app*/
VAR nLastRead INIT 0 /* Last physical read amount */
VAR nDefaultPort
VAR nConnTimeout
VAR bInitialized INIT .F.
VAR cReply
VAR nAccessMode
VAR nWrite INIT 0
VAR nLastWrite INIT 0
VAR bEof INIT .F.
VAR isOpen INIT .F.
VAR exGauge /* Gauge control; it can be a codeblock or a function pointer. */
VAR lTLS INIT .F.
#if defined( HB_HAS_OPENSSL )
VAR ssl_ctx
VAR ssl
VAR nSSLError INIT 0
#endif
VAR Cargo
/* Data for proxy connection */
VAR cProxyHost
VAR nProxyPort INIT 0
VAR cProxyUser
VAR cProxyPassword
METHOD New( oUrl, bTrace, oCredentials )
METHOD Open( cUrl )
METHOD EnableTLS( lEnable )
METHOD Read( nLen )
METHOD ReadToFile( cFile, nMode, nSize )
METHOD Write( cData, nLen, bCommit )
METHOD Commit()
METHOD WriteFromFile( cFile )
METHOD Reset()
METHOD Close()
/* METHOD Data( cData ) */ // commented: calls undeclared METHOD :getOk
METHOD SetProxy( cProxyHost, nProxyPort, cProxyUser, cProxyPassword )
METHOD lastErrorCode() INLINE ::nLastError
METHOD lastErrorMessage( SocketCon ) INLINE ::INetErrorDesc( SocketCon )
METHOD InetRcvBufSize( SocketCon, nSizeBuff )
METHOD InetSndBufSize( SocketCon, nSizeBuff )
METHOD InetTimeOut( SocketCon, nConnTimeout )
PROTECTED:
VAR nLastError INIT 0
METHOD OpenProxy( cServer, nPort, cProxy, nProxyPort, cResp, cUserName, cPassWord, cUserAgent )
METHOD ReadHTTPProxyResponse( sResponse )
/* Methods to log data if needed */
METHOD InetRecv( SocketCon, cStr1, len)
METHOD InetRecvLine( SocketCon, nRet, size )
METHOD InetRecvAll( SocketCon, cRet, size )
METHOD InetCount( SocketCon )
METHOD InetSendAll( SocketCon, cData, nLen )
METHOD InetErrorCode( SocketCon )
METHOD InetErrorDesc( SocketCon )
METHOD InetConnect( cServer, nPort, SocketCon )
METHOD Log( ... )
ENDCLASS
METHOD New( oUrl, bTrace, oCredentials ) CLASS tIPClient
LOCAL oErr
LOCAL aProtoAccepted := { "ftp", "http", "pop", "smtp" }
#if defined( HB_HAS_OPENSSL )
LOCAL aProtoAcceptedSSL := { "ftps", "https", "pop3s", "pop3", "smtps" }
#else
LOCAL aProtoAcceptedSSL := {}
#endif
IF ISCHARACTER( oUrl )
oUrl := tUrl():New( oUrl )
ENDIF
IF AScan( aProtoAccepted , {| tmp | tmp == oURL:cProto } ) == 0 .AND. ;
AScan( aProtoAcceptedSSL, {| tmp | tmp == oURL:cProto } ) == 0
oErr := ErrorNew()
oErr:Args := { Self, oURL:cProto }
oErr:CanDefault := .F.
oErr:CanRetry := .F.
oErr:CanSubstitute := .T.
oErr:Description := "unsupported protocol"
oErr:GenCode := EG_UNSUPPORTED
oErr:Operation := ::className() + ":new()"
oErr:Severity := ES_ERROR
oErr:SubCode := 1081
oErr:SubSystem := "BASE"
Eval( ErrorBlock(), oErr )
ENDIF
IF ! ::bInitSocks
hb_inetInit()
#if defined( HB_HAS_OPENSSL )
SSL_init()
RAND_seed( Time() + hb_username() + DToS( Date() ) + hb_DirBase() + NetName() )
#endif
::bInitSocks := .T.
ENDIF
#if defined( HB_HAS_OPENSSL )
IF oURL:cProto == "ftps" .OR. ;
oURL:cProto == "https" .OR. ;
oURL:cProto == "pop3s" .OR. oURL:cProto == "pops" .OR. ;
oURL:cProto == "smtps"
::EnableTLS( .T. )
ENDIF
#endif
::oUrl := oUrl
::oCredentials := oCredentials
::bTrace := bTrace
RETURN self
METHOD Open( cUrl ) CLASS tIPClient
LOCAL nPort
LOCAL cResp
IF ISCHARACTER( cUrl )
::oUrl := tUrl():New( cUrl )
ENDIF
IF ::oUrl:nPort == -1
nPort := ::nDefaultPort
ELSE
nPort := ::oUrl:nPort
ENDIF
::SocketCon := hb_inetCreate()
::InetTimeOut( ::SocketCon )
IF ! Empty( ::cProxyHost )
cResp := ""
IF ! ::OpenProxy( ::oUrl:cServer, nPort, ::cProxyHost, ::nProxyPort, @cResp, ::cProxyUser, ::cProxyPassword, "Mozilla/3.0 compatible" )
RETURN .F.
ENDIF
ELSE
::InetConnect( ::oUrl:cServer, nPort, ::SocketCon )
IF ::InetErrorCode( ::SocketCon ) != 0
RETURN .F.
ENDIF
ENDIF
::isOpen := .T.
RETURN .T.
METHOD EnableTLS( lEnable ) CLASS tIPClient
LOCAL lSuccess
IF ::lTLS == lEnable
RETURN .T.
ENDIF
#if defined( HB_HAS_OPENSSL )
IF lEnable
::ssl_ctx := SSL_CTX_new()
::ssl := SSL_new( ::ssl_ctx )
::lTLS := .T.
lSuccess := .T.
ELSE
::lTLS := .F.
lSuccess := .T.
ENDIF
#else
IF lEnable
lSuccess := .F.
ELSE
lSuccess := .T.
ENDIF
#endif
RETURN lSuccess
METHOD OpenProxy( cServer, nPort, cProxy, nProxyPort, cResp, cUserName, cPassWord, cUserAgent ) CLASS tIPClient
LOCAL cRequest
LOCAL lRet := .F.
LOCAL tmp
::InetConnect( cProxy, nProxyPort, ::SocketCon )
IF ( tmp := ::InetErrorCode( ::SocketCon ) ) == 0
cRequest := "CONNECT " + cServer + ":" + hb_ntos( nPort ) + " HTTP/1.1" + Chr( 13 ) + Chr( 10 )
IF ! Empty( cUserAgent )
cRequest += "User-agent: " + cUserAgent + Chr( 13 ) + Chr( 10 )
ENDIF
IF ! Empty( cUserName )
cRequest += "Proxy-authorization: Basic " + hb_base64Encode( cUserName + ":" + cPassWord ) + Chr( 13 ) + Chr( 10 )
ENDIF
cRequest += Chr( 13 ) + Chr( 10 )
::InetSendAll( ::SocketCon, cRequest )
cResp := ""
IF ::ReadHTTPProxyResponse( @cResp )
tmp := At( " ", cResp )
IF tmp > 0 .AND. Val( SubStr( cResp, tmp + 1 ) ) == 200
lRet := .T.
ENDIF
ENDIF
IF ! lRet
::close()
ENDIF
ELSE
cResp := hb_ntos( tmp )
lRet := .F.
ENDIF
RETURN lRet
METHOD ReadHTTPProxyResponse( /* @ */ sResponse ) CLASS tIPClient
LOCAL bMoreDataToRead := .T.
LOCAL nLength, nData
LOCAL szResponse
DO WHILE bMoreDataToRead
szResponse := Space( 1 )
nData := ::InetRecv( ::SocketCon, @szResponse, Len( szResponse ) )
IF nData == 0
RETURN .F.
ENDIF
sResponse += szResponse
nLength := Len( sResponse )
IF nLength >= 4
bMoreDataToRead := !( ( SubStr( sResponse, nLength - 3, 1 ) == Chr( 13 ) ) .AND. ( SubStr( sResponse, nLength - 2, 1 ) == Chr( 10 ) ) .AND. ;
( SubStr( sResponse, nLength - 1, 1 ) == Chr( 13 ) ) .AND. ( SubStr( sResponse, nLength, 1 ) == Chr( 10 ) ) )
ENDIF
ENDDO
RETURN .T.
METHOD Close() CLASS tIPClient
LOCAL nRet := -1
IF ! Empty( ::SocketCon )
nRet := hb_inetClose( ::SocketCon )
#if defined( HB_HAS_OPENSSL )
IF ::lTLS
SSL_shutdown( ::ssl )
::ssl := NIL
::ssl_ctx := NIL
ENDIF
#endif
::SocketCon := NIL
::isOpen := .F.
ENDIF
IF ISBLOCK( ::bTrace )
/* Call with no parameter to signal end of logging session */
Eval( ::bTrace )
ENDIF
RETURN nRet
METHOD Reset() CLASS tIPClient
::bInitialized := .F.
::bEof := .F.
RETURN .T.
METHOD Commit() CLASS tIPClient
RETURN .T.
METHOD Read( nLen ) CLASS tIPClient
LOCAL cStr0
LOCAL cStr1
IF ::nLength > 0 .AND. ::nLength == ::nRead
RETURN NIL
ENDIF
IF Empty( nLen ) .OR. nLen < 0 .OR. ( ::nLength > 0 .AND. nLen > ::nLength - ::nRead )
nLen := ::nLength - ::nRead
ENDIF
IF Empty( nLen ) .OR. nLen < 0
// read till end of stream
cStr1 := Space( RCV_BUF_SIZE )
cStr0 := ""
::nLastRead := ::InetRecv( ::SocketCon, @cStr1, RCV_BUF_SIZE )
DO WHILE ::nLastRead > 0
::nRead += ::nLastRead
cStr0 += Left( cStr1, ::nLastRead )
::nLastRead := ::InetRecv( ::SocketCon, @cStr1, RCV_BUF_SIZE )
ENDDO
::bEof := .T.
ELSE
// read an amount of data
cStr0 := Space( nLen )
IF ::lTLS
#if defined( HB_HAS_OPENSSL )
/* Getting around implementing the hack used in non-SSL branch for now.
IMO the proper fix would have been done to hb_inetRecvAll(). [vszakats] */
::nLastRead := ::InetRecvAll( ::SocketCon, @cStr0, nLen )
#endif
ELSE
// S.R. if len of file is less than RCV_BUF_SIZE hb_inetRecvAll return 0
// ::nLastRead := ::InetRecvAll( ::SocketCon, @cStr0, nLen )
::InetRecvAll( ::SocketCon, @cStr0, nLen )
::nLastRead := ::InetCount( ::SocketCon )
ENDIF
::nRead += ::nLastRead
IF ::nLastRead != nLen
::bEof := .T.
cStr0 := Left( cStr0, ::nLastRead )
// S.R. RETURN NIL
ENDIF
IF ::nRead == ::nLength
::bEof := .T.
ENDIF
ENDIF
RETURN cStr0
METHOD ReadToFile( cFile, nMode, nSize ) CLASS tIPClient
LOCAL nFout
LOCAL cData
LOCAL nSent
IF ! ISNUMBER( nMode )
nMode := FC_NORMAL
ENDIF
nSent := 0
IF ! Empty( ::exGauge )
hb_ExecFromArray( ::exGauge, { nSent, nSize, Self } )
ENDIF
::nRead := 0
::nStatus := 1
DO WHILE ::InetErrorCode( ::SocketCon ) == 0 .AND. ! ::bEof
cData := ::Read( RCV_BUF_SIZE )
IF cData == NIL
IF nFout != NIL
FClose( nFout )
ENDIF
RETURN ::InetErrorCode( ::SocketCon ) == 0
ENDIF
IF nFout == NIL
nFout := FCreate( cFile, nMode )
IF nFout < 0
::nStatus := 0
RETURN .F.
ENDIF
ENDIF
IF FWrite( nFout, cData ) < 0
FClose( nFout )
RETURN .F.
ENDIF
nSent += Len( cData )
IF ! Empty( ::exGauge )
hb_ExecFromArray( ::exGauge, { nSent, nSize, Self } )
ENDIF
ENDDO
IF nSent > 0
::Commit()
ENDIF
::nStatus := 2
FClose( nFout )
RETURN .T.
METHOD WriteFromFile( cFile ) CLASS tIPClient
LOCAL nFin
LOCAL cData
LOCAL nLen
LOCAL nSize, nSent, nBufSize
::nWrite := 0
::nStatus := 0
nFin := FOpen( cFile, FO_READ )
IF nFin < 0
RETURN .F.
ENDIF
nSize := FSeek( nFin, 0, FS_END )
FSeek( nFin, 0 )
nBufSize := SND_BUF_SIZE
// allow initialization of the gauge
nSent := 0
IF ! Empty( ::exGauge )
hb_ExecFromArray( ::exGauge, { nSent, nSize, Self } )
ENDIF
::nStatus := 1
cData := Space( nBufSize )
nLen := FRead( nFin, @cData, nBufSize )
DO WHILE nLen > 0
IF ::Write( @cData, nLen ) != nLen
FClose( nFin )
RETURN .F.
ENDIF
nSent += nLen
IF ! Empty( ::exGauge )
hb_ExecFromArray( ::exGauge, {nSent, nSize, Self} )
ENDIF
nLen := FRead( nFin, @cData, nBufSize )
/* 14-04-2012 javier lloris, añado el SysRefresh() para intentar evitar el "no responde" */
SysRefresh()
ENDDO
// it may happen that the file has length 0
IF nSent > 0
::Commit()
ENDIF
::nStatus := 2
FClose( nFin )
RETURN .T.
/*
HZ: METHOD :getOk() is not declared in tIPClient
METHOD Data( cData ) CLASS tIPClient
::InetSendall( ::SocketCon, "DATA" + ::cCRLF )
IF ! ::GetOk()
RETURN .F.
ENDIF
::InetSendall(::SocketCon, cData + ::cCRLF + "." + ::cCRLF )
RETURN ::GetOk()
*/
METHOD Write( cData, nLen, bCommit ) CLASS tIPClient
IF Empty( nLen )
nLen := Len( cData )
ENDIF
::nLastWrite := ::InetSendall( ::SocketCon, cData, nLen )
IF ! Empty( bCommit ) .AND. bCommit
::Commit()
ENDIF
::nWrite += ::nLastWrite
RETURN ::nLastWrite
METHOD InetSendAll( SocketCon, cData, nLen ) CLASS tIPClient
LOCAL nRet
IF Empty( nLen )
nLen := Len( cData )
ENDIF
IF ::lTLS
#if defined( HB_HAS_OPENSSL )
#if defined( _SSL_DEBUG_TEMP )
? "SSL_WRITE()", cData
#endif
nRet := SSL_write( ::ssl, cData, nLen )
::nSSLError := iif( nRet < 0, nRet, 0 )
#else
nRet := 0
#endif
ELSE
nRet := hb_inetSendAll( SocketCon, cData, nLen )
ENDIF
IF ISBLOCK( ::bTrace )
::Log( SocketCon, nlen, cData, nRet )
ENDIF
RETURN nRet
METHOD InetCount( SocketCon ) CLASS tIPClient
LOCAL nRet := hb_inetCount( SocketCon )
IF ISBLOCK( ::bTrace )
::Log( SocketCon, nRet )
ENDIF
RETURN nRet
METHOD InetRecv( SocketCon, cStr1, len ) CLASS tIPClient
LOCAL nRet
IF ::lTLS
#if defined( HB_HAS_OPENSSL )
#if defined( _SSL_DEBUG_TEMP )
? "SSL_READ()"
#endif
nRet := SSL_read( ::ssl, @cStr1, len )
::nSSLError := iif( nRet < 0, nRet, 0 )
#else
nRet := 0
#endif
ELSE
nRet := hb_inetRecv( SocketCon, @cStr1, len )
ENDIF
IF ISBLOCK( ::bTrace )
::Log( SocketCon, "", len, iif( nRet >= 0, cStr1, nRet ) )
ENDIF
RETURN nRet
METHOD InetRecvLine( SocketCon, nRet, size ) CLASS tIPClient
LOCAL cRet
IF ::lTLS
#if defined( HB_HAS_OPENSSL )
nRet := hb_SSL_read_line( ::ssl, @cRet, size, ::nConnTimeout )
#if defined( _SSL_DEBUG_TEMP )
? "HB_SSL_READ_LINE()", cRet
#endif
IF nRet == 0 .OR. Empty( cRet )
cRet := NIL
ENDIF
::nSSLError := iif( nRet < 0, nRet, 0 )
#else
cRet := ""
nRet := 0
#endif
ELSE
cRet := hb_inetRecvLine( SocketCon, @nRet, size )
ENDIF
IF ISBLOCK( ::bTrace )
::Log( SocketCon, "", size, cRet )
ENDIF
RETURN cRet
METHOD InetRecvAll( SocketCon, cRet, size ) CLASS tIPClient
LOCAL nRet
IF ::lTLS
#if defined( HB_HAS_OPENSSL )
nRet := hb_SSL_read_all( ::ssl, @cRet, size, ::nConnTimeout )
#if defined( _SSL_DEBUG_TEMP )
? "HB_SSL_READ_ALL()", cRet
#endif
IF nRet == 0 .OR. Empty( cRet )
cRet := NIL
ENDIF
::nSSLError := iif( nRet < 0, nRet, 0 )
#else
cRet := ""
nRet := 0
#endif
ELSE
nRet := hb_inetRecvAll( SocketCon, @cRet, size )
ENDIF
IF ISBLOCK( ::bTrace )
::Log( SocketCon, "", size, iif( nRet >= 0, cRet, nRet ) )
ENDIF
RETURN nRet
METHOD InetErrorCode( SocketCon ) CLASS tIPClient
LOCAL nRet
IF ::lTLS
#if defined( HB_HAS_OPENSSL )
nRet := iif( ::nSSLError == 0, 0, SSL_get_error( ::ssl, ::nSSLError ) )
#else
nRet := 0
#endif
ELSE
nRet := hb_inetErrorCode( SocketCon )
ENDIF
::nLastError := nRet
IF ISBLOCK( ::bTrace )
::Log( SocketCon, nRet )
ENDIF
RETURN nRet
METHOD InetErrorDesc( SocketCon ) CLASS tIPClient
LOCAL cMsg := ""
DEFAULT SocketCon TO ::SocketCon
IF ! Empty( SocketCon )
IF ::lTLS
#if defined( HB_HAS_OPENSSL )
IF ::nSSLError != 0
cMsg := ERR_error_string( SSL_get_error( ::ssl, ::nSSLError ) )
ENDIF
#endif
ELSE
cMsg := hb_inetErrorDesc( SocketCon )
ENDIF
ENDIF
RETURN cMsg
/* BROKEN, should test number of parameters and act accordingly, see doc\inet.txt */
METHOD InetConnect( cServer, nPort, SocketCon ) CLASS tIPClient
hb_inetConnect( cServer, nPort, SocketCon )
IF ! Empty( ::nDefaultSndBuffSize )
::InetSndBufSize( SocketCon, ::nDefaultSndBuffSize )
ENDIF
IF ! Empty( ::nDefaultRcvBuffSize )
::InetRcvBufSize( SocketCon, ::nDefaultRcvBuffSize )
ENDIF
#if defined( HB_HAS_OPENSSL )
IF ::lTLS
SSL_set_mode( ::ssl, HB_SSL_MODE_AUTO_RETRY )
SSL_set_fd( ::ssl, hb_inetFD( SocketCon ) )
SSL_connect( ::ssl )
/* TODO: Add error handling */
ENDIF
#endif
IF ISBLOCK( ::bTrace )
::Log( cServer, nPort, SocketCon )
ENDIF
RETURN NIL
/* Methods to manage buffers */
METHOD InetRcvBufSize( SocketCon, nSizeBuff ) CLASS tIPClient
IF ! Empty( nSizeBuff )
hb_inetSetRcvBufSize( SocketCon, nSizeBuff )
ENDIF
RETURN hb_inetGetRcvBufSize( SocketCon )
METHOD InetSndBufSize( SocketCon, nSizeBuff ) CLASS tIPClient
IF ! Empty( nSizeBuff )
hb_inetSetSndBufSize( SocketCon, nSizeBuff )
ENDIF
RETURN hb_inetGetSndBufSize( SocketCon )
METHOD InetTimeOut( SocketCon, nConnTimeout ) CLASS tIPClient
IF ISNUMBER( nConnTimeout )
::nConnTimeout := nConnTimeout
ENDIF
IF ISNUMBER( ::nConnTimeout )
RETURN hb_inetTimeout( SocketCon, ::nConnTimeout )
ENDIF
RETURN NIL
/* Called from another method with list of parameters and, as last parameter, return code
of function being logged.
Example, I want to log MyFunc( a, b, c ) which returns m,
::Log( a, b, c, m )
*/
METHOD Log( ... ) CLASS tIPClient
LOCAL xVar
LOCAL cMsg
IF ISBLOCK( ::bTrace )
cMsg := DToS( Date() ) + "-" + Time() + Space( 2 ) + ;
SubStr( ProcName( 1 ), RAt( ":", ProcName( 1 ) ) ) +;
"( "
FOR EACH xVar IN hb_AParams()
// Preserves CRLF on result
IF xVar:__enumIndex() < PCount()
cMsg += StrTran( StrTran( AllTrim( hb_CStr( xVar ) ), Chr( 13 ), "<cr>" ), Chr( 10 ), "<lf>" )
ELSE
cMsg += hb_CStr( xVar )
ENDIF
cMsg += iif( xVar:__enumIndex() < PCount() - 1, ", ", "" )
IF xVar:__enumIndex() == PCount() - 1
cMsg += " )" + hb_eol() + ">> "
ELSEIF xVar:__enumIndex() == PCount()
cMsg += " <<" + hb_eol() + hb_eol()
ENDIF
NEXT
Eval( ::bTrace, cMsg )
ENDIF
RETURN Self
METHOD SetProxy( cProxyHost, nProxyPort, cProxyUser, cProxyPassword ) CLASS tIPClient
::cProxyHost := cProxyHost
::nProxyPort := nProxyPort
::cProxyUser := cProxyUser
::cProxyPassword := cProxyPassword
RETURN Self
FUNCTION tip_SSL()
#if defined( HB_HAS_OPENSSL )
RETURN .T.
#else
RETURN .F.
#endif
while( iSent < iSend )
{
if( socket->sendFunc )
{
iLen = socket->sendFunc( socket->stream, socket->sd,
buffer + iSent, iSend - iSent,
socket->iTimeout, &lLastSnd );
if( lLastSnd <= 0 && iLen > 0 )
{
iSent += iLen;
iLen = ( int ) lLastSnd;
}
}
else
iLen = hb_socketSend( socket->sd, buffer + iSent, iSend - iSent,
0, socket->iTimeout );
if( iLen > 0 )
{
iSent += iLen;
if( ! lAll )
break;
}
else
{
hb_inetGetError( socket );
break;
}
}
Return to FiveWin para Harbour/xHarbour
Users browsing this forum: No registered users and 23 guests