Compare commits

...

24 commits

Author SHA1 Message Date
bbeceee2b8 Session Handling initial 2024-09-30 17:07:24 +02:00
6479c4645d Errorpage handling change and header work 2024-09-23 05:59:11 +02:00
bd70412795 Small fix in the sample function library 2024-09-23 05:57:51 +02:00
52ff892387 Debug output korrigiert 2024-09-20 13:57:31 +02:00
bfd39d7558 Fixed that a stopped Download Kill the server. 2024-09-20 11:07:37 +02:00
fe883004f8 new lhs_lib 2024-09-17 10:52:42 +02:00
8dc6ba4f77 Add HTTP request methods abd Debug for sucessfull Library Load 2024-03-15 13:27:20 +01:00
a9595720c6 Add ICO mimetype 2024-03-13 09:24:00 +01:00
7b315bcc25 Bugfixes 2024-03-13 09:23:28 +01:00
edccdf62cd Merge remote-tracking branch 'refs/remotes/origin/main' 2024-03-11 10:13:50 +01:00
01b51210ee Installation Fix and Cleanup 2024-03-11 10:10:20 +01:00
ce2a5d4e1a Activate the new module 2023-07-18 08:59:36 +02:00
ce41a4cd23 Remove post decoder from main and create new module 2023-07-18 08:58:51 +02:00
077531d4c8 Refreshed Project 2023-07-17 15:55:10 +02:00
a56ef8a63d Update lib 2023-07-17 15:53:41 +02:00
34c68fa985 add new definitions 2023-07-17 15:47:38 +02:00
26426f7d3d First auth 2023-05-17 18:02:54 +02:00
d1b24f5f97 Websocket Prototype 2023-03-31 12:46:49 +02:00
8574b29021 Initial Websocket and Bugfix for prototype support 2023-03-31 10:40:32 +02:00
194245d3b6 add lhs_web_helper lib to lweb_header 2023-03-31 10:08:28 +02:00
82d6998c7c lhs_lib connection constants 2023-03-31 10:07:44 +02:00
45e484db30 Update lhs_lib for latests state codes 2023-03-31 09:54:49 +02:00
5eaea5a2e6 Update old TODO list 2023-03-31 08:49:32 +02:00
9822988941 New build target (Installer) 2023-03-30 15:55:04 +02:00
17 changed files with 613 additions and 356 deletions

View file

@ -3,10 +3,10 @@ lweb HTTP & HTTPS Webserver
TODO List:
DONE: Switch all Network operations to Standard API
POST/PUT with bigger Files and or Contents
Sending of bigger Files (Currently everithing in Memory and then send)
DONE:Sending of bigger Files (Currently everithing in Memory and then send)
error400 handling
error Code handling (Different errorcodes and responses)
Translate Remarks to english
Translate README.md to english
Optimizing Code away from old PureBasic Network Code.
DONE:Optimizing Code away from old PureBasic Network Code.
Cleanup unused Variables

View file

@ -99,6 +99,18 @@
lib_id.i
EndStructure
Structure headerfunctions
header_name.s
call.i
type.i
library.s
perm.i
EndStructure
Structure session
Cookie.s
EndStructure
Structure host
description.s
http.server_http
@ -108,6 +120,8 @@
mem.memory
Map dynamichandler.dynamichandler()
Map usedlibs.usedlibs()
Map headerfunctions.headerfunctions()
Map sessions.session()
defaultfile.s
basedir.s
Map status.http_status_codes() ;Individual Error Messages and Headers

View file

@ -4,6 +4,7 @@
;*
Procedure.s mimetype(file.s)
; TODO:Mimetype dynamic configurable via XML
Select LCase(file)
Case "pdf"
ProcedureReturn "application/pdf"
@ -17,6 +18,8 @@ Procedure.s mimetype(file.s)
ProcedureReturn "application/vnd.ms-excel"
Case "ppt"
ProcedureReturn "application/vnd.ms-powerpoint"
Case "ico"
ProcedureReturn "image/vnd.microsoft.icon"
Case "png"
ProcedureReturn "image/png"
Case "gif"

View file

@ -3,6 +3,7 @@
;* lweb_helper_header.pbi
;*
; TODO:Mimetype dynamic configurable via XML
Declare.s mimetype(file.s)
Declare.s MapToJSONString(Map ConvertMap.s())

View file

