Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

HTTP POST Method with Visual Objects

482 views
Skip to first unread message

Fred Killet

unread,
Mar 24, 2019, 1:26:58 PM3/24/19
to
Hallo,
ist es möglich mit Visual Objects Daten mit der HTTP POST Methode zu
einem Server zu schicken? Hat jemand ein Code-Beispiel?
Danke für die Mühe,
Fred

Hello,
is it possible to use Visual Objects to send data to a server using the
HTTP POST method? Does anyone have a code sample?
Thank you for the effort,
Fred

JohnMartens

unread,
Mar 24, 2019, 1:40:57 PM3/24/19
to
Norbert Kolb was my Guru for these kind of things. het shared his code
below in this group. I also includes other code from Bob McCutcheon that
I got in this NG.


I got XML data from a server using this call tot Norberts coes
oHttpXml := cHttp{"XML exchange"}
cPage := oHttpXml:GetDocumentByGetOrPost( cUrl,cFolder,"","","POST")

Hope it can help

John




METHOD GetDocumentByGetOrPost(cIP, cDocument, cData, cHeader, cMethod,
nP, nFlags) CLASS cHttp
***************************************
// GET or POST - that's the question
// Norbert Kolb, 11/17/03, 12/02/04, 09/02/04 02/25/05
// UG Bodensee (A, CH, D, FL)
***************************************
// First the InternetOpen function is called to initialize the
// remaining functions. Then the InternetConnect function is called
// to identify the type of service being requested. This is necessary
// as the same set of functions can be used to interact with a number
// of different servers.
***************************************
LOCAL lResult AS LOGIC
LOCAL nDataLen AS DWORD
LOCAL nBuffer AS DWORD
LOCAL nBufferLen AS DWORD
LOCAL cRet AS STRING

Default(@cDocument, "")
Default(@cData, "")
Default(@cMethod, "GET")
Default(@nP, SELF:nPort)
Default(@nFlags, 0)

IF _AND(DWORD(nFlags), INTERNET_FLAG_SECURE) = INTERNET_FLAG_SECURE
nP := INTERNET_DEFAULT_HTTPS_PORT
SELF:nPort := nP
ENDIF

IF SELF:hSession == NULL_PTR
lResult := SELF:Open(NIL, SELF:cProxy)
ELSE
lResult := .T.
ENDIF

IF lResult
// Identify the type of service that is being accessed
IF SELF:hConnect == NULL_PTR .OR. SELF:cHostAddress <> cIP
SELF:cHostAddress := cIP
SELF:hConnect := InternetConnect(SELF:hSession, ;
String2Psz(SELF:cHostAddress), ;
nP, ;
String2Psz(SELF:cUserName), ;
String2Psz(SELF:cPassword), ;
INTERNET_SERVICE_HTTP, ;
nFlags, ;
0)
ENDIF

IF SELF:hConnect <> NULL_PTR
SELF:__SetStatusObject()
// Once we've identified the service, we need to indicate the
// page to which the data will be posted. In this example, it will
// be "/getorpost.php"
SELF:hRequest := HttpOpenRequest(SELF:hConnect, ; // hConnect
String2Psz(cMethod), ; // lpszVerb
String2Psz(cDocument), ; // pszObjectName
String2Psz("HTTP/1.1"), ; // pszVersion
NULL_PSZ, ; // pszReferer
NULL_PSZ, ; // pszAcceptTypes
nFlags, ; // dwFlags
SELF:__GetStatusContext()) // dwContext

IF SELF:hRequest <> NULL_PTR
SELF:__SetStatus(SELF:hRequest)
// We need to add a header to notify the web server that the
// incoming data is form encoded and then send the request.
IF cMethod == "POST"
IF Empty(cHeader)
cHeader := "Content-Type: application/x-www-form-urlencoded" +
CrLf + HEADER_ACCEPT
ENDIF
ELSE
IF Empty(cHeader)
cHeader := HEADER_ACCEPT
ENDIF
ENDIF

