PureBasic
Compile this as cgitest.cgi and place that in the "cgi-bin" subfolder of your website (remember to match the architecture of your server).
Code: Select all
Declare SayHello(jsParams,jsRO)
Declare SendChunk(txt$)
Procedure FormatError(jsRO,errcode,errmsg$)
jsErr = AddJSONMember(jsRO,"error")
jsErrO = SetJSONObject(jsErr)
SetJSONString(AddJSONMember(jsErrO,"message"),errmsg$)
SetJSONInteger(AddJSONMember(jsErrO,"code"),errcode)
SetJSONInteger(AddJSONMember(jsErrO,"origin"),2)
jsResP = AddJSONMember(jsRO,"result")
SetJSONNull(jsResp)
EndProcedure
Procedure ProcessIncoming(incoming$)
jsRP = CreateJSON(#PB_Any) ; Start building our JSON-RPC response
jsRO = SetJSONObject(JSONValue(jsRP))
WriteCGIString("Content-type: application/json" + #CRLF$,#PB_UTF8)
WriteCGIString("Transfer-Encoding: chunked" + #CRLF$ + #CRLF$,#PB_UTF8)
js = ParseJSON(#PB_Any,incoming$) ; Parse incoming JSON-RPC
; details here: https://en.wikipedia.org/wiki/JSON-RPC
If js
todo$ = GetJSONString(GetJSONMember(JSONValue(js),"method"))
id$ = GetJSONString(GetJSONMember(JSONValue(js),"id"))
jsParams = GetJSONMember(JSONValue(js),"params")
SetJSONString(AddJSONMember(jsRO,"id"),id$) ; always return id
Select todo$ ; route and pass params to requested method
Case "sayhello"
SayHello(jsParams,jsRO)
Default
FormatError(jsRO,4,"Method not found: "+todo$)
EndSelect
SendChunk(ComposeJSON(jsRP,#PB_JSON_PrettyPrint))
FreeJSON(js)
FreeJSON(jsRP)
EndIf
EndProcedure
Procedure SayHello(jsParams,jsRO)
NewMap qp.s()
ExtractJSONMap(jsParams,qp())
jsErr = AddJSONMember(jsRO,"error")
SetJSONNull(jsErr)
jsResP = AddJSONMember(jsRO,"result")
jsResO = SetJSONObject(jsResP)
SetJSONString(AddJSONMember(jsResO,"msg"),qp("recipient") + " said: '" + qp("greeting") + "'")
EndProcedure
Procedure SendChunk(txt$)
nSize = StringByteLength(txt$,#PB_UTF8)
If nSize = 0 : ProcedureReturn : EndIf ; don't want to SendEOT by mistake
hxSize$ = Hex(nSize)
res$ = hxSize$ + #CRLF$ + txt$ + #CRLF$
WriteCGIString(res$,#PB_UTF8)
EndProcedure
Procedure SendEOT()
WriteCGIString(Hex(0) + #CRLF$ + #CRLF$,#PB_UTF8)
EndProcedure
If Not InitCGI() : End : EndIf
BufferSize = ReadCGI()
If BufferSize = 0 : End : EndIf
RequestBody$ = PeekS(CGIBuffer(),BufferSize,#PB_UTF8)
ProcessIncoming(RequestBody$)
SendEOT()
You have to compile this (Enable Debugger should be ticked) and serve it from the same server that's hosting the CGI
Code: Select all
request$ = ""
Procedure HttpGetEvent(Success,Result$,UserData)
If Success
Debug Result$
Else
Debug "HTTPRequest(): Error"
EndIf
EndProcedure
If CreateJSON(0)
jso = SetJSONObject(JSONValue(0))
SetJSONString(AddJSONMember(jso,"method"),"sayhello")
SetJSONString(AddJSONMember(jso,"id"),"abc123")
jsp = SetJSONObject(AddJSONMember(jso,"params"))
SetJSONString(AddJSONMember(jsp,"recipient"),"Weave")
SetJSONString(AddJSONMember(jsp,"greeting"),"Hello, World!")
request$ = ComposeJSON(0)
FreeJSON(0)
EndIf
Debug request$
Debug ""
NewMap Headers$()
Headers$("Content-Type") = "application/json"
HTTPRequest(#PB_HTTP_Post,"cgi-bin/cgitest.cgi",request$,@HttpGetEvent(),0,Headers$())