@ -0,0 +1,68 @@
;********************************
;*
;* lweb_http_post_decoder.pbi
;*
;* LiHaSo Webserver HTTP POST Data decoder
;*
;* Currently only x_www_form_urlencode implemented.
;*
DeclareModule lhs_web_post
Declare.s mem_x_www_form_urlencoded(ContentLength.i, MemorSize.i, Memory.i)
Declare.s mem_multipart_form_data(ContentLength.i, MemorySize.i, Memory.i)
#error_string = "error"
EndDeclareModule
Module lhs_web_post
Procedure.s mem_x_www_form_urlencoded(ContentLength.i, MemorSize.i, Memory.i)
Define.s JSONString, Working, ContentString
Define CountParams, Count, JSON
Protected NewMap Posts.s()
If ContentLength > 0
OffsetMemory = Memory + (MemorSize - ContentLength)
ContentString = PeekS(OffsetMemory, ContentLength, #PB_UTF8)
;Zerlegen &
;Mapname = Content
If Len(ContentString) > 0
CountParams = CountString(ContentString,"&")
If CountParams = 0
If CountString(ContentString, "=")
Posts(StringField(ContentString, 1, "=")) = StringField(ContentString,2, "=")
Else
ProcedureReturn ""
EndIf
ElseIf CountParams > 0
Count = 0
Repeat
Posts(StringField(StringField(ContentString, Count + 1, "&"),1,"=")) = StringField(StringField(ContentString, Count + 1, "&"),2,"=")
;ldl::Logging("Worked Count:"+Str(Count)+" of: "+Str(CountParams)+":"+StringField(StringField(ContentString, Count + 1, "&"),1,"=")+" = "+StringField(StringField(ContentString, Count + 1, "&"),2,"=")
Count + 1
Until Count > CountParams
Else
ProcedureReturn ""
EndIf
JSON = CreateJSON(#PB_Any)
If JSON
InsertJSONMap(JSONValue(JSON), Posts())
JSONString = ComposeJSON(JSON)
FreeMap(Posts())
FreeJSON(JSON)
ProcedureReturn JSONString.s
Else
ProcedureReturn #error_string
EndIf
Else
ProcedureReturn ""
EndIf
Else
ProcedureReturn ""
EndIf
EndProcedure
Procedure.s mem_multipart_form_data(ContentLength.i, MemorySize.i, Memory.i)
ProcedureReturn "NA"
EndProcedure
EndModule

View file

@ -121,3 +121,16 @@ Procedure status_get_content(status.s, UUID.s="Default")
EndIf
EndProcedure
Procedure.s status_render_html(status.s, UUID.s="Default")
If UUID <> "Default"
If configuration\hosts(UUID)\status(status)\status = status
ProcedureReturn body.s
EndIf
Else
If configuration\status(status)\status = status
ProcedureReturn body.s
EndIf
EndIf
EndProcedure

View file

@ -15,4 +15,5 @@ Declare.s status_get_message(status.s, UUID.s="Default")
Declare.s status_get_message_body(status.s, UUID.s="Default")
Declare status_get_template(status.s, UUID.s="Default")
Declare status_get_content(status.s, UUID.s="Default")
Declare.s status_render_html(status.s, UUID.s="Default")

View file

@ -77,7 +77,7 @@
;Now we need to load additional Config Files
ResetMap(configuration\config_file())
While NextMapElement(configuration\config_file())
Debug configuration\config_file()\configtype
ldl::Logging("Config Type:" + configuration\config_file()\configtype )
Select LCase(configuration\config_file()\configtype)
Case "hosts_dir"
ldl::Logging("Hosts Directory:"+configuration\config_file()\name)
@ -209,58 +209,6 @@
EndIf
Case #conf_runfile
; Case #conf_HTTP_port
; configuration\http\port = Val(setting)
; Case #conf_HTTPS_Port
; configuration\https\port = Val(setting)
; Case #conf_HTTP_binding
; If IsIPStringValid(setting)
; configuration\http\binding = setting
; Else
; configuration\http\binding = "127.0.0.1"
; ProcedureReturn #False
; EndIf
; Case #conf_HTTPS_Binding
; If IsIPStringValid(setting)
; configuration\https\binding = setting
; Else
; configuration\https\binding = "127.0.0.1"
; ProcedureReturn #False
; EndIf
; Case #conf_HTTPS_CA
; configuration\https\CA = setting
; Case #conf_HTTPS_Cert
; configuration\https\Certs = setting
; Case #conf_HTTPS_Key
; configuration\https\Key = setting
; Case #conf_HTTPS_Key_Pass
; configuration\https\key_pass = setting
; Case #conf_HTTPS_Enable
; configuration\https\enabled = Val(setting)
; Case #conf_defaultfile
; configuration\defaultfile = setting
; Case #conf_basedir
; configuration\basedir = setting
; Case #conf_error400
; configuration\error400 = setting ; Kann "integrated" sein wass die integrierte Standard Fehlermeldung hervorruft.
; Case #conf_max_HTTP_clients
; If MemoryStatus(#PB_System_FreePhysical) > (Val(setting)*(1024*384))
; configuration\http\max_clients = Val(setting)
; Else
; configuration\http\max_clients = 10
; ProcedureReturn #False
; EndIf
; Case #conf_max_HTTPS_clients
; If MemoryStatus(#PB_System_FreePhysical) > (Val(setting)*(1024*384))
; configuration\https\max_clients = Val(setting)
; Else
; configuration\https\max_clients = 10
; ProcedureReturn #False
; EndIf
; Case #conf_server_type
; configuration\type = Val(setting)
; Case #conf_cache_enable
; configuration\cache\enable = Val(Setting)
Default
ProcedureReturn #False
EndSelect
@ -285,20 +233,6 @@
Else
ProcedureReturn "false"
EndIf
; Case #conf_defaultfile
; ProcedureReturn configuration\defaultfile
; Case #conf_basedir
; ProcedureReturn configuration\basedir
; Case #conf_error400
; ProcedureReturn configuration\error400
; Case #conf_max_HTTP_clients
; ProcedureReturn Str(configuration\http\max_clients)
; Case #conf_server_type
; ProcedureReturn Str(configuration\type)
; Case #conf_HTTP_port
; ProcedureReturn Str(configuration\http\port)
; Case #conf_HTTPS_Port
; ProcedureReturn Str(configuration\https\port)
Default
ProcedureReturn ""
EndSelect

View file

@ -54,7 +54,7 @@ CopyFile("cfg/hosts/default.xml", "/etc/lhttpd/hosts/default.xml")
PrintN("Copy application")
CopyFile("lhttpd", "/opt/lhttpd/lhttpd")
PrintN("chown and chmod for ssl...")
If CreateFile(0, "/tmp/install.sh")
If CreateFile(0, "/tmp/lhttpd_install.sh")
WriteStringN(0, "#!/bin/bash")
WriteStringN(0, "echo 'started'")
WriteStringN(0, "chown -R lhttpd:lhttpd /etc/lhttpd")
@ -71,23 +71,15 @@ If CreateFile(0, "/tmp/install.sh")
WriteStringN(0, "echo 'finished'")
CloseFile(0)
Else
PrintN("Error : Unable To create script")
PrintN("Error : Unable To create script at /tmp/lhttpd_install.sh")
End
EndIf
RunProgram("chmod", "777 /tmp/install.sh", "", #PB_Program_Wait)
RunProgram("chmod", "777 /tmp/lhttpd_install.sh", "", #PB_Program_Wait)
Delay(1000)
RunProgram("/tmp/install.sh", "", "", #PB_Program_Wait)
RunProgram("/tmp/lhttpd_install.sh", "", "", #PB_Program_Wait)
DeleteFile("/tmp/install.sh")
DeleteFile("/tmp/lhttpd_install.sh")
; RunProgram("chown", "-R lhttpd:lhttpd /etc/lhttpd","", #PB_Program_Wait)
; RunProgram("chown", "-R lhttpd:lhttpd /var/lib/lhttpd","", #PB_Program_Wait)
; RunProgram("chown", "-R lhttpd:lhttpd /var/log/lhttpd","", #PB_Program_Wait)
; RunProgram("chown", "-R lhttpd:lhttpd /opt/lhttpd","", #PB_Program_Wait)
; RunProgram("chmod", "-R 744 /etc/lhttpd","",#PB_Program_Wait)
; RunProgram("chmod", "-R 744 /etc/lhttpd/hosts","",#PB_Program_Wait)
; RunProgram("chmod", "-R 700 /etc/lhttpd/ssl","",#PB_Program_Wait)
; RunProgram("chown", "-R 755 /opt/lhttpd","",#PB_Program_Wait)
PrintN("Create service file: /usr/lib/systemd/system/lhttpd.service")
If CreateFile(0, "/usr/lib/systemd/system/lhttpd.service")
WriteStringN(0,"[Unit]")

@ -1 +1 @@
Subproject commit 80af41e7e681d595d21e2a698153ea40122d4ee9
Subproject commit e6d5b2a00af7bf0ca2d1543a65c92dd82d046d67

View file

@ -2,7 +2,7 @@
;*
;* Lihaso Web Server (lhttpd)
;*
;* (c)2020 by Linder Hard- und Software
;* (c)2024 by Linder Hard- und Software
;*
;* V0.5
;* - Simple webserver for HTTP & HTTPS

413
lweb.pbi
View file

@ -10,6 +10,9 @@
XIncludeFile "lhs_lib/NET/lhs_net_tls.pbi"
XIncludeFile "lhs_lib/NET/lhs_net_socket.pbi"
XIncludeFile "inc/lweb_http_post_decoder.pbi"
Module lhs_web
;********************************
@ -82,6 +85,11 @@ Module lhs_web
#http_method_get = "GET"
#http_method_post = "POST"
#http_method_put = "PUT"
#http_method_connect = "CONNECT"
#http_method_delete = "DELETE"
#http_method_options = "OPTIONS"
#http_method_trace = "TRACE"
#http_method_patch = "PATCH"
;***********************
;* s_lweb_client Struktur Jeder Clientthread muss in die Liste eingetragen werden.:
@ -147,8 +155,14 @@ Module lhs_web
configuration_map_id.s
EndStructure
Structure s_header_functions
header_name.s
call.i
type.i
library.s
perm.i
EndStructure
Enumeration cli_handler_infos 1
#get_handler_procedure ;Funktion die Aufgerufen werden muss
#get_handler_prototype ;Welcher Prototype
@ -187,7 +201,7 @@ Module lhs_web
PrototypeC.s WebHandler_i_Get(handler_Map_JSON.s)
PrototypeC.s WebHandler_i_Post(handler_Map_JSON.s, ContentString.s)
PrototypeC.s WebHandler_i_Universal(handler_Map_JSON.s, ContentString.s)
PrototypeC WebSocket_Handler_String(handler_Map_JSON.s, Back_Semaphore.i)
;********************************
;*
@ -211,8 +225,8 @@ Module lhs_web
Declare call_request(RequestString.s, Info.i=#get_handler_procedure)
Declare.s call_function(ToCallType.i, ToCall.i, Map Header.s(), PostMapString.s ="")
Declare advanced_register_handler(RequesterString.s, Permament.i = 0, Library.s = "", Host.s = "")
Declare.s Work_Post_ToJSON_multipart_form_data(ContentLength.i, MemorSize.i, Memory.i)
Declare.s Work_Post_ToJSON_x_www_form_urlencoded(ContentLength.i, MemorSize.i, Memory.i)
;Declare.s Work_Post_ToJSON_multipart_form_data(ContentLength.i, MemorSize.i, Memory.i)
;Declare.s Work_Post_ToJSON_x_www_form_urlencoded(ContentLength.i, MemorSize.i, Memory.i)
Declare count_client(Type.i, Countchange.i)
XIncludeFile "inc/lweb_IP.pbi"
@ -263,6 +277,7 @@ Module lhs_web
EndProcedure
Procedure main_server(id.i)
ldl::Logging("main Server Loading")
status_defaults()
EndProcedure
@ -517,7 +532,24 @@ Module lhs_web
EndIf
ForEver
EndProcedure
Procedure server_WebSocket(network_client_id)
Protected Quit = 1
Protected.i thread_cli_id = network_client_id
Repeat
; Check if we get data from client
If m_clients(Str(thread_cli_id))\client_type = #client_HTTPS
temp_receivelength = tls::ReadTLSSocket(thread_cli_id, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer, 65536)
Else
temp_receivelength = lsocket::ReadSocket(thread_cli_id, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer, 65536)
EndIf
; Check if Library has data to send
Until Quit = 1
EndProcedure
Procedure client(network_client_id.i)
Protected thread_cli_id = network_client_id, sent
Protected MyThreadJSON, ToCall, ToCallType
@ -668,6 +700,16 @@ Module lhs_web
ldl::Logging("Empty accesslog:["+AccessLog+"]")
EndIf
;TODO: Header Handler
; ex. Cookie: #http_head_cookie
If Header(#http_head_cookie) <> ""
ldl::Logging("Session:"+Header(#http_head_cookie))
Else
Header(#http_head_cookie) = CreateUUID()
configuration\hosts(m_clients(Str(thread_cli_id))\host_id)\sessions(Header(#http_head_cookie))\Cookie = Header(#http_head_cookie)
EndIf
Select Header(#http_head_method)
Case #http_method_get
;********************************
@ -677,141 +719,170 @@ Module lhs_web
;{
ldl::Logging(#http_method_get)
If Header(#http_head_request) = "/"
thread_requested = default_file
Else
thread_requested = Header(#http_head_request)
EndIf
;*
;* Detect websocket upgrade request
;*
ldl::Logging("Requested:"+thread_requested)
ToCallType = call_request(Host_call + thread_requested, #get_handler_prototype)
If ToCallType = #handler_proto_universal Or ToCallType = #handler_proto_get
ToCall = call_request(Host_call + thread_requested)
If call_request(Host_call + thread_requested, #get_handler_library_perm) = 0
LibraryToCall = call_request_string(Host_call + thread_requested, #get_handler_library_perm)
If Len(LibraryToCall) > 0
Library_ID = OpenLibrary(#PB_Any, LibraryToCall)
If Library_ID
If LCase(Header(lhs_web_helper::#http_head_connection)) = lhs_web_helper::#http_connection_upgrade
;Whe have a Upgrade Request.
;Current Disconnect it with not supported
response_status = lhs_web_helper::#http_state_501
thread_type = lhs_web_helper::mimetype("html")
thread_temp_cache_memory = AllocateMemory(StringByteLength("Unsuported"))
PokeS(thread_temp_cache_memory, "Unsuported")
thread_data_size = StringByteLength("Unsuported")
If response_status = "" ;Remove if finished...
;detect a route to there.
If Left(Header(#http_head_request),2) = "ws"
;Whe have a websocket request.
;Detect if whe have a library who react to there:
ToCallType = call_request(Host_call + thread_requested, #get_handler_prototype)
If ToCallType = #handler_proto_i_get Or ToCallType = #handler_proto_get
;Call Websocket
Else
ldl::Logging("Library could not be opened")
EndIf
EndIf
EndIf
Else
ToCall = 0
EndIf
If ToCall = 0
If Right(thread_requested,1) = "/"
If Header(#http_head_request) = "/"
thread_requested = default_file
Else
thread_requested = thread_requested
EndIf
EndIf
If ToCall > 0 ;Dann ist eine Funktion hinterlegt und zulässig aufgerufen zu werden.
;{ Dynamischer WebHandler
Handler_Response = call_function(ToCallType, ToCall, Header())
If call_request(Host_call + thread_requested, #get_handler_library_perm) = 0 And Library_ID <> 0
CloseLibrary(Library_ID)
thread_requested = Header(#http_head_request)
EndIf
ldl::Logging("Main Client Response :"+Handler_Response)
MyThreadJSON = ParseJSON(#PB_Any, Handler_Response)
If MyThreadJSON
ClearMap(Response())
ExtractJSONMap(JSONValue(MyThreadJSON), Response())
FreeJSON(MyThreadJSON)
Else
;WTF ???
ldl::Logging("Fehler Absturz")
Break 2 ; Thread abschiessen
EndIf
ldl::Logging("Response Content:"+Response(#cha_R_ResponseContentType))
Select Response(#cha_R_ResponseContentType)
Case #response_Memory
ldl::Logging("Response Memory")
thread_data_size = Val(Response(#cha_R_MemorySize))
thread_temp_cache_memory = Val(Response(#cha_R_MemoryAdress))
thread_type = Response(#cha_R_ResponseType)
Case #response_string
ldl::Logging("Response String")
thread_temp_decode_memory = AllocateMemory(StringByteLength(Response(#cha_R_StringBase64)))
thread_data_size = Base64Decoder(Response(#cha_R_StringBase64), thread_temp_decode_memory, StringByteLength(Response(#cha_R_StringBase64)))
thread_temp_cache_memory = AllocateMemory(thread_data_size)
CopyMemory(thread_temp_decode_memory, thread_temp_cache_memory, thread_data_size)
FreeMemory(thread_temp_decode_memory)
thread_type = Response(#cha_R_ResponseType)
Default
;Solte ja nicht passieren.
EndSelect
ldl::Logging("Content Finished")
;}
; ElseIf configuration\cache\enable = 1
; ;{ Cached File Handling BUGGY!!!!!!!
; thread_temp_cache_memory = AllocateMemory(1024)
; thread_temp_cache = GetFileFromCache(thread_requested, thread_temp_cache_memory)
; If thread_temp_cache = #error_string
; thread_file_handle = ReadFile(#PB_Any, configuration\basedir + thread_requested,#PB_File_SharedRead)
;
; If thread_file_handle
; ;Alles Ok
; Else
; thread_file_handle = ReadFile(#PB_Any, configuration\basedir + configuration\defaultfile,#PB_File_SharedRead)
; ldl::Logging("FileDir:" + configuration\basedir + configuration\defaultfile)
; If Not thread_file_handle
; thread_file_handle = ReadFile(#PB_Any, "error.html")
; EndIf
;
; EndIf
; thread_data_size = Lof(thread_file_handle)
; thread_temp_cache_memory = ReAllocateMemory(thread_temp_cache_memory, thread_data_size)
; ReadData(thread_file_handle, thread_temp_cache_memory, thread_data_size)
; CloseFile(thread_file_handle)
; AddFileToCache(thread_temp_cache_memory, thread_requested, thread_data_size)
;
; Else
; thread_data_size = Val(StringField(thread_temp_cache, 1, ":"))
; thread_temp_cache_memory = Val(StringField(thread_temp_cache, 2, ":"))
; EndIf
; ;}
Else
;{ Uncached file sems to be stable tested up to 200 clients and 100 requests.
If file_check(thread_requested, m_clients(Str(thread_cli_id))\host_id) = thread_requested
thread_file_handle = ReadFile(#PB_Any, home_dir + thread_requested,#PB_File_SharedRead)
If Not thread_file_handle
thread_file_handle = ReadFile(#PB_Any, home_dir + default_file ,#PB_File_SharedRead)
ldl::Logging("FileDir:" + home_dir + default_file, ErrorLog)
If Not thread_file_handle
ldl::Logging("Error file set", ErrorLog)
thread_file_handle = ReadFile(#PB_Any, "error.html")
ldl::Logging("Requested:"+thread_requested)
ToCallType = call_request(Host_call + thread_requested, #get_handler_prototype)
If ToCallType = #handler_proto_universal Or ToCallType = #handler_proto_get Or ToCallType = #handler_proto_i_universal Or ToCallType = #handler_proto_i_get
ToCall = call_request(Host_call + thread_requested)
If call_request(Host_call + thread_requested, #get_handler_library_perm) = 0
LibraryToCall = call_request_string(Host_call + thread_requested, #get_handler_library_perm)
If Len(LibraryToCall) > 0
Library_ID = OpenLibrary(#PB_Any, LibraryToCall)
If Library_ID
ldl::Logging("Library is opened:"+LibraryToCall)
Else
ldl::Logging("Library could not be opened")
EndIf
EndIf
thread_data_size = Lof(thread_file_handle)
; Is File bigger than MaxFileSize in Memory allowed ?
If thread_data_size >= configuration\hosts(m_clients(Str(thread_cli_id))\host_id)\mem\MaxFileSize
;Do Handle the File another way.
thread_temp_cache_memory = AllocateMemory(configuration\hosts(m_clients(Str(thread_cli_id))\host_id)\mem\MaxFileSize)
thread_temp_file_readed = configuration\hosts(m_clients(Str(thread_cli_id))\host_id)\mem\DefaultBlockSize
thread_data_readed = ReadData(thread_file_handle, thread_temp_cache_memory, thread_temp_file_readed)
thread_data_to_read = thread_data_size - thread_data_readed
thread_oversized_file = #True
Else
thread_temp_cache_memory = AllocateMemory(thread_data_size)
ReadData(thread_file_handle, thread_temp_cache_memory, thread_data_size)
CloseFile(thread_file_handle)
thread_oversized_file = #False
EndIf
EndIf
Else
thread_redirect = #True
ToCall = 0
EndIf
;}
EndIf
If ToCall = 0
If Right(thread_requested,1) = "/"
thread_requested = default_file
Else
thread_requested = thread_requested
EndIf
EndIf
If ToCall > 0 ;Dann ist eine Funktion hinterlegt und zulässig aufgerufen zu werden.
;{ Dynamischer WebHandler
Handler_Response = call_function(ToCallType, ToCall, Header())
If call_request(Host_call + thread_requested, #get_handler_library_perm) = 0 And Library_ID <> 0
CloseLibrary(Library_ID)
EndIf
ldl::Logging("Main Client Response :"+Handler_Response)
MyThreadJSON = ParseJSON(#PB_Any, Handler_Response)
If MyThreadJSON
ClearMap(Response())
ExtractJSONMap(JSONValue(MyThreadJSON), Response())
FreeJSON(MyThreadJSON)
Else
;WTF ???
ldl::Logging("Fehler Absturz")
Break 2 ; Thread abschiessen
EndIf
ldl::Logging("Response Content:"+Response(#cha_R_ResponseContentType))
Select Response(#cha_R_ResponseContentType)
Case #response_Memory
ldl::Logging("Response Memory")
thread_data_size = Val(Response(#cha_R_MemorySize))
thread_temp_cache_memory = Val(Response(#cha_R_MemoryAdress))
thread_type = Response(#cha_R_ResponseType)
Case #response_string
ldl::Logging("Response String")
thread_temp_decode_memory = AllocateMemory(StringByteLength(Response(#cha_R_StringBase64)))
thread_data_size = Base64Decoder(Response(#cha_R_StringBase64), thread_temp_decode_memory, StringByteLength(Response(#cha_R_StringBase64)))
thread_temp_cache_memory = AllocateMemory(thread_data_size)
CopyMemory(thread_temp_decode_memory, thread_temp_cache_memory, thread_data_size)
FreeMemory(thread_temp_decode_memory)
thread_type = Response(#cha_R_ResponseType)
Default
;Solte ja nicht passieren.
EndSelect
ldl::Logging("Content Finished")
;}
; ElseIf configuration\cache\enable = 1
; ;{ Cached File Handling BUGGY!!!!!!!
; thread_temp_cache_memory = AllocateMemory(1024)
; thread_temp_cache = GetFileFromCache(thread_requested, thread_temp_cache_memory)
; If thread_temp_cache = #error_string
; thread_file_handle = ReadFile(#PB_Any, configuration\basedir + thread_requested,#PB_File_SharedRead)
;
; If thread_file_handle
; ;Alles Ok
; Else
; thread_file_handle = ReadFile(#PB_Any, configuration\basedir + configuration\defaultfile,#PB_File_SharedRead)
; ldl::Logging("FileDir:" + configuration\basedir + configuration\defaultfile)
; If Not thread_file_handle
; thread_file_handle = ReadFile(#PB_Any, "error.html")
; EndIf
;
; EndIf
; thread_data_size = Lof(thread_file_handle)
; thread_temp_cache_memory = ReAllocateMemory(thread_temp_cache_memory, thread_data_size)
; ReadData(thread_file_handle, thread_temp_cache_memory, thread_data_size)
; CloseFile(thread_file_handle)
; AddFileToCache(thread_temp_cache_memory, thread_requested, thread_data_size)
;
; Else
; thread_data_size = Val(StringField(thread_temp_cache, 1, ":"))
; thread_temp_cache_memory = Val(StringField(thread_temp_cache, 2, ":"))
; EndIf
; ;}
Else
;{ Uncached file sems to be stable tested up to 200 clients and 100 requests.
If file_check(thread_requested, m_clients(Str(thread_cli_id))\host_id) = thread_requested
thread_file_handle = ReadFile(#PB_Any, home_dir + thread_requested,#PB_File_SharedRead)
If Not thread_file_handle
thread_file_handle = ReadFile(#PB_Any, home_dir + default_file ,#PB_File_SharedRead)
ldl::Logging("FileDir:" + home_dir + default_file, ErrorLog)
If Not thread_file_handle
ldl::Logging("Error file set", ErrorLog)
thread_file_handle = ReadFile(#PB_Any, "error.html")
EndIf
EndIf
thread_data_size = Lof(thread_file_handle)
; Is File bigger than MaxFileSize in Memory allowed ?
If thread_data_size >= configuration\hosts(m_clients(Str(thread_cli_id))\host_id)\mem\MaxFileSize
;Do Handle the File another way.
thread_temp_cache_memory = AllocateMemory(configuration\hosts(m_clients(Str(thread_cli_id))\host_id)\mem\MaxFileSize)
thread_temp_file_readed = configuration\hosts(m_clients(Str(thread_cli_id))\host_id)\mem\DefaultBlockSize
thread_data_readed = ReadData(thread_file_handle, thread_temp_cache_memory, thread_temp_file_readed)
thread_data_to_read = thread_data_size - thread_data_readed
thread_oversized_file = #True
Else
thread_temp_cache_memory = AllocateMemory(thread_data_size)
ReadData(thread_file_handle, thread_temp_cache_memory, thread_data_size)
CloseFile(thread_file_handle)
thread_oversized_file = #False
EndIf
Else
thread_redirect = #True
EndIf
;}
EndIf
EndIf
;}
Case #http_method_post
@ -826,7 +897,7 @@ Module lhs_web
;{ POST Content Type Decoder
If LCase(Header(#http_head_content_type)) = #http_content_type_application_x_www_form_urlencoded
PostMapString = Work_Post_ToJSON_x_www_form_urlencoded(Val(Header(#http_head_content_length)), m_clients(Str(thread_cli_id))\datenbuffer()\Size, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer)
PostMapString = lhs_web_post::mem_x_www_form_urlencoded(Val(Header(#http_head_content_length)), m_clients(Str(thread_cli_id))\datenbuffer()\Size, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer)
MyThreadJSON = ParseJSON(#PB_Any, PostMapString)
If MyThreadJSON
ClearMap(Post())
@ -838,7 +909,7 @@ Module lhs_web
Break 2 ; Kill Thread
EndIf
ElseIf Left(LCase(Header(#http_head_content_type)), Len(#http_content_type_multipart_form_data)) = #http_content_type_multipart_form_data
PostMapString = Work_Post_ToJSON_multipart_form_data(Val(Header(#http_head_content_length)), m_clients(Str(thread_cli_id))\datenbuffer()\Size, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer)
PostMapString = lhs_web_post::mem_x_www_form_urlencoded(Val(Header(#http_head_content_length)), m_clients(Str(thread_cli_id))\datenbuffer()\Size, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer)
MyThreadJSON = ParseJSON(#PB_Any, PostMapString)
If MyThreadJSON
ClearMap(Post())
@ -859,7 +930,7 @@ Module lhs_web
EndIf
ldl::Logging("Requested:"+thread_requested)
ToCallType = call_request(Host_call+thread_requested, #get_handler_prototype)
If ToCallType = #handler_proto_universal Or ToCallType = #handler_proto_post
If ToCallType = #handler_proto_universal Or ToCallType = #handler_proto_post Or ToCallType = #handler_proto_i_universal Or ToCallType = #handler_proto_i_post
ToCall = call_request(Host_call + thread_requested)
ldl::Logging("A To Call is found:"+Str(ToCall))
If call_request(Host_call + thread_requested, #get_handler_library_perm) = 0
@ -1008,14 +1079,20 @@ Module lhs_web
ElseIf response_status <> ""
Header(#http_head_status) = response_status
Else
Header(#http_head_status) = status_get_message("200")
Header(#http_head_status) = status_get_header("200")
EndIf
If Response(#http_head_set_cookie) <> ""
Header(#http_head_set_cookie) = Response(#http_head_set_cookie)
EndIf
If thread_redirect = #True
Header(#http_head_redirect) = file_check(thread_requested, m_clients(Str(thread_cli_id))\host_id)
Header(#http_head_status) = status_get_message("303")
;TODO: Verify it's a file or a configuration ...
If Header(#http_head_redirect) = "configuration\errorfile404"
ldl::Logging("Error 404 : ["+configuration\status("404")\content+"]")
Header(#http_head_redirect) = ""
EndIf
Header(#http_head_status) = status_get_header("303")
Else
Header(#http_head_content_length) = Str(thread_data_size)
Header(#http_head_content_type) = thread_type
@ -1023,7 +1100,9 @@ Module lhs_web
Header(#http_head_connection) = "Keep-Alive"
Header(#http_head_keep_alive) = "timeout=15, max=1000"
thread_header = http_header_generate(Header())
ldl::Logging("Header:"+thread_header)
;large File Handling
If thread_redirect = #True
thread_buffer = AllocateMemory(StringByteLength(thread_header)+12)
@ -1045,7 +1124,7 @@ Module lhs_web
thread_temp_cache_memory = 0
ElseIf thread_temp_cache_memory <> 0 And thread_buffer_offset <> 0 And thread_data_size <> 0 And thread_temp_file_readed <> 0 And thread_oversized_file = #True And thread_redirect = #False
CopyMemory(thread_temp_cache_memory, thread_buffer_offset, thread_temp_file_readed)
ldl::Logging("Cache Address Memory:"+Str(thread_temp_cache_memory))
ldl::Logging("Oversized Cache Address Memory:"+Str(thread_temp_cache_memory))
FreeMemory(thread_temp_cache_memory)
thread_temp_cache_memory = 0
ElseIf thread_redirect = #True
@ -1076,8 +1155,8 @@ Module lhs_web
Else
sent_total = thread_temp_file_readed+(thread_buffer_offset-thread_buffer)
EndIf
;TODO: Stoped download kill server...
ldl::Logging("Memory send_total:"+Str(sent_total))
;Erledigt: Stoped download kill server...
If m_clients(Str(thread_cli_id))\client_type = #client_HTTPS
sent_length = sent_total
sent_buffer_address = thread_buffer
@ -1085,7 +1164,7 @@ Module lhs_web
Repeat
sent = tls::WriteTLSSocket(thread_cli_id, sent_buffer_address , sent_length)
If sent <> -1
;ldl::Logging("ClientID:" + Str(thread_cli_id) + " HTTPS Sent:"+Str(sent)+" bytes")
ldl::Logging("ClientID:" + Str(thread_cli_id) + " HTTPS Sent:"+Str(sent)+" bytes")
sent_length - sent
If thread_oversized_file = #False
sent_buffer_address + sent
@ -1093,14 +1172,14 @@ Module lhs_web
;Read next Block to Memory
If sent_length <= 0 And IsFile(thread_file_handle)
sent_readed = ReadData(thread_file_handle, thread_buffer, thread_temp_file_readed)
;ldl::Logging("ClientID:" + Str(thread_cli_id) + " HTTPS Large File -> Read Next:"+Str(sent_readed)+" bytes")
ldl::Logging("ClientID:" + Str(thread_cli_id) + " HTTPS Large File -> Read Next:"+Str(sent_readed)+" bytes")
If sent_readed < thread_temp_file_readed
CloseFile(thread_file_handle)
EndIf
sent_buffer_address = thread_buffer
sent_length = sent_readed
Else
;ldl::Logging("ClientID:" + Str(thread_cli_id) + " HTTPS Large File -> to Send:"+Str(sent_length)+" bytes")
ldl::Logging("ClientID:" + Str(thread_cli_id) + " HTTPS Large File -> to Send:"+Str(sent_length)+" bytes")
sent_buffer_address + sent
EndIf
EndIf
@ -1124,7 +1203,13 @@ Module lhs_web
sent_buffer_address = thread_buffer
sent_total = 0
Repeat
sent = lsocket::WriteSocket(thread_cli_id, thread_buffer , sent_length)
If lsocket::IsClientSocket(thread_cli_id)
sent = lsocket::WriteSocket(thread_cli_id, thread_buffer , sent_length)
Else
thread_alive=#False
Break 2
EndIf
If sent <> -1
ldl::Logging("HTTP Sent:"+Str(sent)+" bytes")
sent_length - sent
@ -1306,58 +1391,6 @@ Module lhs_web
ProcedureReturn Val(call_request_string(RequestString.s, Info.i))
EndProcedure
Procedure.s Work_Post_ToJSON_x_www_form_urlencoded(ContentLength.i, MemorSize.i, Memory.i)
Define.s JSONString, Working, ContentString
Define CountParams, Count, JSON
Protected NewMap Posts.s()
If ContentLength > 0
OffsetMemory = Memory + (MemorSize - ContentLength)
ContentString = PeekS(OffsetMemory, ContentLength, #PB_UTF8)
;Zerlegen &
;Mapname = Content
If Len(ContentString) > 0
CountParams = CountString(ContentString,"&")
If CountParams = 0
If CountString(ContentString, "=")
Posts(StringField(ContentString, 1, "=")) = StringField(ContentString,2, "=")
Else
ProcedureReturn ""
EndIf
ElseIf CountParams > 0
Count = 0
Repeat
Posts(StringField(StringField(ContentString, Count + 1, "&"),1,"=")) = StringField(StringField(ContentString, Count + 1, "&"),2,"=")
;ldl::Logging("Worked Count:"+Str(Count)+" of: "+Str(CountParams)+":"+StringField(StringField(ContentString, Count + 1, "&"),1,"=")+" = "+StringField(StringField(ContentString, Count + 1, "&"),2,"=")
Count + 1
Until Count > CountParams
Else
ProcedureReturn ""
EndIf
JSON = CreateJSON(#PB_Any)
If JSON
InsertJSONMap(JSONValue(JSON), Posts())
JSONString = ComposeJSON(JSON)
FreeMap(Posts())
FreeJSON(JSON)
ProcedureReturn JSONString.s
Else
ProcedureReturn #error_string
EndIf
Else
ProcedureReturn ""
EndIf
Else
ProcedureReturn ""
EndIf
EndProcedure
Procedure.s Work_Post_ToJSON_multipart_form_data(ContentLength.i, MemorySize.i, Memory.i)
ProcedureReturn "NA"
EndProcedure
Procedure.s register_client_handler(Route.s, Callback.i, AppPrototype.i = #handler_proto_get, RouteType.i = #handler_sub, Host.s = "")
If Len(Host) > 0
Host = "SpecServer:["+Host+"]"

179
lweb.pbp
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.purebasic.com/namespace" version="1.0" creator="PureBasic 6.01 LTS (Linux - x64)">
<project xmlns="http://www.purebasic.com/namespace" version="1.0" creator="PureBasic 6.12 LTS (Linux - x64)">
<section name="config">
<options closefiles="1" openmode="0" name="LiHaSo Webserver Modul"/>
<comment>Projekt ist inklusive Beispiel Code</comment>
@ -8,141 +8,155 @@
<section name="data">
<explorer view="../../../bin/purebasic/examples/" pattern="0"/>
<log show="1"/>
<lastopen date="2023-03-29 11:36" user="renlin" host="renlin-home"/>
<lastopen date="2024-09-30 17:05" user="renlin" host="renlin-office"/>
</section>
<section name="files">
<file name="build_tools/src/default_config_xml_export.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="0" panelstate="+--"/>
<fingerprint md5="03c865cac19c1ef8148ac229388df3b0"/>
</file>
<file name="build_tools/src/default_host_xml_export.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+--"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="1" panelstate="+--"/>
<fingerprint md5="e3e8de2f4e852905bf6410aad61d5565"/>
</file>
<file name="build_tools/src/status_xml_export.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+--"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="2" panelstate="+--"/>
<fingerprint md5="b8282147d13a268e39f6164f684c3169"/>
</file>
<file name="inc/lcmf_main.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="3" panelstate="+-"/>
<fingerprint md5="07b859104cbf3ef2df0b8a9cf3eeab32"/>
</file>
<file name="inc/lweb_file_cache.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="4" panelstate="+-"/>
<fingerprint md5="a3c3072e4eb0a8d09d9e02b2d57b707d"/>
</file>
<file name="inc/lweb_file_cache_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="0" panelstate="+-"/>
<fingerprint md5="3228c16f329808e2e6e3c6866861ae59"/>
</file>
<file name="inc/lweb_header_privat.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<fingerprint md5="1dc56f232d053dc5384ac9496368b257"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="5" panelstate="+-"/>
<fingerprint md5="2803c98024b9588db6f85d77f30023e1"/>
</file>
<file name="inc/lweb_helper.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<fingerprint md5="944c758e53a2b9d4bcf28ef931179d31"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="6" panelstate="+-"/>
<fingerprint md5="e6b5d486bd08b6de7f34a94316df2543"/>
</file>
<file name="lhs_lib/NET/lhs_web_helper.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="7" panelstate="+--"/>
<fingerprint md5="52ed1675b88a463b7ada8cf2003430e1"/>
</file>
<file name="inc/lweb_helper_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="0" panelstate="+-"/>
<fingerprint md5="c250ce791b691f679782e5016a3346be"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="8" panelstate="+-"/>
<fingerprint md5="6ea3e5baa62f8e66063e3b45e17d7e91"/>
</file>
<file name="inc/lweb_http.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="9" panelstate="+-"/>
<fingerprint md5="a42cddb6a1102779589facc17ba96cd8"/>
</file>
<file name="inc/lweb_http_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="10" panelstate="+-"/>
<fingerprint md5="d7df8e152291b0f91e8316ad8e00191c"/>
</file>
<file name="inc/lweb_http_status.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<fingerprint md5="cabf767d4a63c045f9ac4e7ca9e8f303"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="11" panelstate="+-"/>
<fingerprint md5="6f3a4e08bf4318407b547cb5ca794260"/>
</file>
<file name="inc/lweb_http_status_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<fingerprint md5="ad8d9313172646d803164eaa5431d2f4"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="12" panelstate="+-"/>
<fingerprint md5="6fd5131bd1dc2558e3abf2160fbef98c"/>
</file>
<file name="inc/lweb_http_status_header_private.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="13" panelstate="+-"/>
<fingerprint md5="c7736a7cdc87c1ed676b17d9757ba135"/>
</file>
<file name="inc/lweb_IP.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="14" panelstate="+-"/>
<fingerprint md5="502f26844f0a4b7d7f25924f76b17473"/>
</file>
<file name="inc/lweb_IP_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+-"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="15" panelstate="+-"/>
<fingerprint md5="636558037ff2cab03552fb129e2a4f52"/>
</file>
<file name="lhs_lib/SYS/lhs_log_ext.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+--"/>
<fingerprint md5="f37e027dbab8be85535563b3287f7fff"/>
</file>
<file name="lhttpd.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+"/>
<fingerprint md5="424692edd20ea5900da432a691fafd1d"/>
</file>
<file name="lweb.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+"/>
<fingerprint md5="66915c3206c429b1355c4d8bf521e3ea"/>
</file>
<file name="lweb_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+"/>
<fingerprint md5="10bdf9728cfc8057a3d9bcca61a9efa5"/>
</file>
<file name="server_example.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+"/>
<fingerprint md5="553b829778f085e9c06a37eab3bd98b5"/>
</file>
<file name="server_example_function.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="0" panelstate="+"/>
<fingerprint md5="20aeb237a42149a8260c89af41699bfb"/>
</file>
<file name="lhs_lib/NET/lhs_net_tls.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="0" panelstate="+--"/>
<fingerprint md5="c586d25a1493f437c7461374a891a715"/>
</file>
<file name="lhs_lib/NET/lhs_net_socket.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="0" panelstate="+--"/>
<fingerprint md5="3674a9181dad4f9f42c6eb9e7c407986"/>
</file>
<file name="lhs_lib/SYS/lhs_sys_debug_wrapper.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="0" panelstate="+--"/>
<fingerprint md5="8c3a929cf403d443ec968d21593294a5"/>
</file>
<file name="inc/lweb_server_cfg.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="0" panelstate="+-"/>
<fingerprint md5="1e525bdeabfad8faf29176465f5d2fa2"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="16" panelstate="+-"/>
<fingerprint md5="4ef74f56126e4dcbb66e51ac1fe2d605"/>
</file>
<file name="inc/lweb_server_cfg_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="0" panelstate="+-"/>
<fingerprint md5="27ac522c0b7e7b9c00cc9063084694ae"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="17" panelstate="+-"/>
<fingerprint md5="57787e1e3db6c77d81fc5576e124beae"/>
</file>
<file name="installation.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="18" panelstate="+"/>
<fingerprint md5="b5ba175b6bddf19d7c039396199911fd"/>
</file>
<file name="lhs_lib/NET/lhs_net_socket.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="19" panelstate="+--"/>
<fingerprint md5="9fc8219dabd4ed47be5289b435d089d6"/>
</file>
<file name="lhs_lib/NET/lhs_net_tls.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="20" panelstate="+--"/>
<fingerprint md5="c586d25a1493f437c7461374a891a715"/>
</file>
<file name="lhs_lib/SYS/lhs_log_ext.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="21" panelstate="+--"/>
<fingerprint md5="f37e027dbab8be85535563b3287f7fff"/>
</file>
<file name="lhs_lib/SYS/lhs_sys_debug_wrapper.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="22" panelstate="+--"/>
<fingerprint md5="8c3a929cf403d443ec968d21593294a5"/>
</file>
<file name="lhttpd.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="23" panelstate="+"/>
<fingerprint md5="f24daf76ff093910b9f4fb635d2a439c"/>
</file>
<file name="lweb.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="24" panelstate="+"/>
<fingerprint md5="c1c977e77f83f79bc4e6e2b64b0a6b77"/>
</file>
<file name="lweb_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="25" panelstate="+"/>
<fingerprint md5="53bf42c3a6e95d381fa49bc2d076946b"/>
</file>
<file name="server_example.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="26" panelstate="+"/>
<fingerprint md5="02bd1b26234f33a366ee312164beb638"/>
</file>
<file name="server_example_function.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="27" panelstate="+"/>
<fingerprint md5="5265cbd658ef5ff271bd2c6ea30b5713"/>
</file>
<file name="server_example_function_library.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="28" panelstate="+"/>
<fingerprint md5="bdf6276db9ea8921c3ef06ba10afdbb3"/>
</file>
<file name="build_tools/src/default_config_xml_export.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="999" panelstate="+--"/>
<fingerprint md5="03c865cac19c1ef8148ac229388df3b0"/>
</file>
<file name="inc/lweb_file_cache_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" sortindex="999" panelstate="+-"/>
<fingerprint md5="3228c16f329808e2e6e3c6866861ae59"/>
</file>
</section>
<section name="targets">
<target name="Standard-Ziel" enabled="1" default="1">
<target name="Standard-Ziel" enabled="1" default="0">
<inputfile value="server_example.pb"/>
<outputfile value="server_example"/>
<compiler version="PureBasic 6.01 LTS (Linux - x64)"/>
<compiler version="PureBasic 6.12 LTS - C Backend (Linux - x64)"/>
<executable value="server_example"/>
<options thread="1" xpskin="1" debug="1" optimizer="1"/>
<options thread="1" xpskin="1" debug="1" optimizer="0"/>
<format exe="console" cpu="0"/>
<debugger custom="1" type="ide"/>
</target>
<target name="lhttpd" enabled="1" default="0">
<target name="lhttpd" enabled="1" default="1">
<inputfile value="lhttpd.pb"/>
<outputfile value="lhttpd"/>
<compiler version="PureBasic 6.12 LTS (Linux - x64)"/>
<executable value="lhttpd"/>
<options thread="1" optimizer="0"/>
<options thread="1" debug="1" optimizer="0"/>
<format exe="console" cpu="0"/>
<debugger custom="1" type="standalone"/>
</target>
<target name="build_tools/status_xml_export" enabled="1" default="0">
<inputfile value="build_tools/src/status_xml_export.pb"/>
<outputfile value="build_tools/status_xml_export"/>
<compiler version="PureBasic 6.00 Beta 4 - C Backend (Linux - x64)"/>
<compiler version="PureBasic 6.12 LTS (Linux - x64)"/>
<executable value="build_tools/status_xml_export"/>
<options optimizer="1"/>
<options optimizer="0"/>
<format exe="console" cpu="0"/>
</target>
<target name="build_tools/default_config_xml_export" enabled="1" default="0">
@ -150,7 +164,7 @@
<outputfile value="build_tools/default_config_xml_export"/>
<compiler version="PureBasic 6.00 Beta 4 - C Backend (Linux - x64)"/>
<executable value="build_tools/default_config_xml_export"/>
<options optimizer="1"/>
<options optimizer="0"/>
<format exe="console" cpu="0"/>
</target>
<target name="build_tools/default_host_xml_export" enabled="1" default="0">
@ -158,14 +172,23 @@
<outputfile value="build_tools/default_host_xml_export"/>
<compiler version="PureBasic 6.00 Beta 4 - C Backend (Linux - x64)"/>
<executable value="build_tools/default_host_xml_export"/>
<options optimizer="1"/>
<options optimizer="0"/>
<format exe="console" cpu="0"/>
</target>
<target name="server_example_library_test" enabled="1" default="0">
<inputfile value="server_example_function_library.pb"/>
<outputfile value="testfunction.so"/>
<compiler version="PureBasic 6.01 LTS - C Backend (Linux - x64)"/>
<executable value="testfunction.so"/>
<options thread="1" optimizer="0"/>
<format exe="dll" cpu="0"/>
</target>
<target name="lhttpd installer" enabled="1" default="0">
<inputfile value="installation.pb"/>
<outputfile value="lhttpd_install"/>
<executable value="lhttpd_install"/>
<options optimizer="0"/>
<format exe="console" cpu="0"/>
</target>
</section>
</project>

167
lweb_auth.pb Normal file
View file

@ -0,0 +1,167 @@
;************************
;* lweb_auth.pb
;*
;* Simple Authentication Library.
;*
;* Created and develobed by Linder Hard- und Software
;*
;* First Release Only "demo" Database
XIncludeFile "lhs_lib/NET/lhs_web_helper.pbi"
Structure DB_Config
Type.i ;0=csv, 1=txt ,2=SQLite, 3=mar, 4=psq
File_Name.s
DB_Connection.s
DB_User.s
DB_Password.s
EndStructure
Structure Config
DB_User.DB_Config
DB_Session.DB_Config
EndStructure
Global.s ZumSenden
Global.s State
Global.s DB_Cfg
Global.s DB_Session
ProcedureCDLL init(Config_XML.s)
EndProcedure
ProcedureCDLL Database_User(DB_Cfg.s)
Select Left(DB_Cfg, 3)
Case "csv"
;csv:/path/to/file.csv
Case "txt"
;txt:/path/to/file.txt
Case "sli"
;sli:/path/to/sqliteDB.sqlite
Case "mar"
;mar:host=localhost port=3306 dbname=test user=|USERNAME| password=|PASSWORD|
Case "psq"
;psq:host=localhost port=5432 dbname=test user=|USERNAME| password=|PASSWORD|
Case "demo"
;Demo Accounts
; Grp. Usr. Pw. ID Mod
;|demo|admin|admin1234|0 |777|
;|demo|user |user1234 |1 |744|
;|demo|guest|guest1234|2 |004|
Default
State = "Failed"
ProcedureReturn @State
EndSelect
EndProcedure
ProcedureCDLL Database_Session(DB_Cfg.s)
Select Left(DB_Cfg, 3)
Case "csv"
;csv:/path/to/file.csv
Case "txt"
;txt:/path/to/file.txt
Case "sli"
;sli:/path/to/sqliteDB.sqlite
Case "mar"
;mar:host=localhost port=3306 dbname=test user=|USERNAME| password=|PASSWORD|
Case "psq"
;psq:host=localhost port=5432 dbname=test user=|USERNAME| password=|PASSWORD|
Default
State = "Failed"
ProcedureReturn @Failed
EndSelect
EndProcedure
Procedure.s GetUserFromDBCFG(DB_Cfg.s)
Protected Pos_Start, Pos_End, User_Name.s
Pos_Start = FindString(DB_Cfg, "user=|", 0) + Len("user=|")
Pos_End = FindString(DB_Cfg, "|", Pos_Start)
User_Name.s = Mid(DB_Cfg, Pos_Start, Pos_End-Pos_Start)
ProcedureReturn User_Name
EndProcedure
Procedure.s GetPassworfFromDBCFG(DB_Cfg.s)
Protected Pos_Start, Pos_End, User_Password.s
Pos_Start = FindString(DB_Cfg, "password=|", 0) + Len("password=|")
Pos_End = FindString(DB_Cfg, "|", Pos_Start)
User_Password.s = Mid(DB_Cfg, Pos_Start, Pos_End-Pos_Start)
ProcedureReturn User_Password
EndProcedure
Procedure.s CreateSession(ID.s)
EndProcedure
Procedure.s IsSession(SessionID.s)
EndProcedure
Procedure.s User_Verify(User.s)
EndProcedure
Procedure.s User_Login(User.s, Password.s)
EndProcedure
Procedure.s Get_MOD(SessionID.s)
EndProcedure
Procedure.s Get_Group(SessionID.s)
EndProcedure
Procedure.s Get_UseID(SessionID.s)
EndProcedure
ProcedureCDLL post_test(handler_Map_JSON.s, ContentData.s)
Define *Text
Define.s Encoded, TBD, Text, JSONStringToMap
Define MyThreadJSON, File
NewMap Header.s()
File = CreateFile(#PB_Any, "test.log")
WriteStringN(File, "handler_Map_JSON:")
WriteStringN(File, handler_Map_JSON)
WriteStringN(File, "Content Data:")
WriteStringN(File, ContentData)
JSONStringToMap = handler_Map_JSON
If JSONStringToMap <> lhs_web_helper::#error_string
MyThreadJSON = ParseJSON(#PB_Any, JSONStringToMap)
If MyThreadJSON
ClearMap(Header())
ExtractJSONMap(JSONValue(MyThreadJSON), Header())
FreeJSON(MyThreadJSON)
EndIf
EndIf
NewMap Response.s()
TBD="<div><div><h1>FormularPost</h1></div><br/>"+#CRLF$
ResetMap(Header())
While NextMapElement(Header())
TBD = TBD+"<div>"+MapKey(Header())+" : "+Header()+" </div><br/>"+#CRLF$
Wend
ContentData = URLDecoder(ContentData, #PB_UTF8)
Text = ~"<html lang=\"de\">" +
"<head>" +
~"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>" +
"<title>Alle Client Headers</title></header><body>"+TBD+"<hr/><br/><h1>ConentJSON</h1><br/>"+ContentData+"</body></html>"
*Text = AllocateMemory(StringByteLength(Text, #PB_UTF8))
PokeS(*Text, Text, -1, #PB_UTF8)
Encoded = Base64Encoder(*Text, MemorySize(*Text))
Response(lhs_web_helper::#cha_R_ResponseContentType) = lhs_web_helper::#response_string
Response(lhs_web_helper::#cha_R_StringBase64) = Encoded
Response(lhs_web_helper::#cha_R_ResponseType) = lhs_web_helper::mimetype("html")
Response(lhs_web_helper::#cha_R_http_head_status) = "200 Ok"
ZumSenden = lhs_web_helper::MapToJSONString(Response())
WriteStringN(File, "ZumSenden:")
WriteStringN(File, ZumSenden)
CloseFile(File)
ProcedureReturn @ZumSenden
EndProcedure

View file

@ -11,6 +11,8 @@
EnableExplicit
XIncludeFile "lhs_lib/NET/lhs_web_helper.pbi"
CompilerIf #PB_Compiler_Thread = 0
CompilerError "Muss Threadsicher Kompiliert werden"
CompilerEndIf

View file

@ -4,7 +4,7 @@
;*
;* HTTP/HTTPS example extended Server
;*
;* (c)2015 - 2023 by Linder Hard- und Software
;* (c)2015 - 2024 by Linder Hard- und Software
;*
;*
@ -36,7 +36,9 @@ lhs_log_ext::Init(DebugLog)
ldl::Register(lhs_log_ext::@Out(), DebugLog, 1, DebugLog, ldl::#AdvancedLog)
ldl::SetDefault(DebugLog)
ldl::Logging("Start Debug Log registered with ldl at UUID:"+DebugLog)
ldl::Logging("-------------------------------------------------------------------------------------------------------------------------------")
ldl::Logging("Server initializing.")
ldl::Logging("-------------------------------------------------------------------------------------------------------------------------------")
Debuggings = lhs_web::get_config(lhs_web::#conf_Debug_logUUID)
Debug Debuggings
;*
@ -64,6 +66,7 @@ PrintN("Configuration read done.")
;*
PrintN("Start the Server")
lhs_web::main_server(0)
If lhs_web::server_start()
ldl::Logging("Server started")
Else
@ -75,6 +78,9 @@ counter = 0
PrintN("Server_Sample started.")
PrintN("Press Enter to Exit")
Input()
ldl::Logging("-------------------------------------------------------------------------------------------------------------------------------")
ldl::Logging("Server Stopped.")
ldl::Logging("-------------------------------------------------------------------------------------------------------------------------------")
lhs_log_ext::StopAllLogger()
lhs_web::server_stop()
PrintN("Finished")

View file

@ -16,7 +16,7 @@ ProcedureCDLL post_test(handler_Map_JSON.s, ContentData.s)
Define.s Encoded, TBD, Text, JSONStringToMap
Define MyThreadJSON, File
NewMap Header.s()
File = CreateFile(#PB_Any, "test.log")
File = CreateFile(#PB_Any, "/var/log/lhttpd/post_test.log")
WriteStringN(File, "handler_Map_JSON:")
WriteStringN(File, handler_Map_JSON)
WriteStringN(File, "Content Data:")
@ -42,7 +42,7 @@ ProcedureCDLL post_test(handler_Map_JSON.s, ContentData.s)
Text = ~"<html lang=\"de\">" +
"<head>" +
~"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>" +
"<title>Alle Client Headers</title></header><body>"+TBD+"<hr/><br/><h1>ConentJSON</h1><br/>"+ContentData+"</body></html>"
"<title>Alle Client Headers</title></header><body>"+TBD+"<hr/><br/><h1>Conent in JSON Format</h1><br/>"+ContentData+"</body></html>"
*Text = AllocateMemory(StringByteLength(Text, #PB_UTF8))
PokeS(*Text, Text, -1, #PB_UTF8)
Encoded = Base64Encoder(*Text, MemorySize(*Text))