IF HttpAddRequestHeaders(SELF:hRequest, ;
String2Psz(cHeader), ;
SLen(cHeader), ;
HTTP_ADDREQ_FLAG_ADD)

// Sometimes you have to set SECURITY_FLAGS
InternetQueryOption(SELF:hRequest, INTERNET_OPTION_SECURITY_FLAGS,
@nBuffer, @nBufferLen)
nBuffer := _OR(nBuffer, SECURITY_FLAG_IGNORE_UNKNOWN_CA)
InternetSetOption(SELF:hRequest, INTERNET_OPTION_SECURITY_FLAGS,
@nBuffer, nBufferLen)
nDataLen := SLen(cData)

IF HttpSendRequest(SELF:hRequest, ;
NULL, ;
0, ;
PTR(_CAST, cData), ;
nDataLen)

// Finally, we need to collect our reward for all this effort
SELF:GetResponseHeader()
cRet := SELF:GetResponse()

ENDIF // SendRequest

SELF:CloseRequest()

END // AddRequestHeaders

ENDIF

SELF:__DelStatusObject()

ENDIF

ENDIF

RETURN cRet

METHOD PostToDocumentOnServer(cServer, cDocument,cCargo, cID, cPw) CLASS
cHttp // String
// Bob McCutcheon
// VO NG Wed 25 Sept 2002 21:46
// LOCAL ohttp:=myhttp{}
//
ohttp:PostToDocumentOnserver("https://www.ups.com/ups.app/xml/Track","c:\ACCESS.xml","testUser","testPW")
LOCAL cRet := '' AS STRING
LOCAL pCargo AS PTR
LOCAL cContentType AS STRING
LOCAL lOpen AS LOGIC
LOCAL lSend AS LOGIC
//LOCAL accepttype,acceptlang AS STRING
LOCAL acceptencoding AS STRING
//LOCAL referer, User_agent AS STRING
LOCAL nfile,clin:="",cdoc:=""
Default(@cServer, URL_LOCAL_HOST)
Default(@cDocument, "")
IF File(cdocument)
IF (nfile:=FOpen(cdocument)) != F_ERROR
DO WHILE ! FEof(nfile)
cdoc+=clin
ENDDO
FClose(nfile)
SELF:ConnectRemote(cServer, cID, cPw)
IF SELF:Connected
cContentType:="Content-Length: " + Str(Len(cdoc))+CRLF
cContentType+="Accept-Language: en" +CRLF
cContentType+="Connection: Keep-Alive" +CRLF
cContentType+="Content-Type: application/x-www-form-urlencoded" + CrLf
ACCEptEncoding := "Accept-Encoding: gzip, deflate"
lOpen := SELF:OpenRequest("POST",cdoc, "HTTP/1.0")
IF lOpen
//sHeader := "Content-Length: 2048" + CrLf
lSend :=
SELF:SendRequest(cContentType,PTR(_CAST,pcargo),WORD(_CAST,Len(cDoc)))
IF lSend
cRet := SELF:GetResponse()
ELSE
cRet := 'FOUT: verzending naar '+cServer+' mislukt.'
ENDIF
MemFree(pcargo)
SELF:CloseRequest()
ELSE
cRet := 'FOUT: verzoek bij '+cServer+' mislukt.'
ENDIF
SELF:CloseRemote()
ELSE
cRet := 'FOUT: geen verbinding kunnen maken met '+cServer+'.'
ENDIF
ELSE
cRet := 'FOUT: '+cdocument+' kan niet geopend worden.'
ENDIF
ELSE
cRet := 'FOUT: '+cdocument+' bestaat niet.'
ENDIF
RETURN cRet



Op 24-3-2019 om 18:26 schreef Fred Killet:

Wolfgang Riedmann

unread,
Mar 25, 2019, 5:07:35 AM3/25/19
to
Hi Fred,

I had used that code really for a long time, but since it uses WinINet,
and Microsoft does not supports it anymore, I use winHttp now instead.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa384270%28v=vs
.85%29.aspx

