An embedded in memory http / https web server with a PB tag preprocessor
to unleash the pure power of PB on the web, built on civetweb a MIT fork of mongoose server before it went GPL in 2013.
Current build is v1.0 built on Civetweb 1.10, windows x86 build at the moment
The package contains all you need to get started.
See civet_server_in_memSSL.pb which is based on civetserver.pbi wrapper to civetweb.pbi import
Civet_server_in_memSSL.pb demonstrates an embedded in memory ssl server, served to a webgadget
The site is packed in "www.ezp" which you can extract to file by the provided ezpack test file unpackfromdisk
(couldn't upload the www source folder to git hub as it had to many files in it, so you can inspect and extract it)
you can then switch from running in memory to file by commenting out app\packAddress =?Index
the source of the site can then be edited and repacked by using the utility function
Civet_Server_Create_Pack(app)
The Preprocessor expects files saved as ".pbh" and you simply tag where you want to inline the output
as <?PB SomeFunction() /> and declare your procedure as runtime. Easy!
delivering an ASP or php like experience
CivetServer.pbi
Is the PB friendly wrapper for civetweb, it's not complete needs some changes but it's a starting point
it has additional dependencies to ezpack.pbi archiver for in memory functions
and has it's own mimetypes.pbi which shouldn't really be required but a few in civetweb are wrong
and it's easier to add them to the mimetypes.pbi as required rather than rebuild civetweb.lib
Civetserver is designed to work from both file and in memory. Civetweb itself doesn't facilitate in memory functionality
so it bypasses a considerable portion of checks civetweb's would normally handle, though the file based functions
are still passed through civetweb's pipeline.
It's usage is demonstrated in civet_server_in_memSSL.pb
basically all you need to do is handle get and post queries and return the appropriate response
you can easily handle ajax calls for instance and return json objects from file or in memory
and with the preprocessor is makes it dead easy to inline your output.
Civetweb.pbi
Is just the raw import of the static libs change the import to which version you want ssl or non ssl
Not all of the functionality of civetweb is tested. see civetweb site for implementation and documentation
The current build is v 1.10 and will be updated to 1.11 when I get around to it.
If it doesn't work it at all you may need to install the msvc 2017 redistributables. which you would distribute
with an application setup.
https://aka.ms/vs/15/release/vc_redist.x86.exe
The project download link
https://github.com/idle-PB/pb_civet_server
The project was commissioned by one of our members who may or may not want to be publically attributed
and I thank him for his custom and generosity in allowing me to share the project with the community
I am looking for contributors and someone for linux and osx who can build the static libs
PM me if your interested in contributing.
Source of civet_server_in_memSSL.pb
Code: Select all
IncludeFile "civetserver.pbi"
Global app.Civet_Server
Procedure Resize()
ResizeGadget(2,0,0,WindowWidth(0),WindowHeight(0))
EndProcedure
;If you declare a runtime procedure and add a tag <?PB ElementFillTable() /> in the source html page remamed as .pbh
;it will call the function and inline the code in the output
Runtime Procedure ElementsFillTable(*app.Civet_Server)
Protected sout.s,sum.f,a
sout = "<div><H2>Output from ElementsFillTable() Callback</h2></div>"
sout + "<div class='table-wrapper'><table><thead><tr><th>Name</th><th>Description</th><th>Price</th></tr></thead>" + #LF$
sout + "<tbody>" + #LF$
For a = 1 To 20
sout + "<tr><td>Item " + Str(a) + "</td><td>Ante turpis integer aliquet porttitor.</td><td>" + StrF(a * 2.99,2) + "</td></tr>" + #LF$
sum + (a * 2.99)
Next
sout + "</tbody><tfoot><tr><td colspan='2'></td><td>$" + StrF(sum,2) + "</td></tr></tfoot></table></div>"
ProcedureReturn UTF8(sout)
EndProcedure
Procedure cbPost(ctx,*request.Civet_Server_Request) ;callbacks are threaded only use locally scoped resources
Debug "cbpost request type " + *request\RequestType
Debug *request\Uri
ForEach *request\mquery()
Debug *request\mquery()\name + " " + *request\mquery()\value
Next
*request\Uri = "/elements.pbh" ;redirect to
ProcedureReturn 0 ;to continue processing or 200
EndProcedure
Procedure cbGet(ctx,*request.Civet_Server_Request)
Debug "cbGet request type " + *request\RequestType
Debug *request\Uri
Debug GetFilePart(*request\Uri)
ForEach *request\mquery()
Debug MapKey(*request\mQuery()) + " " + *request\mquery()\name + " " + *request\mquery()\value
Next
If *request\mQuery("play")\value = "Waponez"
RunProgram("Http://127.0.0.1/Waponez.html")
Civet_Server_Send_Response(ctx,"",0,0,"204 No Content")
ProcedureReturn 204
EndIf
ProcedureReturn 0
EndProcedure
app\packAddress =?Index ;address for ezp pack archive of website in datasection. if unset will load from files.
app\packsize = ?EndIndex - ?Index ;size of the pack to read in
app\dirRelitive = "www" ;required
app\cbpost = @cbpost() ;set a call back to process the post tokens
app\cbget = @cbGet() ;set a call back to process query strings from a get request
Debug GetPathPart(ProgramFilename()) + app\dirRelitive
app\Server_Settings\document_root = GetPathPart(ProgramFilename()) + app\dirRelitive ;set a root to be safe
app\Server_Settings\access_control_list = "-0.0.0.0/0,+127.0.0.1" ;block all and then only allow connection from 127.0.0.1
app\Server_Settings\error_log_file = GetPathPart(ProgramFilename()) + "error.log" ;set logs
app\Server_Settings\access_log_file = GetPathPart(ProgramFilename()) + "access.log" ;set logs
app\Server_Settings\static_file_max_age = "0" ;nothing should be cached when debugging
app\Server_Settings\ssl_certificate = GetPathPart(ProgramFilename()) + "ssl_cert.pem"
app\Server_Settings\enable_keep_alive = "yes"
;app\Server_CallBacks\begin_request = @cb_begin_request() ;these callbacks are usefull for debug info
;app\Server_CallBacks\end_request = @cb_end_request() ;or if you want to overide civetweb, declared in civetweb.pbi
;app\Server_CallBacks\connection_close = @cb_connection_closed()
;app\Server_CallBacks\log_Access = @cb_log_access()
;app\Server_CallBacks\log_message = @cb_log_message()
;app\Server_CallBacks\http_error = @cb_http_error()
;app\Server_CallBacks\init_connection = @cb_init_Connection()
;app\Server_CallBacks\init_context = @cb_init_Context()
;app\Server_CallBacks\exit_context = @cb_exit_context()
;This can be used to pack your website to ezp so you can include it in the datasection
;it will be named as the folder of the app\dirRelitive setting with an extension of .ezp eg: www.ezp
;Civet_Server_Create_Pack(app)
If Civet_Server_Start(app,80,443,"127.0.0.1")
If OpenWindow(0,0,0,1024,600,"PB_Civet_Server_in_memSSL example of in memory embedded PB_Civet_Server " + app\Server_Settings\listening_ports,#PB_Window_SystemMenu |#PB_Window_SizeGadget |#PB_Window_MaximizeGadget)
WebGadget(2,0,0,1024,600,"https://127.0.0.1:"+ app\https_port)
BindEvent(#PB_Event_SizeWindow,@Resize())
Repeat
Until WaitWindowEvent(30) = #PB_Event_CloseWindow
EndIf
Civet_Server_Stop(app)
Else
MessageRequester(GetFilePart(ProgramFilename()),"Cant start Server")
End
EndIf
DataSection
Index:
IncludeBinary "www.ezp"
EndIndex:
EndDataSection