https://msdn.microsoft.com/en-us/library/aa384270%28VS.85%29.aspx#Postin
g_data_to_the_

If you need that code, I can share my winHttp class.

Wolfgang
--

Johan Nel

unread,
Mar 25, 2019, 8:01:53 AM3/25/19
to
Or as Wolfgang indicated, old stuff.

How about looking at X# and start making the XBase.NET future move.....
X#, start integrating the latest technology into your applications...


On 2019/03/25 11:07, Wolfgang Riedmann wrote:
> Hi Fred,
>
> I had used that code really for a long time, but since it uses WinINet,
> and Microsoft does not supports it anymore, I use winHttp now instead.
>
> https://msdn.microsoft.com/en-us/library/windows/desktop/aa384270%28v=vs
> ..85%29.aspx
*Johan Nel*
George, South Africa

nk

unread,
Mar 25, 2019, 7:26:23 PM3/25/19
to
Hi Wolfgang,

I have interest on your winHTTP class. Can you share it to me?

Norbert

Wolfgang Riedmann

unread,
Mar 26, 2019, 6:55:56 AM3/26/19
to
Hi Norbert,

> I have interest on your winHTTP class. Can you share it to me?

please find it here:

https://www.riedmann.it/download/winHttp.zip

This library is using external modules as most of my libraries that are
shared between different VO projects.

Wolfgang

P.S. other VO sources downloads are on the same page:
https://www.riedmann.it/verschiedenes_cavo.php

>
> Norbert
>
> Am 25.03.2019 um 10:07 schrieb Wolfgang Riedmann:
> > Hi Fred,
> >
> > I had used that code really for a long time, but since it uses
> > WinINet, and Microsoft does not supports it anymore, I use winHttp
> > now instead.
> >
> > https://msdn.microsoft.com/en-us/library/windows/desktop/aa384270%28
> > v=vs .85%29.aspx
> >
> > https://msdn.microsoft.com/en-us/library/aa384270%28VS.85%29.aspx#Po
> > stin g_data_to_the_
> >
> > If you need that code, I can share my winHttp class.
> >
> > Wolfgang
> >
> >



--

nk

unread,
Mar 26, 2019, 10:08:49 AM3/26/19
to
Hi Wolfgang!

Thank you very much, well done!

Norbert

Fred Killet

unread,
Mar 30, 2019, 7:02:25 AM3/30/19
to
Hello John,

thank you very much to share the source from Norbert and Bob.

That one from Bob I could not to get running. But that from Norbert
works well. I changed it a little bit to make it working with my perl
script which is on the internet server. I use it with VO27. Here I share
the updated code:

FUNCTION sendDataByPostToCgi(cServer,cCgiPath,cPostData,cError)
/*
Die Funktion sendet Daten an ein CGI-Script.

Beispiel:
LOCAL cServer,cCgiPath,cPostData,cError AS STRING
cServer := "www.killetsoft.de"
cCgiPath := "cgi-bin/xxxxxxxx/xxxxxxx.pl"
cPostData := "field1=value1&field2=value2&field3=value3"
if .not. sendDataByPostToCgi(cServer,cCgiPath,cPostData,@cError)
? cError
else
? "Daten erfolgreich übertragen"
endif
*/

// Variablen
LOCAL cHeader AS STRING
LOCAL lResult AS LOGIC
LOCAL oHttp AS cHttp

// Parameter aufbereiten
oHttp := cHttp{"KilletSoft"}
IF .not. Left(cCgiPath,1) == "/"
cCgiPath := "/" + cCgiPath
ENDIF

// Header vorbelegen
cHeader := "Accept: *" + "/" + "*" + CRLF
cHeader += "Man: POSThttp://" + cServer + cCgiPath + " HTTP/1.1" + CRLF
cHeader += "Content-Type: text/html; charset=utf-8" + CRLF

// Daten senden. Methode POST, Timeout 200 Millisekunden
lResult :=
oHttp:GetDocumentByGetOrPost(cServer,cCgiPath,cPostData,cHeader,"POST",200)

// Fehlermeldung zurück geben
IF .not. lResult
IF .not. IsNil(cError)
cError := oHttp:PostErrorMsg
ENDIF
ENDIF

// Aufräumen
oHttp:CloseRemote()
oHttp:Axit()
RETURN lResult


METHOD
GetDocumentByGetOrPost(cServer,cDocument,cData,cHeader,cMethod,nTimeOut,nPort,nFlags)
CLASS cHttp
/******************************************************************
GET or POST - that's the question
Norbert Kolb, 11/17/03, 12/02/04, 09/02/04 02/25/05
UG Bodensee (A, CH, D, FL)
Fred Killet, 03/29/19
Killet Software Ing.-GbR
*******************************************************************
First the InternetOpen FUNCTION IS called TO initialize the
remaining functions. Then the InternetConnect FUNCTION IS called
TO identify the type OF service being requested. THIS IS necessary
AS the same set OF functions can be used TO interact WITH a number
OF different servers.
/*****************************************************************/

// Varialblen
LOCAL lResult AS LOGIC
LOCAL lRet AS LOGIC
LOCAL nSecur,nLen AS DWORD

// Default-Parameter
Default(@cDocument,"")
Default(@cData,"")
Default(@cMethod,"GET")
Default(@nPort,SELF:nPort)
Default(@nFlags,0)
Default(@nTimeOut,1000)

// Vorbelegungen
lRet := FALSE
SELF:PostErrorMsg := ""

// HTTPS-Port ermitteln
IF _AND(DWORD(nFlags),INTERNET_FLAG_SECURE) = INTERNET_FLAG_SECURE
nPort := INTERNET_DEFAULT_HTTPS_PORT
SELF:nPort := nPort
ENDIF

// Use opened session or open new http session.
IF SELF:hSession == NULL_PTR
lResult := SELF:Open(NIL,SELF:cProxy)
ELSE
lResult := TRUE
ENDIF

// Identify the type of service that is being accessed
IF lResult
IF SELF:hConnect == NULL_PTR .or. SELF:cHostAddress <> cServer
SELF:cHostAddress := cServer
SELF:hConnect := InternetConnect(;
SELF:hSession,;
String2Psz(SELF:cHostAddress),;
nPort,;
String2Psz(SELF:cUserName),;
String2Psz(SELF:cPassword),;
INTERNET_SERVICE_HTTP,;
nFlags,;
0;
)
ENDIF

// Once we've identified the service, we need to indicate the
// page to which the data will be posted.
IF SELF:hConnect <> NULL_PTR
SELF:__SetStatusObject()
SELF:hRequest := HttpOpenRequest(;
SELF:hConnect,; // hConnect
String2Psz(cMethod),; // lpszVerb
String2Psz(cDocument),; // pszObjectName
String2Psz("HTTP/1.1"),; // pszVersion
NULL_PSZ,; // pszReferer
NULL_PSZ,; // pszAcceptTypes
nFlags,; // dwFlags
SELF:__GetStatusContext(); // dwContext
)

// We need to add a header to notify the web server that the
// incoming data is form encoded and then send the request.
IF SELF:hRequest <> NULL_PTR
SELF:__SetStatus(SELF:hRequest)
IF cMethod == "POST"
IF Empty(cHeader)
cHeader := "Content-Type: application/x-www-form-urlencoded"
+ CRLF + HEADER_ACCEPT
ENDIF
ELSE
IF Empty(cHeader)
cHeader := HEADER_ACCEPT
ENDIF
ENDIF

// Connect requested headers
IF
HttpAddRequestHeaders(SELF:hRequest,String2Psz(cHeader),SLen(cHeader),HTTP_ADDREQ_FLAG_ADD)

// Sometimes you have to set SECURITY_FLAGS
nLen := _sizeof(DWORD)

InternetQueryOption(SELF:hRequest,INTERNET_OPTION_SECURITY_FLAGS,@nSecur,@nLen)
nSecur := _OR(nSecur,SECURITY_FLAG_IGNORE_UNKNOWN_CA)

InternetSetOption(SELF:hRequest,INTERNET_OPTION_SECURITY_FLAGS,@nSecur,nLen)

// Here the timeout is set

InternetSetOption(SELF:hRequest,INTERNET_OPTION_SEND_TIMEOUT,@nTimeOut,_sizeof(DWORD))

InternetSetOption(SELF:hRequest,INTERNET_OPTION_RECEIVE_TIMEOUT,@nTimeOut,_sizeof(DWORD))

InternetSetOption(SELF:hRequest,INTERNET_OPTION_CONNECT_TIMEOUT,@nTimeOut,_sizeof(DWORD))

// Send the data
IF
HttpSendRequest(SELF:hRequest,NULL,0,PTR(_CAST,cData),DWORD(_CAST,SLen(cData)))
lRet := TRUE

// Here you can downoad the updated document and the sent header
* SELF:GetResponseHeader()
* SELF:GetResponse()

// Fehler beim Senden der Daten
ELSE
SELF:PostErrorMsg := "Fehler beim Senden der Daten"
ENDIF
SELF:CloseRequest()

// Fehler beim Senden der Header-Informationen
ELSE
SELF:PostErrorMsg := "Fehler beim Senden der Header-Informationen"
ENDIF

// Fehler beim Zugriff auf das html-Dokument
ELSE
SELF:PostErrorMsg := "Fehler beim Zugriff auf das html-Dokument"
ENDIF
SELF:__DelStatusObject()

// Fehler beim Herstellen der html-Verbindung
ELSE
SELF:PostErrorMsg := "Fehler beim Herstellen der html-Verbindung"
ENDIF

// Fehler beim Zugriff auf die http-Session
ELSE
SELF:PostErrorMsg := "Fehler beim Zugriff auf die http-Session"
ENDIF
RETURN lRet


ACCESS PostErrorMsg() CLASS cHttp
// Zugriff auf eine Fehlermeldung der Methode cHttp:GetDocumentByGetOrPost()
RETURN SELF:cError


ASSIGN PostErrorMsg(cError) CLASS cHttp
// Eintragen einer Fehlermeldung in der Methode
cHttp:GetDocumentByGetOrPost()
IF IsString(cError)
SELF:cError := cError
ENDIF
RETURN SELF:cError


DEFINE INTERNET_OPTION_CONNECT_TIMEOUT := 2


DEFINE INTERNET_OPTION_RECEIVE_TIMEOUT := 6


DEFINE INTERNET_OPTION_SECURITY_FLAGS := 31


DEFINE INTERNET_OPTION_SEND_TIMEOUT := 5


DEFINE SECURITY_FLAG_IGNORE_UNKNOWN_CA := 0x00000100

JohnMartens

unread,
Mar 30, 2019, 4:45:19 PM3/30/19
to
Glad to be of help
John

Op 30-3-2019 om 12:02 schreef Fred Killet:

Fred Killet

unread,
Apr 1, 2019, 7:08:39 PM4/1/19
to
Thank you all for your help!
Kind regards, Fred

Message has been deleted

Heraldo Gama

unread,
Sep 30, 2021, 2:55:19 PM9/30/21
to
Em segunda-feira, 1 de abril de 2019 às 20:08:39 UTC-3, Fred Killet escreveu:
> Thank you all for your help!
> Kind regards, Fred

Hi everyone...

My conttrib using winHttp library from Wolfgang.

LOCAL oHttp as winHttp

cServerName := "ef49-177-47-50-94.ngrok.io"
cURL := "/hook/"
cJSONstring := [{"name":"] +self:oDCmPaciente:Caption+["}]

oHttp := winHttp{}
oHttp:UseSSL := true
cResult := oHttp:PostURL(cServerName,cURL,cJSONstring,INTERNET_DEFAULT_HTTPS_PORT)

RETURN self
0 new messages