Compare commits

...

78 Commits

Author SHA1 Message Date
René Linder 8dc6ba4f77 Add HTTP request methods abd Debug for sucessfull Library Load 2024-03-15 13:27:20 +01:00
René Linder a9595720c6 Add ICO mimetype 2024-03-13 09:24:00 +01:00
René Linder 7b315bcc25 Bugfixes 2024-03-13 09:23:28 +01:00
René Linder edccdf62cd Merge remote-tracking branch 'refs/remotes/origin/main' 2024-03-11 10:13:50 +01:00
René Linder 01b51210ee Installation Fix and Cleanup 2024-03-11 10:10:20 +01:00
René Linder ce2a5d4e1a Activate the new module 2023-07-18 08:59:36 +02:00
René Linder ce41a4cd23 Remove post decoder from main and create new module 2023-07-18 08:58:51 +02:00
René Linder 077531d4c8 Refreshed Project 2023-07-17 15:55:10 +02:00
René Linder a56ef8a63d Update lib 2023-07-17 15:53:41 +02:00
René Linder 34c68fa985 add new definitions 2023-07-17 15:47:38 +02:00
René Linder 26426f7d3d First auth 2023-05-17 18:02:54 +02:00
René Linder d1b24f5f97 Websocket Prototype 2023-03-31 12:46:49 +02:00
René Linder 8574b29021 Initial Websocket and Bugfix for prototype support 2023-03-31 10:40:32 +02:00
René Linder 194245d3b6 add lhs_web_helper lib to lweb_header 2023-03-31 10:08:28 +02:00
René Linder 82d6998c7c lhs_lib connection constants 2023-03-31 10:07:44 +02:00
René Linder 45e484db30 Update lhs_lib for latests state codes 2023-03-31 09:54:49 +02:00
René Linder 5eaea5a2e6 Update old TODO list 2023-03-31 08:49:32 +02:00
René Linder 9822988941 New build target (Installer) 2023-03-30 15:55:04 +02:00
René Linder 65dd638294 new install standards 2023-03-30 15:47:31 +02:00
René Linder ab08722bcf New lhttp main 2023-03-30 15:46:01 +02:00
René Linder ce46b5c8de Log Bugfix .... 2023-03-30 15:40:27 +02:00
René Linder 61342616b4 new install routine .... alpha release git add installation.pb ! 2023-03-30 15:34:18 +02:00
René Linder 5d82ee5704 New lhttpd Release of main application 2023-03-30 10:49:06 +02:00
René Linder beef8490f5 Rework Configuration Load, it is possible to set directly a xml String or a file 2023-03-30 09:55:55 +02:00
René Linder e8651f7602 Rework dynamic and procedure function call 2023-03-30 09:46:13 +02:00
René Linder dab5de5edb Add internal Procedure functions 2023-03-30 09:44:56 +02:00
René Linder be7ad5e1c7 Remove old ini configuration 2023-03-30 09:43:42 +02:00
René Linder ccbfa29588 Use the lhs_lib helper library now 2023-03-30 08:28:45 +02:00
René Linder c949699f9c Update to the latest lhs_lib 2023-03-30 08:25:58 +02:00
René Linder 9fbe1146ae New build target and other small changes 2023-03-29 20:06:25 +02:00
René Linder 0b540f0fa7 First Dynamic Handler release 2023-03-29 20:06:01 +02:00
René Linder 22b40bd09e Add header info for Dynamic Handling 2023-03-29 20:04:59 +02:00
René Linder b50bc0a1a0 Update default config 2023-03-29 20:03:54 +02:00
René Linder b89f00318c Remove the post_test handler 2023-03-29 20:03:17 +02:00
René Linder 0148ec2859 Add a separate Library (Dll/so) for function for Dynamic Load 2023-03-29 20:02:31 +02:00
René Linder e619f73a89 latest hashes and added files in the project file 2023-03-29 10:48:04 +02:00
René Linder ba837a4825 New Currently working lweb server enviroment 2023-03-29 10:47:34 +02:00
René Linder fe28ebae1c New Multi Host/Server and XML configurationlayer 2023-03-29 10:46:56 +02:00
René Linder 68a0fbc990 Logger Change in lhttpd - didn't work this way currently 2023-03-29 10:45:53 +02:00
René Linder 18de367ae5 Add extended Logger function 2023-03-29 10:44:52 +02:00
René Linder f342610c4b Add Remarks thats only HTTP/1.1 Header Compatibility 2023-03-29 10:44:30 +02:00
René Linder d22652cd92 added XML Debug String function and fix file selector 2023-03-29 10:43:54 +02:00
René Linder 6a57a9f393 Removal of old caching 2023-03-29 10:41:36 +02:00
René Linder 72fc4436c9 Missing server_config xml 2023-03-29 10:40:53 +02:00
René Linder cfec9a7e9d Updated header and added private header 2023-03-29 10:40:17 +02:00
René Linder fe6245e6a1 Status and Config XML uploaded 2023-03-29 10:39:26 +02:00
René Linder 5aa5b4b51d Build Tools Update 2023-03-29 10:38:48 +02:00
René Linder 6c9fdce488 More separated Configuration functions 2023-03-29 10:37:51 +02:00
René Linder d892791ab6 Separate http status functions 2023-03-29 10:37:20 +02:00
René Linder 1e0ca0b1b1 New XML Config files and configuration of server to separate includes 2023-03-29 10:36:42 +02:00
René Linder 2620fffeee Update lhs_lib to latest bugfix release 2023-03-29 10:34:48 +02:00
René Linder a8615e45ae Server Configuration for sample 2023-03-27 17:43:46 +02:00
René Linder 96af06143e Removed Remarks 2023-03-27 17:42:23 +02:00
René Linder 2827ee8a78 New server_example 2023-03-27 17:38:13 +02:00
René Linder ae8cc74d27 Remove included librarys which are no in lhs_lib 2023-03-27 17:29:17 +02:00
René Linder dc4e8266b5 Update lhs_lib 2023-03-27 17:27:03 +02:00
René Linder 73d7e85542 XML HTTP Status Export for import to next release 2022-02-21 11:54:15 +01:00
René Linder d9f7a3fb0c Update lhs_lib 2022-02-21 08:27:05 +01:00
René Linder 9ef376da1d If a Headerline has another : don't cut off there #6 2022-02-20 13:45:32 +01:00
René Linder 88b2126db5 Cleanup Header all the same with : ending #6 2022-02-20 13:40:15 +01:00
René Linder 5ad5d95e05 Last Header line missed #6 2022-02-20 13:28:31 +01:00
René Linder 88582f0b84 Update project file 2022-02-18 16:09:45 +01:00
René Linder 78a0c42f9e index file should never be with beginning /... and rename startup message 2022-02-18 16:08:53 +01:00
René Linder 8e335d7da1 Redirect on Directory to subdirectory with default index file 2022-02-18 16:05:48 +01:00
René Linder 3a7183a391 Bugfixes UTF8 Encoding... 2022-02-17 15:30:51 +01:00
René Linder a78508440f Add gz MIME Type 2022-02-17 15:30:17 +01:00
René Linder 2f44cf1149 Make Large File Handling configurable and Default from 5MiB to 512KiB and BlockSize from 3MiB to 64KiB 2022-02-17 14:20:25 +01:00
René Linder 11ea5611bb changed submodule to https 2022-02-17 13:40:53 +01:00
René Linder d3a12eaa23 Large File Support Tested with 6 GiB Files 2022-02-17 13:23:42 +01:00
René Linder 421dc9b04f Add other Types and change default 2022-02-17 13:21:13 +01:00
René Linder 50a09dfe02 Updated 32bit libraries and typo 2022-02-17 13:20:19 +01:00
René Linder 7c9a610f47 when a large file Download was stoped the Server exited with SIGPIPE - fixed 2022-02-17 13:19:46 +01:00
René Linder 2ce4902b39 Add Version 22 to libtls.so 2022-02-14 15:49:50 +01:00
René Linder c5200f4273 Add log to ignorelist 2022-02-14 15:49:21 +01:00
René Linder 98401760e6 Add Ignore Files for local dev 2022-02-14 15:05:59 +01:00
René Linder 9aa3b8aa6d missing space 2022-02-14 15:00:13 +01:00
René Linder dc95017cf8 Cachelog added 2021-06-06 09:49:08 +02:00
René Linder 0c032cfa9d Typo createini.pb 2021-06-06 09:04:05 +02:00
48 changed files with 3461 additions and 1368 deletions

12
.gitignore vendored
View File

@ -21,4 +21,16 @@ project.cfg
*.out
# End of https://www.gitignore.io/api/purebasic
# Zertifikate
*.pem
democert
# Logs
*.log
# Executables
lhttpd
lhttpd_install
server_example
test
README

2
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "lhs_lib"]
path = lhs_lib
url = ssh://git@gitea.lihaso.com:3001/PB_Includes/lhs_lib.git
url = https://gitea.lihaso.com/PB_Includes/lhs_lib.git

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

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,142 @@
OpenConsole("Write Default HTTP Config XML Server")
PrintN("Create default_http_config.xml...")
Structure server_http
enabled.i
port.i
binding.s
max_clients.i
reuse.b
thread_id.i
EndStructure
Structure server_https
enabled.i
port.i
binding.s
max_clients.i
reuse.b
CA.s
Certs.s
key.s
key_pass.s
thread_id.i
EndStructure
Structure server_cache
time.i
maxsize.i
current.i
enable.i
EndStructure
Structure memory
MaxFileSize.i
DefaultBlockSize.i
EndStructure
Structure log_config
DebuglogUUID.s
Debugdisable.i
Accesslog.s
AccesslogUUID.s
Errorlog.s
ErrorlogUUID.s
Cachelog.s
CachelogUUID.s
EndStructure
Enumeration http_header_fieldtype
#http_header_field_Static ;Fieldcontent could be directly used
#http_header_field_Dynamic_auto ;Must be handled by the Fieldcontent_proc
EndEnumeration
Enumeration http_headerfield_param
#http_headerfield_param_string
#http_headerfield_param_map
#http_headerfield_param_integer
EndEnumeration
Structure http_headerfield_params
Type.i ;Types of Field #Content or #Map
Content_string.s ;String Field
Map Content_Maps.s() ;Map Field
Content_integer.i ;Integer Field
EndStructure
Structure http_headerfield
Fieldname.s ; Name bevore : for ex. "keep-alive:"
Fieldcontent.s ; Content after : for ex. "Keep-Alive"
Fieldcontent_type.i ; #http_header_field_Static or #http_header_field_Dynamic_auto
Fieldcontent_proc.i ; A Procedure Prototype to call
Map Field_proc_parameters.http_headerfield_params() ;Parameters to give to call
EndStructure
XIncludeFile "../../inc/lweb_http_status_header_private.pbi"
Structure host
description.s
http.server_http
https.server_https
cache.server_cache
log.log_config
mem.memory
defaultfile.s
basedir.s
Map status.http_status_codes() ;Individual Error Messages and Headers
EndStructure
Structure config_loader
name.s
type.s
EndStructure
Structure server
Map hosts.host()
Map status.http_status_codes() ;Default Error Messages and Headers
Map config_file.config_loader() ;Map Key is Type and string is file
log.log_config
mem.memory
global_max_cli_threads.i ;The maximum Thread Count = 0 unlimited
global_max_cli_memory.i ;The maximum Used Memory per Client Thread = 0 unlimited
version.s
identifikation.s
type.i
EndStructure
;}
;*
;*
;* Identifikation des Servers.
;*
Global configuration.server
configuration\version = "V0.9"
configuration\identifikation = "LiHaSo Webserver " + configuration\version
configuration\config_file("status_xml")\name = "cfg/default_http_status_codes.xml"
configuration\config_file("status_xml")\type = "file"
configuration\config_file("hosts_dir")\name = "cfg/server/"
configuration\config_file("hosts_dir")\type = "dir"
;*
;* Diese Parameter müssen entsprechend angepasst sein.
;* Später ausgelagert in ein nicht synchronisiertes lweb-cfg.pbi
;* Folgende Parameter müssen im Hauptprogramm definiert sein.
configuration\type = 0
configuration\global_max_cli_memory = 0 ; Unlimited
configuration\global_max_cli_threads = 0 ; Unlimited
If CreateXML(0)
InsertXMLStructure(RootXMLNode(0), @configuration, server)
FormatXML(0, #PB_XML_ReFormat)
ToSave.s = ComposeXML(0)
EndIf
CreateFile(0, "../cfg/default_http_config.xml")
WriteString(0, ToSave)
PrintN("Default config xml created: default_http_config.xml")
End

View File

@ -0,0 +1,44 @@
OpenConsole("Write Default Host Config XML Server")
PrintN("Create default_host.xml...")
IncludeFile "../../inc/lweb_header_privat.pbi"
Global host.host
host\description = "Default Server"
host\defaultfile = "index.html"
host\basedir = "/srv/lweb-srv/"
host\http\max_clients = 10 ; Max sametime HTTP connections.
host\http\port = 8080
host\http\binding = "127.0.0.1"
host\https\max_clients = 100
host\https\port = 8443
host\https\binding = "127.0.0.1"
host\https\enabled = 0
host\https\CA = "fullchain.pem"
host\https\Certs = "cert.pem"
host\https\key = "privkey.pem"
host\https\key_pass = ""
host\cache\enable = 0 ; Enable / Disable Cached Server
host\cache\time = 120 ; TTL of cached files
host\cache\maxsize = 1 ; Max Cache
host\cache\current = 0 ;
host\log\AccesslogFile = "/var/log/lhttpd/default_access.log"
host\log\CachelogFile = "/var/log/lhttpd/default_cache.log"
host\log\ErrorlogFile = "/var/log/lhttpd/default_error.log"
host\log\DebuglogFile = "/var/log/lhttpd/default_debug.log"
host\mem\MaxFileSize = 524288 ; Default 512 KiB
host\mem\DefaultBlockSize = 65536 ; Default Blocksize 64 KiB
If CreateXML(0)
InsertXMLStructure(RootXMLNode(0), @host, host)
ExtractXMLStructure(0, @host, host, #PB_XML_NoCase)
FormatXML(0, #PB_XML_ReFormat)
ToSave.s = ComposeXML(0)
EndIf
CreateFile(0, "../cfg/hosts/default_host.xml")
WriteString(0, ToSave)
PrintN("Default config xml created: default_host.xml")
End

View File

@ -0,0 +1,125 @@
OpenConsole("Write Default HTTP Status Code XML Server")
PrintN("Create default_http_status_codes.xml...")
Enumeration http_header_fieldtype
#http_header_field_Static ;Fieldcontent could be directly used
#http_header_field_Dynamic_auto ;Must be handled by the Fieldcontent_proc
EndEnumeration
Enumeration http_headerfield_param
#http_headerfield_param_string
#http_headerfield_param_map
#http_headerfield_param_integer
EndEnumeration
Structure http_headerfield_params
Type.i ;Types of Field #Content or #Map
Content_string.s ;String Field
Map Content_Maps.s() ;Map Field
Content_integer.i ;Integer Field
EndStructure
Structure http_headerfield
Fieldname.s ; Name bevore : for ex. "keep-alive:"
Fieldcontent.s ; Content after : for ex. "Keep-Alive"
Fieldcontent_type.i ; #http_header_field_Static or #http_header_field_Dynamic_auto
Fieldcontent_proc.i ; A Procedure Prototype to call
Map Field_proc_parameters.http_headerfield_params() ;Parameters to give to call
EndStructure
Structure http_status_codes
status.s ;Error Number
file.s ;Error File or "Integrated" for default Message as Template
header.s ;Error Header message for #http_head_status
message.s ;Error Message for Templated
message_body.s ;Error Message Body for Templated
template.b ;Is it a Template {ErrorNo}=error and {Message}=message and {Message_body}=message_body need to be there
content.b ;has it a content to send. (200 for ex. has no content who need to be processed.)
Map head_fields.http_headerfield()
EndStructure
Structure config
Map status.http_status_codes()
EndStructure
Global configuration.config
configuration\status("200")\status = "200"
configuration\status("200")\file = ""
configuration\status("200")\header = "200 Ok"
configuration\status("200")\message = ""
configuration\status("200")\template = #False
configuration\status("200")\content = #False
;3xx
configuration\status("303")\status = "303"
configuration\status("303")\file = ""
configuration\status("303")\header = "303 See Other"
configuration\status("303")\message = ""
configuration\status("303")\template = #False
configuration\status("303")\content = #False
;4xx
configuration\status("400")\status = "400"
configuration\status("400")\file = "integrated"
configuration\status("400")\header = "400 Bad Request"
configuration\status("400")\message = "400 Bad Request"
configuration\status("400")\template = #True
configuration\status("400")\content = #True
configuration\status("403")\status = "403"
configuration\status("403")\file = "integrated"
configuration\status("403")\header = "403 Forbidden"
configuration\status("403")\message = "403 Forbidden"
configuration\status("403")\template = #True
configuration\status("403")\content = #True
configuration\status("404")\status = "404"
configuration\status("404")\file = "integrated"
configuration\status("404")\header = "404 Not Found"
configuration\status("404")\message = "404 Not Found"
configuration\status("404")\template = #True
configuration\status("404")\content = #True
;5xx
configuration\status("500")\status = "500"
configuration\status("500")\file = "integrated"
configuration\status("500")\header = "500 Internal Server Error"
configuration\status("500")\message = "500 Internal Server Error"
configuration\status("500")\template = #True
configuration\status("500")\content = #True
configuration\status("501")\status = "501"
configuration\status("501")\file = "integrated"
configuration\status("501")\header = "501 Not Implemented"
configuration\status("501")\message = "501 Not Implemented"
configuration\status("501")\template = #True
configuration\status("501")\content = #True
configuration\status("502")\status = "502"
configuration\status("502")\file = "integrated"
configuration\status("502")\header = "502 Bad Gateway"
configuration\status("502")\message = "502 Bad Gateway"
configuration\status("502")\template = #True
configuration\status("502")\content = #True
configuration\status("503")\status = "503"
configuration\status("503")\file = "integrated"
configuration\status("503")\header = "503 Service Unavailable"
configuration\status("503")\message = "503 Service Unavailable"
configuration\status("503")\template = #True
configuration\status("503")\content = #True
If CreateXML(0)
InsertXMLMap(RootXMLNode(0), configuration\status())
FormatXML(0, #PB_XML_ReFormat)
ToSave.s = ComposeXML(0)
EndIf
CreateFile(0, "../cfg/default_http_status_codes.xml")
WriteString(0, ToSave)
PrintN("Default status codes xml created: default_http_status_codes.xml")
End

BIN
build_tools/status_xml_export Executable file

Binary file not shown.

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-16"?>
<server>
<hosts/>
<status/>
<config_file>
<element key="status_xml">
<name>cfg/default_http_status_codes.xml</name>
<type>file</type>
</element>
<element key="hosts_dir">
<name>cfg/server/</name>
<type>dir</type>
</element>
</config_file>
<log>
<DebuglogUUID/>
<Debugdisable>0</Debugdisable>
<Accesslog/>
<AccesslogUUID/>
<Errorlog/>
<ErrorlogUUID/>
<Cachelog/>
<CachelogUUID/>
</log>
<mem>
<MaxFileSize>0</MaxFileSize>
<DefaultBlockSize>0</DefaultBlockSize>
</mem>
<global_max_cli_threads>0</global_max_cli_threads>
<global_max_cli_memory>0</global_max_cli_memory>
<version>V0.9</version>
<identifikation>LiHaSo Webserver V0.9</identifikation>
<type>0</type>
</server>

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-16"?>
<map>
<element key="400">
<status>400</status>
<file>integrated</file>
<header>400 Bad Request</header>
<message>400 Bad Request</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="403">
<status>403</status>
<file>integrated</file>
<header>403 Forbidden</header>
<message>403 Forbidden</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="404">
<status>404</status>
<file>integrated</file>
<header>404 Not Found</header>
<message>404 Not Found</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="303">
<status>303</status>
<file/>
<header>303 See Other</header>
<message/>
<message_body/>
<template>0</template>
<content>0</content>
<head_fields/>
</element>
<element key="200">
<status>200</status>
<file/>
<header>200 Ok</header>
<message/>
<message_body/>
<template>0</template>
<content>0</content>
<head_fields/>
</element>
<element key="500">
<status>500</status>
<file>integrated</file>
<header>500 Internal Server Error</header>
<message>500 Internal Server Error</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="501">
<status>501</status>
<file>integrated</file>
<header>501 Not Implemented</header>
<message>501 Not Implemented</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="502">
<status>502</status>
<file>integrated</file>
<header>502 Bad Gateway</header>
<message>502 Bad Gateway</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="503">
<status>503</status>
<file>integrated</file>
<header>503 Service Unavailable</header>
<message>503 Service Unavailable</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
</map>

35
cfg/hosts/default.xml Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-16"?>
<host>
<description>Sample Server</description>
<http>
<enabled>1</enabled>
<port>80</port>
<binding>0.0.0.0</binding>
<max_clients>100</max_clients>
<reuse>0</reuse>
</http>
<https>
<enabled>0</enabled>
</https>
<cache>
<time>120</time>
<maxsize>1</maxsize>
<current>0</current>
<enable>0</enable>
</cache>
<log>
<DebuglogFile>/var/log/lhttpd/default_debug.log</DebuglogFile>
<Debugdisable>0</Debugdisable>
<AccesslogFile>/var/log/lhttpd/default_access.log</AccesslogFile>
<ErrorlogFile>/var/log/lhttpd/default_error.log</ErrorlogFile>
</log>
<mem>
<MaxFileSize>524288</MaxFileSize>
<DefaultBlockSize>65536</DefaultBlockSize>
</mem>
<dynamichandler/>
<defaultfile>index.html</defaultfile>
<basedir>/var/lib/lhttpd/default/</basedir>
<status/>
</host>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-16"?>
<host>
<description>Default Server</description>
<http>
<enabled>0</enabled>
<port>8080</port>
<binding>127.0.0.1</binding>
<max_clients>10</max_clients>
<reuse>0</reuse>
<thread_id>0</thread_id>
</http>
<https>
<enabled>0</enabled>
<port>8443</port>
<binding>127.0.0.1</binding>
<max_clients>100</max_clients>
<reuse>0</reuse>
<CA>fullchain.pem</CA>
<Certs>cert.pem</Certs>
<key>privkey.pem</key>
<key_pass/>
<thread_id>0</thread_id>
</https>
<cache>
<time>120</time>
<maxsize>1</maxsize>
<current>0</current>
<enable>0</enable>
</cache>
<log>
<DebuglogUUID/>
<DebuglogFile>/var/log/lhttpd/default_debug.log</DebuglogFile>
<Debugdisable>0</Debugdisable>
<AccesslogFile>/var/log/lhttpd/default_access.log</AccesslogFile>
<AccesslogUUID/>
<ErrorlogFile>/var/log/lhttpd/default_error.log</ErrorlogFile>
<ErrorlogUUID/>
<CachelogFile>/var/log/lhttpd/default_cache.log</CachelogFile>
<CachelogUUID/>
</log>
<mem>
<MaxFileSize>524288</MaxFileSize>
<DefaultBlockSize>65536</DefaultBlockSize>
</mem>
<defaultfile>index.html</defaultfile>
<basedir>/srv/lweb-srv/</basedir>
<status/>
</host>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-16"?>
<host>
<description>Default Server</description>
<http>
<enabled>0</enabled>
<port>8080</port>
<binding>127.0.0.1</binding>
<max_clients>10</max_clients>
<reuse>0</reuse>
<thread_id>0</thread_id>
</http>
<https>
<enabled>0</enabled>
<port>8443</port>
<binding>127.0.0.1</binding>
<max_clients>100</max_clients>
<reuse>0</reuse>
<CA>fullchain.pem</CA>
<Certs>cert.pem</Certs>
<key>privkey.pem</key>
<key_pass/>
<thread_id>0</thread_id>
</https>
<cache>
<time>120</time>
<maxsize>1</maxsize>
<current>0</current>
<enable>0</enable>
</cache>
<log>
<DebuglogUUID/>
<DebuglogFile>/var/log/lhttpd/default_debug.log</DebuglogFile>
<Debugdisable>0</Debugdisable>
<AccesslogFile>/var/log/lhttpd/default_access.log</AccesslogFile>
<AccesslogUUID/>
<ErrorlogFile>/var/log/lhttpd/default_error.log</ErrorlogFile>
<ErrorlogUUID/>
<CachelogFile>/var/log/lhttpd/default_cache.log</CachelogFile>
<CachelogUUID/>
</log>
<mem>
<MaxFileSize>524288</MaxFileSize>
<DefaultBlockSize>65536</DefaultBlockSize>
</mem>
<defaultfile>index.html</defaultfile>
<basedir>/srv/lweb-srv/</basedir>
<status/>
</host>

54
cfg/hosts/sample.xml Normal file
View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-16"?>
<host>
<description>Sample Server</description>
<http>
<enabled>1</enabled>
<port>8085</port>
<binding>0.0.0.0</binding>
<max_clients>100</max_clients>
<reuse>0</reuse>
</http>
<https>
<enabled>1</enabled>
<port>8445</port>
<binding>0.0.0.0</binding>
<max_clients>100</max_clients>
<reuse>0</reuse>
<CA>fullchain.pem</CA>
<Certs>cert.pem</Certs>
<key>privkey.pem</key>
<key_pass/>
</https>
<cache>
<time>120</time>
<maxsize>1</maxsize>
<current>0</current>
<enable>0</enable>
</cache>
<log>
<DebuglogFile>default_debug.log</DebuglogFile>
<Debugdisable>0</Debugdisable>
<AccesslogFile>default_access.log</AccesslogFile>
<ErrorlogFile>default_error.log</ErrorlogFile>
<CachelogFile>default_cache.log</CachelogFile>
</log>
<mem>
<MaxFileSize>524288</MaxFileSize>
<DefaultBlockSize>65536</DefaultBlockSize>
</mem>
<dynamichandler>
<element key="/post_test">
<functiontype>Universal</functiontype>
<file>/home/renlin/dev/LiHaSo/lweb/testfunction.so</file>
<proc>post_test</proc>
<routetype>handler_only</routetype>
<url>/post_test</url>
<extension/>
<permlib>false</permlib>
</element>
</dynamichandler>
<defaultfile>index.html</defaultfile>
<basedir>/home/renlin/testweb/</basedir>
<status/>
</host>

43
cfg/hosts/sample.xml_ Normal file
View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-16"?>
<host>
<description>Sample Server</description>
<http>
<enabled>1</enabled>
<port>8084</port>
<binding>0.0.0.0</binding>
<max_clients>100</max_clients>
<reuse>0</reuse>
</http>
<https>
<enabled>1</enabled>
<port>8446</port>
<binding>0.0.0.0</binding>
<max_clients>100</max_clients>
<reuse>0</reuse>
<CA>fullchain.pem</CA>
<Certs>cert.pem</Certs>
<key>privkey.pem</key>
<key_pass/>
</https>
<cache>
<time>120</time>
<maxsize>1</maxsize>
<current>0</current>
<enable>0</enable>
</cache>
<log>
<DebuglogFile>default_debug.log</DebuglogFile>
<Debugdisable>0</Debugdisable>
<AccesslogFile>default_access.log</AccesslogFile>
<ErrorlogFile>default_error.log</ErrorlogFile>
<CachelogFile>default_cache.log</CachelogFile>
</log>
<mem>
<MaxFileSize>524288</MaxFileSize>
<DefaultBlockSize>65536</DefaultBlockSize>
</mem>
<defaultfile>index.html</defaultfile>
<basedir>/home/renlin/testweb/</basedir>
<status/>
</host>

37
cfg/lhttpd.xml Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-16"?>
<server>
<hosts/>
<status/>
<config_file>
<element key="status_xml">
<name>/etc/lhttpd/default_http_status_codes.xml</name>
<type>file</type>
<configtype>status_xml</configtype>
</element>
<element key="host_file">
<name>/etc/lhttpd/hosts/default.xml</name>
<type>file</type>
<configtype>host_file</configtype>
</element>
</config_file>
<log>
<DebuglogUUID/>
<Debugdisable>0</Debugdisable>
<Accesslog/>
<AccesslogUUID/>
<Errorlog/>
<ErrorlogUUID/>
<Cachelog/>
<CachelogUUID/>
</log>
<mem>
<MaxFileSize>0</MaxFileSize>
<DefaultBlockSize>0</DefaultBlockSize>
</mem>
<global_max_cli_threads>256</global_max_cli_threads>
<global_max_cli_memory>0</global_max_cli_memory>
<version>V0.9</version>
<identifikation>LiHaSo lhttpd Webserver</identifikation>
<type>0</type>
</server>

42
cfg/server_config.xml Normal file
View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-16"?>
<server>
<hosts/>
<status/>
<config_file>
<element key="status_xml">
<name>cfg/default_http_status_codes.xml</name>
<type>file</type>
<configtype>status_xml</configtype>
</element>
<!--<element key="hosts_dir">
<name>cfg/hosts/</name>
<type>dir</type>
<configtype>hosts_dir</configtype>
</element> -->
<element key="host_file">
<name>cfg/hosts/sample.xml</name>
<type>file</type>
<configtype>host_file</configtype>
</element>
</config_file>
<log>
<DebuglogUUID/>
<Debugdisable>0</Debugdisable>
<Accesslog/>
<AccesslogUUID/>
<Errorlog/>
<ErrorlogUUID/>
<Cachelog/>
<CachelogUUID/>
</log>
<mem>
<MaxFileSize>0</MaxFileSize>
<DefaultBlockSize>0</DefaultBlockSize>
</mem>
<global_max_cli_threads>256</global_max_cli_threads>
<global_max_cli_memory>0</global_max_cli_memory>
<version>V0.9</version>
<identifikation>LiHaSo Sample Webserver V0.9</identifikation>
<type>0</type>
</server>

View File

@ -1,107 +0,0 @@
Structure GROUP
gr_name.s ; group name
gr_passwd.s ; group password
gr_gid.i ; group id
gr_mem.i ; group members
EndStructure
Global gID.i = getgid_()
Global group.group
Global gName.s
Global eingabe.s
*groupmem = AllocateMemory(SizeOf(group))
*groupmem = getgrgid_(gID)
CopyMemory(*groupmem, @group, SizeOf(group))
gName = PeekS(@group\gr_name, -1, #PB_Ascii)
OpenConsole("lhttpd Init")
If gName <> "root"
PrintN("You need to run this app as root capable user")
End
EndIf
PrintN("Create lhttpd config: /etc/lhttpd/lhttpd.cfg")
PrintN("Create service file: /usr/lib/systemd/system/lhttpd.service")
PrintN("Logfiles /var/log/lhttpd/* (access.log & error.log)")
PrintN("User = lhttpd")
PrintN("Grounp = lhttpd")
PrintN("Everything Ok (y/n)")
eingabe = Input()
If eingabe <> "y"
PrintN("Bad: "+eingabe+" exit...")
End
EndIf
PrintN("Create dir...")
CreateDirectory("/etc/lhttpd")
CreateDirectory("/etc/lhttpd/ssl")
CreateDirectory("/var/lib/lhttpd")
CreateDirectory("/var/log/lhttpd")
CreateDirectory("/opt/lhttpd")
PrintN("Create group lhttpd")
RunProgram("groupadd", "-f lhttpd", "", #PB_Program_Wait)
Delay(1000)
PrintN("Create User lhttpd")
RunProgram("useradd", "-s /bin/false -b /var/lib -g lhttpd lhttpd","", #PB_Program_Wait)
PrintN("Create config")
CreatePreferences("/etc/lhttpd/lhttpd.cfg", #PB_Preference_NoSpace | #PB_Preference_GroupSeparator)
PreferenceGroup("lhttpd")
WritePreferenceString("HTTP_Port","8080")
WritePreferenceString("HTTP_Binding","0.0.0.0")
WritePreferenceString("HTTPS_CA","/etc/lhttpd/ssl/sample/fullchain.pem")
WritePreferenceString("HTTPS_Cert","/etc/lhttpd/ssl/sample/cert.pem")
WritePreferenceString("HTTPS_Key","/etc/lhttpd/ssl/sample/privkey.pem")
WritePreferenceString("HTTPS_Key_Pass","test-server-pass")
WritePreferenceString("HTTPS_Port","8443)
WritePreferenceString("HTTPS_Binding","0.0.0.0")
WritePreferenceString("HTTPS_enable","1")
WritePreferenceString("Defaultfile","/index.html")
WritePreferenceString("Basedirectory","/srv/www/htdocs")
WritePreferenceString("Error400_Handling","integrated")
WritePreferenceString("Max_HTTP_Clients","10")
WritePreferenceString("Max_HTTPS_Clients","100")
WritePreferenceString("Filememorycache","0")
WritePreferenceString("Checkrun","/tmp/lhttpd.run")
WritePreferenceString("Debug_logfile","/var/log/lhttpd/debug.log")
WritePreferenceString("Debug_disable","true")
WritePreferenceString("Access_logfile","/var/log/lhttpd/access.log")
WritePreferenceString("Error_logfile","/var/log/lhttpd/error.log")
ClosePreferences()
PrintN("chown and chmod for ssl...")
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("chmod", "-r 755 /etc/lhttpd","",#PB_Program_Wait)
RunProgram("chmod", "-r 700 /etc/lhttpd/ssl","",#PB_Program_Wait)
PrintN("create service file...")
If CreateFile(0, "/usr/lib/systemd/system/lhttpd.service")
WriteStringN(0,"[Unit]")
WriteStringN(0,"Description=Lweb httpd server")
WriteStringN(0,"After=network.target")
WriteStringN(0,"StartLimitIntervalSec=0")
WriteStringN(0,"")
WriteStringN(0,"[Service]")
WriteStringN(0,"Type=simple")
WriteStringN(0,"Restart=always")
WriteStringN(0,"RestartSec=1")
WriteStringN(0,"User=lhttpd")
WriteStringN(0,"PIDFile=/tmp/lhttpd.run")
WriteStringN(0,"ExecStart=/opt/lhttpd/lhttpd")
WriteStringN(0,"ExecStop=/bin/rm /tmp/lhttpd.run")
WriteStringN(0,"")
WriteStringN(0,"[Install]")
WriteStringN(0,"WantedBy=multi-user.target")
CloseFile(0)
PrintN("daemon reload...")
RunProgram("systemctl", "daemon-reload", "", #PB_Program_Wait)
PrintN("tests...")
RunProgram("systemctl", "status lhttpd", "", #PB_Program_Wait)
PrintN("finished")
Else
PrintN("Servicefile failed")
EndIf
End

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-16"?>
<map>
<element key="400">
<status>400</status>
<file>integrated</file>
<header>400 Bad Request</header>
<message>400 Bad Request</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="403">
<status>403</status>
<file>integrated</file>
<header>403 Forbidden</header>
<message>403 Forbidden</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="404">
<status>404</status>
<file>integrated</file>
<header>404 Not Found</header>
<message>404 Not Found</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="303">
<status>303</status>
<file/>
<header>303 See Other</header>
<message/>
<message_body/>
<template>0</template>
<content>0</content>
<head_fields/>
</element>
<element key="200">
<status>200</status>
<file/>
<header>200 Ok</header>
<message/>
<message_body/>
<template>0</template>
<content>0</content>
<head_fields/>
</element>
<element key="500">
<status>500</status>
<file>integrated</file>
<header>500 Internal Server Error</header>
<message>500 Internal Server Error</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="501">
<status>501</status>
<file>integrated</file>
<header>501 Not Implemented</header>
<message>501 Not Implemented</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="502">
<status>502</status>
<file>integrated</file>
<header>502 Bad Gateway</header>
<message>502 Bad Gateway</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
<element key="503">
<status>503</status>
<file>integrated</file>
<header>503 Service Unavailable</header>
<message>503 Service Unavailable</message>
<message_body/>
<template>1</template>
<content>1</content>
<head_fields/>
</element>
</map>

129
inc/lcmf_main.pbi Normal file
View File

@ -0,0 +1,129 @@
;********************************
;*
;* lcmf_main.pbi
;*
;* (c) Cache (m) Memory and (f) File
;*
;* LiHaSo Webserver Modul In Memory File Cache
;*
;* It Could be configured Globaly and by Virtualhost
;*
DeclareModule lcmf
#Cache_Server_Single = 0
#Cache_Server_Multi = 1
EnumerationBinary lcmf_init
#Mem_Cache
#File_Cache
EndEnumeration
EnumerationBinary lcmf_object_state
#NA ;Not available
#InProgress ;Copy is in Progress
#Cached ;Object is available
#Cleaning ;Object is on the way to cleaned out
EndEnumeration
EnumerationBinary lcmf_params_state
;#UCP = Universal Cache Params (File and Mem)
#UCP_Max_Size_Total ;Total Size of Cache
#UCP_Max_Size_per_Entry ;Max Size of a File or Memoryblock
;#FAC = File Access Config
#FAC_MC ;Minimum Access Times until a File is Cached (Generic)
#FAC_RT ;Max Time a File could be in Cache (Generic)
#FAC_LA_RT ;How long a File could stay in Cache sinde last Access (Generic)
;(If a File has regulary access For ex. every 10 min. And this lifetime is 3600min. it will be killed after FAC_RT is reached)
#FAC_WL_Add ;Whitelist add Generic (Ex. :
;".html" = All html files
;"file.html" Expliciz Filenames
;"/path/" Including all Files and Subdirectorys It is added to Valid_Source
;"/path" only Files in Directory
;"'/path/','.rpm'" Combines a path and a Specific file extension
#FAC_WL_Add_Ext ;Whitelist which add with special MC/RT/LA_RT Params
#FAC_Valid_Source ;From where the files could get
#FAC_Cache_Dir ;Directory where the Cached Files could be written
;Some Function for Set_State who do a active Work
#FAC_Check_Cache ;Checks if all Files are the Same as Source
#UCP_Flush_Object ;Removes a Object from Cache
EndEnumeration
Declare.s Init(Server_Type.i = #Cache_Server_Multi) ;Create a Main Cache_Thread Management Server
Declare.s Init_cache(Cache_Type.i = #Mem_Cache) ;Create a Cache_Thread gives back the UUID
Declare.i Set_Params(Server_ID.s, Parameters.s) ;Set Cache Parameters in pre run state
Declare.i Use_New_Params(Server_ID.s) ;Reinit the Cache Thread
Declare.i Run_Cache(Server_ID.s) ;Start a initialised Cache Init()->InitCache()->Set_Params()->Run_Cache()
Declare.i Kill_Cache(Server_ID.s) ;Kills a Cache Server Thread
Declare.i Set_State(Server_ID.s, Parameters.s) ;Force to do something in Cache Thread (Flush a Element, Cleanup the Filecache-IO Intesitive, Check for Updates on Files an co.)
Declare.s Get_State(Server_ID.s, Parameters.s) ;Get Cache Server Thread State (For ex. current elements cachced, sizes and co.)
Declare.s Put_Mem(Server_ID.s, Memblock_ToSave.i, MC.i=-1, RT.i=-1, LA_RT.i=-1) ;Push a Memory Block to cache (Ex. some pre executed scripts or pictures and so on.)
Declare.s Get_Mem(Server_ID.s, Memblock_ID.s, MC.i=-1, RT.i=-1, LA_RT.i=-1) ;Get That Memoryblock from cache who was Previously Stored
Declare.s Get_File(Server_ID.s, Full_File_Name.s, Force_Disk.i = #True) ;Get a File (Cached or uncached) could be used everytime (ServerUUID empty everytime uncached or Flag uncached is set)
EndDeclareModule
Module lcmf
IncludeFile "lhs_uuid.pbi"
Structure lcmf_mem_objects
MemoryAddress.i
State.i
EndStructure
Structure lcmf_file_objects
LocalFileUUID.s
EndStructure
Structure lcmf_cache_servers
EndStructure
Structure lcmf_cache_servers_config_prepare
EndStructure
Procedure.i Main_Thread(ID.i)
;What this Thread does:
;* Check if Subthreads are alive and if not remove from Mapping Space
;* Spawn new Cache Threads and Kill Cache Threads
EndProcedure
Procedure.i Cache_Mem_Thread(ID.i)
;What this Thread does:
;* Manage the mem Objects
EndProcedure
Procedure.i Cache_File_Thread(ID.i)
;What this Thread does:
;* Manage the file Objects and maybe the memobjects.
EndProcedure
Procedure.i Copy_Thread(ID.i)
;What this Thread does:
;* Copy a File to Cachefolder
EndProcedure
Procedure.i Check_Thread(ID.i)
;What this Thread does:
;* Checks the Cachefolder and Memorymap if all Files are valid.
EndProcedure
Procedure.i Copy_File_to_Memory_Thread(ID.i)
;What this thread does:
;* Copy a local cached File to Memory
;
EndProcedure
EndModule

View File

@ -15,15 +15,15 @@ Procedure IsIPStringValid(Adress.s)
My_Regex_v6_compress = CreateRegularExpression(#PB_Any, "^(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)::(([0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){0,5})?)$")
If MatchRegularExpression(My_Regex_v4, Adress) And Valid = 0
lhs_log::Out("My_Regex_v4")
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"My_Regex_v4")
Valid = 1
EndIf
If MatchRegularExpression(My_Regex_v6_nocompress, Adress) And Valid = 0
lhs_log::Out("My_Regex_v6_nocompress")
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"My_Regex_v6_nocompress")
Valid = 1
EndIf
If MatchRegularExpression(My_Regex_v6_compress, Adress) And Valid = 0
lhs_log::Out("My_Regex_v6_compress")
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"My_Regex_v6_compress")
Valid = 1
EndIf

20
inc/lweb_config.pbi Normal file
View File

@ -0,0 +1,20 @@
;********************************
;*
;* lweb_config.pbi
;*
;* LiHaSo Webserver Config module.
;*
;* Configuration Module for Configs.
;*
;Set Configuration Paramters as a JSON
Procedure.s config_set(ID.s, JSONConfig.s)
EndProcedure
;Get the whole Config as a JSON String
Procedure.s config_get(ID.s)
EndProcedure

View File

@ -0,0 +1,15 @@
;********************************
;*
;* lweb_config_header.pbi
;*
;* Header File
;*
;* LiHaSo Webserver Config module.
;*
;* Configuration Module for Configs.
;*
;Set Configuration Paramters as a JSON
Declare.s config_set(ID.s, JSONConfig.s)
;Get the whole Config as a JSON String
Declare.s config_get(ID.s)

View File

@ -1,80 +1,242 @@

;********************************
;*
;* lweb_file_cache.pbi
;*
;* LiHaSo Webserver Modul In Memory File Cache (Obsolete and replaced by lcmf_main.pbi)
;*
;* It Could be configured Globaly and by Virtualhost
;*
DeclareModule lweb_FC
Enumeration Server_Type
#Type_Main ;Main Server
#Type_Virtual_Main ;Shared Virtual Server which get Data from Main
#Type_Virtual ;Standalone Virtual Server which has own Memory Area
EndEnumeration
;{ Error Enumeration
#Err_Unknown = -1
#Err_Server_Not_Found = -2
#Err_Server_File_Not_Found = -3
;}
Declare.s FC_Config_Get(UUID.s)
Declare.i FC_Config_Set(UUID.s, ConfigXML.s)
Declare.i FC_Create(UUID.s, Type.i = #Type_Main)
Declare.i FC_Destroy(UUID.s)
Declare.s FC_Status_Get(UUID.s)
Declare.i FC_GetFile(UUID.s, FileName.s)
Declare.i FC_SetFile(UUID.s, FileName.s, Memory.i, Size.i)
EndDeclareModule
Module lweb_FC
Structure St_Jobs
Type.i
Memory.i
EndStructure
Structure St_File
lifetime.i
timer.i
size.i
memoryID.i
ThreadID.i
Accesed.i
Mutex.i
Semaphore.i
List Job.St_Jobs()
EndStructure
Structure St_FC_Config
max_life_time.i
max_total_size.i
max_file_size.i
current_total_size.i
enabled.b
EndStructure
Structure St_Server
VServer_UUID.s
Log_UUID.s
Status.s
Thread.i
Semaphore.i
Config.St_FC_Config
Map Files.St_File()
EndStructure
Structure St_CacheServers
Main_UUID.s
Log_UUID.s
Status.s
Thread.i
Map Virtual.St_Server()
EndStructure
Global Var_FC_Server.St_CacheServers
Declare.i Cache_Cleaner(UUID.s)
Declare.i Cache_Server(UUID.s)
Declare.i Cache_File(UUID.s)
Procedure.s FC_Config_Get(UUID.s)
Protected XMLString.s, XMLID.i
If FindMapElement(FC\Virtual(), UUID)
XMLID = CreateXML(#PB_Any)
InsertXMLMap(RootXMLNode(XMLID), FC\Virtual\
Else
ProcedureReturn Str(#Err_Server_Not_Found)
EndIf
EndProcedure
Procedure.i FC_Config_Set(UUID.s, ConfigXML.s)
;Apply the Config XML to the Map
Protected XML_ID.i
XML_ID = CreateXML(#PB_Any)
If XMLStatus(XML_ID) = #PB_XML_Success
ParseXML(XML_ID, ConfigXML)
If XMLStatus(XML_ID) = #PB_XML_Success
ExtractXMLMap(MainXMLNode(XML_ID), @FC\Virtual(UUID), #PB_XML_NoCase)
FreeXML(XML_ID)
ProcedureReturn #True
Else
FreeXML(XML_ID)
ProcedureReturn #False
EndIf
Else
If XML_ID <> 0
FreeXML(XML_ID)
EndIf
ProcedureReturn #False
EndIf
EndProcedure
Procedure.i FC_Create(UUID.s, Type.i = #Type_Main)
;Create the Server
EndProcedure
Procedure.i FC_Destroy(UUID.s)
;Kill Thread Cache Handler Thread.
EndProcedure
Procedure.s FC_Status_Get(UUID.s)
;Status of the Server
EndEnumeration
Procedure.i FC_GetFile(UUID.s, FileName.s, MemoryID.i)
;Fill the Cached File to Memory and if response > 0 it was succesfull.
EndEnumeration
Procedure.i FC_SetFile(UUID.s, FileName.s, Memory.i, Size.i)
;Create cached file thread and save it to thread memory.
EndEnumeration
Procedure.i Cache_Cleaner(UUID.s)
;Cleans out old Files.
Protected.i Selected
Protected.i Counter
Protected.i MaxSize = Information
Repeat
Delay(1000) ;Nur Alle Sekunden Prüfen
Counter + 1
LockMutex(file_cache_mutex)
ResetMap(m_file_cache_map())
;Debug "FileCacheCleaner" + Str(Counter) + " Map Size:" + Str(MapSize(m_file_cache_map()))
If NextMapElement(m_file_cache_map())
Repeat
m_file_cache(MapKey(m_file_cache_map()))\Timer - 1
If m_file_cache(MapKey(m_file_cache_map()))\Timer <= 0
If m_file_cache(MapKey(m_file_cache_map()))\Buffer > 0
configuration\cache\current - m_file_cache(MapKey(m_file_cache_map()))\Size
FreeMemory(m_file_cache(MapKey(m_file_cache_map()))\Buffer)
DeleteMapElement(m_file_cache(), MapKey(m_file_cache_map()))
lhs_log_ext::Out(configuration\log\CachelogUUID, "Info:["+Str(innercount)+"] Killed:["+MapKey(m_file_cache_map())+"]")
Selected = DeleteMapElement(m_file_cache_map())
Else
lhs_log_ext::Out(configuration\log\CachelogUUID, "Info:["+Str(innercount)+"] Could Not kill:["+MapKey(m_file_cache_map())+"]")
EndIf
Else
Selected = NextMapElement(m_file_cache_map())
EndIf
Until Selected = 0
EndIf
UnlockMutex(file_cache_mutex)
ForEver
EndProcedure
Procedure.i Cache_Server(UUID.s)
;http://purearea.net/pb/english/manual/reference/ug_memory.html
Protected FileCacheCleanerThread.i
Protected Tempbuffer.i, MaxSize.i, Current.i
MaxSize = configuration\cache\maxsize * 1024 * 1024
FileCacheCleanerThread = CreateThread(@FileCacheCleaner(), MaxSize)
Repeat
WaitSemaphore(file_cache_semaphore)
lhs_log_ext::Out(configuration\log\CachelogUUID, "Adresse:"+m_file_cache()\Buffer)
If (m_file_cache()\Size + configuration\cache\current) <= MaxSize
configuration\cache\current + m_file_cache()\Size
Tempbuffer = AllocateMemory(m_file_cache()\Size)
CopyMemory(m_file_cache()\Buffer, Tempbuffer, MemorySize(m_file_cache()\Buffer))
m_file_cache()\Buffer = Tempbuffer
m_file_cache()\Timer = configuration\cache\time
m_file_cache()\Is = #True
m_file_cache_map(MapKey(m_file_cache())) = #True
SignalSemaphore(file_cache_semaphore_thread)
Else
lhs_log_ext::Out(configuration\log\CachelogUUID, "Cache Full")
SignalSemaphore(file_cache_semaphore_thread)
EndIf
ForEver
EndProcedure
Procedure.i Cache_File(UUID.s)
;Procedure for File_Cache Thread who handles the Cachefile
Protected MyMemory.i, My_Host_UUID.s = StringField(UUID, 0, ";"),My_File_UUID.s = StringField(UUID, 1, ";"), WorkElement.i
Repeat
WaitSemaphore(Var_FC_Server\Virtual(UUID)\Semaphore)
LockMutex(Var_FC_Server\Virtual(UUID)\Mutex)
WorkElement = FirstElement(Var_FC_Server\Virtual(UUID)\Files()
UnlockMutex(Var_FC_Server\Virtual(UUID)\Files(UUID)\Mutex)
ForEver
EndProcedure
EndModule
;Buggy FileCache Routines ... Wiso auch immer das noch nicht richtig Funktioniert.
Procedure FileCacheCleaner(Information.i)
Protected.i Selected
Protected.i Counter
Protected.i MaxSize = Information
Repeat
Delay(1000) ;Nur Alle Sekunden Prüfen
Counter + 1
LockMutex(file_cache_mutex)
ResetMap(m_file_cache_map())
;Debug "FileCacheCleaner" + Str(Counter) + " Map Size:" + Str(MapSize(m_file_cache_map()))
If NextMapElement(m_file_cache_map())
Repeat
m_file_cache(MapKey(m_file_cache_map()))\Timer - 1
If m_file_cache(MapKey(m_file_cache_map()))\Timer <= 0
If m_file_cache(MapKey(m_file_cache_map()))\Buffer > 0
configuration\cache\current - m_file_cache(MapKey(m_file_cache_map()))\Size
FreeMemory(m_file_cache(MapKey(m_file_cache_map()))\Buffer)
DeleteMapElement(m_file_cache(), MapKey(m_file_cache_map()))
Debug "Info:["+Str(innercount)+"] Killed:["+MapKey(m_file_cache_map())+"]"
Selected = DeleteMapElement(m_file_cache_map())
Else
Debug "Info:["+Str(innercount)+"] Could Not kill:["+MapKey(m_file_cache_map())+"]"
EndIf
Else
Selected = NextMapElement(m_file_cache_map())
EndIf
Until Selected = 0
EndIf
UnlockMutex(file_cache_mutex)
ForEver
EndProcedure
Procedure FileCache(Information.i)
;http://purearea.net/pb/english/manual/reference/ug_memory.html
Protected FileCacheCleanerThread.i
Protected Tempbuffer.i, MaxSize.i, Current.i
MaxSize = configuration\cache\maxsize * 1024 * 1024
FileCacheCleanerThread = CreateThread(@FileCacheCleaner(), MaxSize)
Repeat
WaitSemaphore(file_cache_semaphore)
Debug "Adresse:"+m_file_cache()\Buffer
If (m_file_cache()\Size + configuration\cache\current) <= MaxSize
configuration\cache\current + m_file_cache()\Size
Tempbuffer = AllocateMemory(m_file_cache()\Size)
CopyMemory(m_file_cache()\Buffer, Tempbuffer, MemorySize(m_file_cache()\Buffer))
m_file_cache()\Buffer = Tempbuffer
m_file_cache()\Timer = configuration\cache\time
m_file_cache()\Is = #True
m_file_cache_map(MapKey(m_file_cache())) = #True
SignalSemaphore(file_cache_semaphore_thread)
Else
Debug "Cache Full"
SignalSemaphore(file_cache_semaphore_thread)
EndIf
ForEver
EndProcedure
Procedure AddFileToCache(MemoryID.i, FileName.s, Size.i)
LockMutex(file_cache_mutex)
Debug "Cache MaxSize:"+Str(configuration\cache\maxsize*1024*1024)+" Actual Size:"+Str(configuration\cache\current)
lhs_log_ext::Out(configuration\log\CachelogUUID, "Cache MaxSize:"+Str(configuration\cache\maxsize*1024*1024)+" Actual Size:"+Str(configuration\cache\current))
m_file_cache(FileName)\Buffer = MemoryID
m_file_cache(FileName)\Size = Size
SignalSemaphore(file_cache_semaphore)
WaitSemaphore(file_cache_semaphore_thread)
If m_file_cache(FileName)\Is
Debug FileName+" Size:"+Str(m_file_cache(FileName)\Size)+" Timer:"+Str(m_file_cache(FileName)\Timer)+ " new Memory ID:"+Str(m_file_cache(FileName)\Buffer)
lhs_log_ext::Out(configuration\log\CachelogUUID, FileName+" Size:"+Str(m_file_cache(FileName)\Size)+" Timer:"+Str(m_file_cache(FileName)\Timer)+ " new Memory ID:"+Str(m_file_cache(FileName)\Buffer))
Else
Debug "File not in cache was to full:"+FileName+ " MaxSize:"+Str(configuration\cache\maxsize)+" Actual Size:"+Str(configuration\cache\current/1024/1024)
lhs_log_ext::Out(configuration\log\CachelogUUID, "File not in cache was to full:"+FileName+ " MaxSize:"+Str(configuration\cache\maxsize)+" Actual Size:"+Str(configuration\cache\current/1024/1024))
EndIf
UnlockMutex(file_cache_mutex)
@ -92,7 +254,10 @@ Procedure.s GetFileFromCache(FileName.s, MemoryID.i)
String.s = #error_string
EndIf
UnlockMutex(file_cache_mutex)
Debug "Get from cache: "+FileName+">"+String+"-------------------------------------------------------------<"
lhs_log_ext::OutL(configuration\log\CachelogUUID,lhs_log_ext::#Info, "File from Cache:"+FileName)
lhs_log_ext::OutL(configuration\log\CachelogUUID,lhs_log_ext::#Debugging, "Content: --------------------------------------------------------")
lhs_log_ext::OutL(configuration\log\CachelogUUID,lhs_log_ext::#Debugging, String)
lhs_log_ext::OutL(configuration\log\CachelogUUID,lhs_log_ext::#Debugging, "End Content. ----------------------------------------------------")
ProcedureReturn String.s
Else
ProcedureReturn #error_string

133
inc/lweb_header_privat.pbi Normal file
View File

@ -0,0 +1,133 @@
;********************************
;*
;* lweb_header_privat.pbi
;*
;* LiHaSo Webserver Modul Header/Declare Privatmodule
;*
;* It is usable as standalone Webserver, look at lhttpd.pb
;*
;*
;*
Structure server_http
enabled.i
port.i
binding.s
max_clients.i
reuse.b
thread_id.i
EndStructure
Structure server_https
enabled.i
port.i
binding.s
max_clients.i
reuse.b
CA.s
Certs.s
key.s
key_pass.s
thread_id.i
server_id.i
EndStructure
Structure server_cache
time.i
maxsize.i
current.i
enable.i
EndStructure
Structure memory
MaxFileSize.i
DefaultBlockSize.i
EndStructure
Structure log_config
DebuglogUUID.s
DebuglogFile.s
Debugdisable.i
AccesslogFile.s
AccesslogUUID.s
ErrorlogFile.s
ErrorlogUUID.s
CachelogFile.s
CachelogUUID.s
EndStructure
Enumeration http_header_fieldtype
#http_header_field_Static ;Fieldcontent could be directly used
#http_header_field_Dynamic_auto ;Must be handled by the Fieldcontent_proc
EndEnumeration
Enumeration http_headerfield_param
#http_headerfield_param_string
#http_headerfield_param_map
#http_headerfield_param_integer
EndEnumeration
Structure http_headerfield_params
Type.i ;Types of Field #Content or #Map
Content_string.s ;String Field
Map Content_Maps.s() ;Map Field
Content_integer.i ;Integer Field
EndStructure
Structure http_headerfield
Fieldname.s ; Name bevore : for ex. "keep-alive:"
Fieldcontent.s ; Content after : for ex. "Keep-Alive"
Fieldcontent_type.i ; #http_header_field_Static or #http_header_field_Dynamic_auto
Fieldcontent_proc.i ; A Procedure Prototype to call
Map Field_proc_parameters.http_headerfield_params() ;Parameters to give to call
EndStructure
IncludeFile "lweb_http_status_header_private.pbi"
Structure dynamichandler
functiontype.s
proc.s
file.s
routetype.s
url.s
extension.s
permlib.s
EndStructure
Structure usedlibs
permlib.s
lib_id.i
EndStructure
Structure host
description.s
http.server_http
https.server_https
cache.server_cache
log.log_config
mem.memory
Map dynamichandler.dynamichandler()
Map usedlibs.usedlibs()
defaultfile.s
basedir.s
Map status.http_status_codes() ;Individual Error Messages and Headers
EndStructure
Structure config_loader
name.s
type.s
configtype.s
EndStructure
Structure server
Map hosts.host()
Map status.http_status_codes() ;Default Error Messages and Headers
Map config_file.config_loader() ;Map Key is Type and string is file
log.log_config
mem.memory
global_max_cli_threads.i ;The maximum Thread Count = 0 unlimited
global_max_cli_memory.i ;The maximum Used Memory per Client Thread = 0 unlimited
version.s
identifikation.s
type.i
EndStructure

View File

@ -4,7 +4,22 @@
;*
Procedure.s mimetype(file.s)
Select file
; TODO:Mimetype dynamic configurable via XML
Select LCase(file)
Case "pdf"
ProcedureReturn "application/pdf"
Case "zip"
ProcedureReturn "application/zip"
Case "gz"
ProcedureReturn "application/gzip"
Case "doc"
ProcedureReturn "application/msword"
Case "xls"
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"
@ -21,12 +36,14 @@ Procedure.s mimetype(file.s)
ProcedureReturn "text/html"
Case "mss"
ProcedureReturn "text/html"
Case "php"
ProcedureReturn "text/html"
Case "css"
ProcedureReturn "text/css"
Case "js"
ProcedureReturn "text/javascript"
Default
ProcedureReturn "text/html"
ProcedureReturn "application/octet-stream"
EndSelect
EndProcedure
@ -42,4 +59,10 @@ Procedure.s MapToJSONString(Map ConvertMap.s())
ProcedureReturn Response
EndIf
ProcedureReturn #error_string
EndProcedure
Procedure.s xml_error_debug(XMLHandle)
Define Debug_String.s
Debug_String = "XML Error:["+XMLError(XMLHandle)+"] At Line:["+Str(XMLErrorLine(XMLHandle))+"] Position:["+Str(XMLErrorPosition(XMLHandle))+"]"
ProcedureReturn Debug_String
EndProcedure

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

@ -1,6 +1,8 @@
;********************************
;*
;* lweb_http.pbi
;*
;* HTTP 1.1 Header
;*
Procedure.s http_day(Tag.i)
@ -90,6 +92,7 @@
Define CountLines, Lines, JSON
If CountString(String,#CRLF$+#CRLF$)
Working = StringField(String,1,#CRLF$+#CRLF$)
Working = Working + #CRLF$
Else
ProcedureReturn #error_string
EndIf
@ -108,7 +111,7 @@
EndIf
For CountLines = 2 To Lines
Working_Line = StringField(Working,CountLines,#CRLF$)
Header(LCase(Trim(StringField(Working_Line,1,":")))+":") = Trim(StringField(Working_Line,2,":"))
Header(LCase(Trim(StringField(Working_Line,1,":")))+":") = Trim(Mid(Working_Line, FindString(Working_Line, ":") + 1))
Next
Else
FreeMap(Header())

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

123
inc/lweb_http_status.pbi Normal file
View File

@ -0,0 +1,123 @@
;********************************
;*
;* lweb_http_status.pbi
;*
;* LiHaSo Webserver Default status.
;*
;* Configuration Module for Configs.
;*
; configuration\status("number")\status = "200"
; configuration\status("number")\file = ""
; configuration\status("number")\header = "200 Ok"
; configuration\status("number")\message = ""
; configuration\status("number")\template = #False
; configuration\status("number")\content = #False
;*
;* Default status components
;* Please add here only rfc7231 codes.
;*
Procedure status_defaults()
;Import XML cfg/default_http_status_codes.xml resp config
Protected ReadedXML.s, FileHandle.i, XMLHandle.i
FileHandle = ReadFile(#PB_Any, configuration\config_file("status_xml")\name)
If IsFile(FileHandle)
ReadedXML = ReadString(FileHandle, #PB_File_IgnoreEOL)
CloseFile(FileHandle)
XMLHandle = ParseXML(#PB_Any, ReadedXML)
If XMLHandle And XMLStatus(XMLHandle) = #PB_XML_Success
ExtractXMLMap(MainXMLNode(XMLHandle), configuration\status())
Else
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Info, "Import of the File:"+configuration\config_file("status_xml")\name+" failed.")
EndIf
Else
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Info, "Could not open File:"+configuration\config_file("status_xml")\name+" .")
EndIf
EndProcedure
Procedure.s status_get_file(status.s, UUID.s="Default")
If UUID <> "Default"
If configuration\hosts(UUID)\status(status)\status = status
ProcedureReturn configuration\hosts(UUID)\status(status)\file
EndIf
EndIf
If configuration\status(status)\status = status
ProcedureReturn configuration\status(status)\file
Else
ProcedureReturn "Internal"
EndIf
EndProcedure
Procedure.s status_get_header(status.s, UUID.s="Default")
If UUID <> "Default"
If configuration\hosts(UUID)\status(status)\status = status
ProcedureReturn configuration\hosts(UUID)\status(status)\header
EndIf
EndIf
If configuration\status(status)\status = status
ProcedureReturn configuration\status(status)\header
Else
ProcedureReturn "500 Internal Server Error"
EndIf
EndProcedure
Procedure.s status_get_message(status.s, UUID.s="Default")
If UUID <> "Default"
If configuration\hosts(UUID)\status(status)\status = status
ProcedureReturn configuration\hosts(UUID)\status(status)\message
EndIf
EndIf
If configuration\status(status)\status = status
ProcedureReturn configuration\status(status)\message
Else
ProcedureReturn "500 Internal Server Error"
EndIf
EndProcedure
Procedure.s status_get_message_body(status.s, UUID.s="Default")
If UUID <> "Default"
If configuration\hosts(UUID)\status(status)\status = status
ProcedureReturn configuration\hosts(UUID)\status(status)\message_body
EndIf
EndIf
If configuration\status(status)\status = status
ProcedureReturn configuration\status(status)\message_body
Else
ProcedureReturn ""
EndIf
EndProcedure
Procedure status_get_template(status.s, UUID.s="Default")
If UUID <> "Default"
If configuration\hosts(UUID)\status(status)\status = status
ProcedureReturn configuration\hosts(UUID)\status(status)\template
EndIf
EndIf
If configuration\status(status)\status = status
ProcedureReturn configuration\status(status)\template
Else
ProcedureReturn #True
EndIf
EndProcedure
Procedure status_get_content(status.s, UUID.s="Default")
If UUID <> "Default"
If configuration\hosts(UUID)\status(status)\status = status
ProcedureReturn configuration\hosts(UUID)\status(status)\content
EndIf
EndIf
If configuration\status(status)\status = status
ProcedureReturn configuration\status(status)\content
Else
ProcedureReturn #True
EndIf
EndProcedure

View File

@ -0,0 +1,18 @@
;********************************
;*
;* lweb_http_status.pbi
;*
;* LiHaSo Webserver Default status Headerfile.
;*
;* Configuration Module for Configs.
;*
;* Please add here only rfc7231 codes.
Declare.s status_get_file(status.s, UUID.s="Default")
Declare.s status_get_header(status.s, UUID.s="Default")
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")

View File

@ -0,0 +1,21 @@
;********************************
;*
;* lweb_http_status.pbi
;*
;* LiHaSo Webserver Default status Headerfile.
;*
;* Configuration Module for Configs.
;*
;* Please add here only rfc7231 codes.
Structure http_status_codes
status.s ;Error Number
file.s ;Error File or "Integrated" for default Message as Template
header.s ;Error Header message for #http_head_status
message.s ;Error Message for Templated
message_body.s ;Error Message Body for Templated
template.b ;Is it a Template {ErrorNo}=error and {Message}=message and {Message_body}=message_body need to be there
content.b ;has it a content to send. (200 for ex. has no content who need to be processed.)
Map head_fields.http_headerfield()
EndStructure

240
inc/lweb_server_cfg.pbi Normal file
View File

@ -0,0 +1,240 @@
;********************************
;*
;* inc/lweb_server_cfg.pbi
;*
;* LiHaSo Webserver Server Configuration module.
;*
;* Configuration functions.
;*
Procedure server_load_host(XMLString.s)
;Load the Configuration to the Memory Structure.
Protected XMLHandle.i
Protected ImportHost.host
XMLHandle = ParseXML(#PB_Any, XMLString)
If XMLStatus(XMLHandle) = #PB_XML_Success
ExtractXMLStructure(MainXMLNode(XMLHandle), @ImportHost, host, #PB_XML_NoCase)
configuration\hosts(ImportHost\description)\description = ImportHost\description
CopyStructure(@ImportHost, @configuration\hosts(ImportHost\description), host)
FreeXML(XMLHandle)
ProcedureReturn #True
Else
ldl::Logging(xml_error_debug(XMLHandle))
FreeXML(XMLHandle)
ProcedureReturn #False
EndIf
EndProcedure
Procedure server_load_status(XMLString.s)
;Load the Status Codes to the Memory Map Structure.
Protected XMLHandle.i
Protected NewMap ImportStatus.http_status_codes()
XMLHandle = ParseXML(#PB_Any, XMLString)
If XMLStatus(XMLHandle) = #PB_XML_Success
ExtractXMLMap(MainXMLNode(XMLHandle), ImportStatus(), #PB_XML_NoCase)
If Not CopyMap(ImportStatus(), configuration\status())
ldl::Logging("Map Structure failed.")
FreeXML(XMLHandle)
FreeMap(ImportStatus())
ProcedureReturn #False
EndIf
FreeXML(XMLHandle)
FreeMap(ImportStatus())
ProcedureReturn #True
Else
ldl::Logging(xml_error_debug(XMLHandle))
FreeXML(XMLHandle)
FreeMap(ImportStatus())
ProcedureReturn #False
EndIf
EndProcedure
Procedure server_initial(ConfigOptions.s)
;Initialize Webserver from the Config File(s)
Protected FileHandle.i, XMLHandle.i, DirectoryHandle.i
Protected XMLReaded.s, ConfigFile.s
If Left(ConfigOptions, 5) = "file:"
ConfigFile = RemoveString(ConfigOptions, "file:")
FileHandle = ReadFile(#PB_Any, ConfigFile)
If IsFile(FileHandle)
XMLReaded = ReadString(FileHandle, #PB_File_IgnoreEOL)
CloseFile(FileHandle)
EndIf
Else
XMLReaded = ConfigOptions
EndIf
If Len(XMLReaded) > 0
XMLHandle = ParseXML(#PB_Any, XMLReaded)
If XMLStatus(XMLHandle) = #PB_XML_Success
ExtractXMLStructure(MainXMLNode(XMLHandle), @configuration, server, #PB_XML_NoCase)
FreeXML(XMLHandle)
;Now we need to load additional Config Files
ResetMap(configuration\config_file())
While NextMapElement(configuration\config_file())
Debug configuration\config_file()\configtype
Select LCase(configuration\config_file()\configtype)
Case "hosts_dir"
ldl::Logging("Hosts Directory:"+configuration\config_file()\name)
DirectoryHandle = ExamineDirectory(#PB_Any, configuration\config_file()\name, "*.xml")
If IsDirectory(DirectoryHandle)
While NextDirectoryEntry(DirectoryHandle)
If DirectoryEntryType(DirectoryHandle) = #PB_DirectoryEntry_File
FileHandle = ReadFile(#PB_Any, configuration\config_file()\name+DirectoryEntryName(DirectoryHandle))
If IsFile(FileHandle)
ldl::Logging("Found supported File:"+configuration\config_file()\name+DirectoryEntryName(DirectoryHandle))
XMLReaded = ReadString(FileHandle, #PB_File_IgnoreEOL)
CloseFile(FileHandle)
If server_load_host(XMLReaded)
ldl::Logging("succesful")
Else
ldl::Logging("failed")
EndIf
Else
ldl::Logging("Could not open File:"+configuration\config_file()\name+DirectoryEntryName(DirectoryHandle))
EndIf
EndIf
Wend
Else
ldl::Logging("Could not open the Directory for Analyzing:"+configuration\config_file()\name)
EndIf
Case "host_file"
ldl::Logging("Host File:"+configuration\config_file()\name)
FileHandle = ReadFile(#PB_Any, configuration\config_file()\name)
If IsFile(FileHandle)
XMLReaded = ReadString(FileHandle, #PB_File_IgnoreEOL)
CloseFile(FileHandle)
If server_load_host(XMLReaded)
ldl::Logging("succesful")
Else
ldl::Logging("failed")
EndIf
Else
ldl::Logging("Could not open File:"+configuration\config_file()\name)
EndIf
Case "status_xml"
ldl::Logging("Status XML File:"+configuration\config_file()\name)
FileHandle = ReadFile(#PB_Any, configuration\config_file()\name)
If IsFile(FileHandle)
XMLReaded = ReadString(FileHandle, #PB_File_IgnoreEOL)
CloseFile(FileHandle)
If server_load_status(XMLReaded)
ldl::Logging("succesful")
Else
ldl::Logging("failed")
EndIf
Else
ldl::Logging("Could not open File:"+configuration\config_file()\name)
EndIf
Default
ldl::Logging("Unsupported configtype:["+configuration\config_file()\configtype + "] Ignored.")
EndSelect
Wend
ldl::Logging("Config File Imported.")
ProcedureReturn #True
Else
ldl::Logging(xml_error_debug(XMLHandle))
FreeXML(XMLHandle)
ProcedureReturn #False
EndIf
Else
ldl::Logging("Could not open File:"+ConfigFile)
ProcedureReturn #False
EndIf
EndProcedure
Procedure.s server_get_config(Type.s, UUID.s = "")
Define Report.s
Define NewMap MapEntrys.s()
Select LCase(Type)
Case "ports_http"
ForEach configuration\hosts()
MapEntrys(Str(configuration\hosts()\http\port)) = "Used"
Next
ForEach MapEntrys()
If Len(Report)>0
Report = Report + ", "+ MapKey(MapEntrys())
Else
Report = MapKey(MapEntrys())
EndIf
Next
Case "ports_https"
ForEach configuration\hosts()
MapEntrys(Str(configuration\hosts()\https\port)) = "Used"
Next
ForEach MapEntrys()
If Len(Report)>0
Report = Report + ", "+ MapKey(MapEntrys())
Else
Report = MapKey(MapEntrys())
EndIf
Next
Default
Report = "Uknown Type"
EndSelect
FreeMap(MapEntrys())
ProcedureReturn Report
EndProcedure
Procedure server_config(UUID.s, XMLStructure.s)
ProcedureReturn #True
EndProcedure
Procedure set_config(parameter.i=#conf_defaultfile, setting.s="index.html")
Select parameter
Case #conf_File_BlockSize
configuration\mem\DefaultBlockSize = Val(setting)
Case #conf_File_max_in_Memory
configuration\mem\MaxFileSize = Val(setting)
Case #conf_Access_logUUID
configuration\log\AccesslogUUID = setting
Case #conf_Error_logUUID
configuration\log\ErrorlogUUID = setting
Case #conf_Cache_logUUID
configuration\log\CachelogUUID = setting
Case #conf_Debug_logUUID
configuration\log\DebuglogUUID = setting
Case #conf_debug_disable
If setting = "true"
configuration\log\Debugdisable = #True
Else
configuration\log\Debugdisable = #False
EndIf
Case #conf_runfile
Default
ProcedureReturn #False
EndSelect
ProcedureReturn #True
EndProcedure
Procedure.s get_config(parameter.i=#conf_defaultfile)
Select parameter
Case #conf_File_BlockSize
ProcedureReturn Str(configuration\mem\DefaultBlockSize)
Case #conf_File_max_in_Memory
ProcedureReturn Str(configuration\mem\MaxFileSize)
Case #conf_Access_logUUID
ProcedureReturn configuration\log\AccesslogUUID
Case #conf_Error_logUUID
ProcedureReturn configuration\log\ErrorlogUUID
Case #conf_Debug_logUUID
ProcedureReturn configuration\log\DebuglogUUID
Case #conf_debug_disable
If configuration\log\Debugdisable = #True
ProcedureReturn "true"
Else
ProcedureReturn "false"
EndIf
Default
ProcedureReturn ""
EndSelect
EndProcedure

View File

@ -0,0 +1,11 @@
;********************************
;*
;* inc/lweb_server_cfg_header.pbi
;*
;* LiHaSo Webserver Server Configuration module header.
;*
;* Configuration functions.
;*
Declare server_initial(ConfigOptions.s)
Declare.s server_get_config(Type.s, UUID.s = "")

145
installation.pb Normal file
View File

@ -0,0 +1,145 @@
Structure GROUP
gr_name.s ; group name
gr_passwd.s ; group password
gr_gid.i ; group id
gr_mem.i ; group members
EndStructure
Global gID.i = getgid_()
Global group.group
Global gName.s
Global eingabe.s
*groupmem = AllocateMemory(SizeOf(group))
*groupmem = getgrgid_(gID)
CopyMemory(*groupmem, @group, SizeOf(group))
gName = PeekS(@group\gr_name, -1, #PB_Ascii)
OpenConsole("lhttpd installation")
If gName <> "root"
PrintN("You need to run this app as root capable user")
End
EndIf
PrintN("Create lhttpd config: /etc/lhttpd/lhttpd.xml")
PrintN("Logfiles /var/log/lhttpd/* (access.log & error.log)")
PrintN("User = lhttpd")
PrintN("Grounp = lhttpd")
PrintN("Everything Ok (y/n)")
eingabe = Input()
If eingabe <> "y"
PrintN("Bad: "+eingabe+" exit...")
End
EndIf
PrintN("Create dir...")
CreateDirectory("/etc/lhttpd")
CreateDirectory("/etc/lhttpd/ssl")
CreateDirectory("/etc/lhttpd/hosts")
CreateDirectory("/var/lib/lhttpd")
CreateDirectory("/var/lib/lhttpd/default")
CreateDirectory("/var/log/lhttpd")
CreateDirectory("/opt/lhttpd")
PrintN("Create group lhttpd")
RunProgram("groupadd", "-f lhttpd", "", #PB_Program_Wait)
Delay(1000)
PrintN("Create User lhttpd")
RunProgram("useradd", "-s /bin/false -b /var/lib -g lhttpd lhttpd","", #PB_Program_Wait)
RunProgram("usermod", "-G wwwrun lhttpd","", #PB_Program_Wait)
PrintN("Copy config")
CopyFile("cfg/lhttpd.xml", "/etc/lhttpd/lhttpd.xml")
CopyFile("cfg/default_http_status_codes.xml", "/etc/lhttpd/default_http_status_codes.xml")
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/lhttpd_install.sh")
WriteStringN(0, "#!/bin/bash")
WriteStringN(0, "echo 'started'")
WriteStringN(0, "chown -R lhttpd:lhttpd /etc/lhttpd")
WriteStringN(0, "chown -R lhttpd:lhttpd /var/lib/lhttpd")
WriteStringN(0, "chown -R lhttpd:lhttpd /var/log/lhttpd")
WriteStringN(0, "chown -R lhttpd:lhttpd /opt/lhttpd")
WriteStringN(0, "chmod -R 644 /etc/lhttpd/*")
WriteStringN(0, "chmod 755 /etc/lhttpd")
WriteStringN(0, "chmod 755 /etc/lhttpd/hosts")
WriteStringN(0, "chmod -R 600 /etc/lhttpd/ssl")
WriteStringN(0, "chmod 700 /etc/lhttpd/ssl")
WriteStringN(0, "chmod 755 /opt/lhttpd")
WriteStringN(0, "chmod 555 /opt/lhttpd/lhttpd")
WriteStringN(0, "echo 'finished'")
CloseFile(0)
Else
PrintN("Error : Unable To create script at /tmp/lhttpd_install.sh")
End
EndIf
RunProgram("chmod", "777 /tmp/lhttpd_install.sh", "", #PB_Program_Wait)
Delay(1000)
RunProgram("/tmp/lhttpd_install.sh", "", "", #PB_Program_Wait)
DeleteFile("/tmp/lhttpd_install.sh")
PrintN("Create service file: /usr/lib/systemd/system/lhttpd.service")
If CreateFile(0, "/usr/lib/systemd/system/lhttpd.service")
WriteStringN(0,"[Unit]")
WriteStringN(0,"Description=Lweb httpd server")
WriteStringN(0,"After=network.target")
WriteStringN(0,"StartLimitIntervalSec=90")
WriteStringN(0,"")
WriteStringN(0,"[Service]")
WriteStringN(0,"AmbientCapabilities=CAP_NET_BIND_SERVICE")
WriteStringN(0,"Type=simple")
WriteStringN(0,"Restart=always")
WriteStringN(0,"RestartSec=1")
WriteStringN(0,"User=lhttpd")
WriteStringN(0,"Group=lhttpd")
WriteStringN(0,"PIDFile=/var/lib/lhttpd/lhttpd.run")
WriteStringN(0,"ExecStartPre=/bin/touch /var/lib/lhttpd/lhttpd.run")
WriteStringN(0,"ExecStart=/opt/lhttpd/lhttpd --run=/var/lib/lhttpd/lhttpd.run --config=/etc/lhttpd/lhttpd.xml")
WriteStringN(0,"ExecStop=/bin/rm /var/lib/lhttpd/lhttpd.run")
WriteStringN(0,"")
WriteStringN(0,"[Install]")
WriteStringN(0,"WantedBy=multi-user.target")
CloseFile(0)
PrintN("daemon reload...")
RunProgram("systemctl", "daemon-reload", "", #PB_Program_Wait)
PrintN("tests...")
RunProgram("systemctl", "status lhttpd", "", #PB_Program_Wait)
PrintN("finished")
Else
PrintN("Servicefile failed")
EndIf
If CreateFile(0, "/usr/lib/systemd/system/lhttpd-debug.service")
WriteStringN(0,"[Unit]")
WriteStringN(0,"Description=Lweb httpd server")
WriteStringN(0,"After=network.target")
WriteStringN(0,"StartLimitIntervalSec=90")
WriteStringN(0,"")
WriteStringN(0,"[Service]")
WriteStringN(0,"AmbientCapabilities=CAP_NET_BIND_SERVICE")
WriteStringN(0,"Type=simple")
WriteStringN(0,"Restart=always")
WriteStringN(0,"RestartSec=1")
WriteStringN(0,"User=lhttpd")
WriteStringN(0,"Group=lhttpd")
WriteStringN(0,"PIDFile=/var/lib/lhttpd/lhttpd.run")
WriteStringN(0,"ExecStartPre=/bin/touch /var/lib/lhttpd/lhttpd.run")
WriteStringN(0,"ExecStart=/opt/lhttpd/lhttpd --debug=/var/log/lhttpd/debug.log --run=/var/lib/lhttpd/lhttpd.run --config=/etc/lhttpd/lhttpd.xml")
WriteStringN(0,"ExecStop=/bin/rm /var/lib/lhttpd/lhttpd.run")
WriteStringN(0,"")
WriteStringN(0,"[Install]")
WriteStringN(0,"WantedBy=multi-user.target")
CloseFile(0)
PrintN("daemon reload...")
RunProgram("systemctl", "daemon-reload", "", #PB_Program_Wait)
PrintN("tests...")
RunProgram("systemctl", "status lhttpd-debug", "", #PB_Program_Wait)
PrintN("finished")
Else
PrintN("Servicefile failed")
EndIf
End

@ -1 +1 @@
Subproject commit b11846a3afa7fffb7d71c43450e3d41e6d591533
Subproject commit 548c80c974d8565000aafff37fc0eb41a4c6878a

View File

@ -1,17 +0,0 @@

[lhttpd]
HTTP_Port=8081
HTTP_Binding=0.0.0.0
HTTPS_CA=/home/renlin/dev/libressl/sample/test_ca.pem
HTTPS_Cert=/home/renlin/dev/libressl/sample/test_server_cert.pem
HTTPS_Key=/home/renlin/dev/libressl/sample/test_server_key.pem
HTTPS_Key_Pass=test-server-pass
HTTPS_Port=8444
HTTPS_Binding=127.0.0.1
HTTPS_enable=1
Defaultfile=/index.html
Basedirectory=/home/renlin/testweb/
Error400_Handling=integrated
Max_HTTP_Clients=10
Max_HTTPS_Clients=100
Filememorycache=0

123
lhttpd.pb
View File

@ -2,21 +2,23 @@
;*
;* 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
;* V0.8
;* - Webserver for HTTP & HTTPS now with the last Library Version
;*
EnableExplicit
XIncludeFile "lhs_lib/SYS/lhs_log.pbi" ;Currently for Debugging
XIncludeFile "lhs_lib/SYS/lhs_log_ext.pbi" ;User for Access Log, Error Access Log, Error Log and maybe more.
XIncludeFile "lhs_lib/SYS/lhs_sys_debug_wrapper.pbi" ;For all Log Outputs
OpenConsole("lhttpd")
Define Parameter.s, Configfile.s, Checkruntime.s, Exit_Web.i
Define Accesslog.s, Errorlog.s
Define Accesslog.s, Errorlog.s, Debuglogfile.s, DebuglogID.s
Define Version.s = "V0.8"
Configfile = "/etc/lhttpd/lhttpd.cfg"
Checkruntime = "/tmp/lhttpd.run"
@ -25,20 +27,23 @@ Repeat
Parameter = ProgramParameter()
If Parameter = "-h" Or Parameter = "--help"
PrintN("lhttpd Web Server")
PrintN("(c)2021 by Linder Hard- und Software")
PrintN("lhttpd Web Server "+Version)
PrintN("(c)2023 by Linder Hard- und Software")
PrintN("")
PrintN("Start parameters:")
PrintN("-c=/etc/lhttpd or --config=/etc/lhttpd")
PrintN("-c=/etc/lhttpd/server.xml or --config=/etc/lhttpd/server.xml")
PrintN(" Configuration file.")
PrintN("--run=/tmp/lhttpd.run")
PrintN(" Check periodical for the file")
PrintN("--debug=/var/log/lhttpd_debug.log")
PrintN(" Activate Debug Log")
ElseIf Left(Parameter,3) = "-c=" Or Left(Parameter,9) = "--config="
Configfile = Right(Parameter, Len(Parameter) - FindString(Parameter, "=") + 1)
Configfile = Right(Parameter, Len(Parameter) - FindString(Parameter, "="))
If ReadFile(0, Configfile)
CloseFile(0)
Else
PrintN("Failed unable to open config file")
PrintN("Failed unable to open config file:["+Configfile+"]")
End
EndIf
ElseIf Left(Parameter,6) = "--run="
@ -49,7 +54,14 @@ Repeat
PrintN("Failed to read check file:["+Checkruntime+"]")
End
EndIf
ElseIf Left(Parameter, 8) = "--debug="
Debuglogfile = Right(Parameter, Len(Parameter)-8)
DebuglogID = lhs_log_ext::Create("DebugLog")
lhs_log_ext::SetLogFile(DebuglogID, Debuglogfile)
lhs_log_ext::Init(DebuglogID)
ldl::Register(lhs_log_ext::@Out(), DebuglogID, 1, DebuglogID, ldl::#AdvancedLog)
ldl::SetDefault(DebuglogID)
ldl::Logging("Start Debug Log registered with ldl at UUID:"+DebuglogID)
ElseIf Parameter = ""
;No Parameters
Else
@ -67,83 +79,54 @@ Until Parameter = ""
XIncludeFile "lweb_header.pbi"
XIncludeFile "lweb.pbi"
If OpenPreferences(Configfile, #PB_Preference_GroupSeparator)
If PreferenceGroup("lhttpd")
lhs_web::set_config(lhs_web::#conf_HTTP_port, ReadPreferenceString("HTTP_Port","8081"))
lhs_web::set_config(lhs_web::#conf_HTTP_binding, ReadPreferenceString("HTTP_Binding","0.0.0.0"))
lhs_web::set_config(lhs_web::#conf_HTTPS_CA, ReadPreferenceString("HTTPS_CA","/home/renlin/dev/libressl/sample/fullchain.pem"))
lhs_web::set_config(lhs_web::#conf_HTTPS_Cert, ReadPreferenceString("HTTPS_Cert","/home/renlin/dev/libressl/sample/cert.pem"))
lhs_web::set_config(lhs_web::#conf_HTTPS_Key, ReadPreferenceString("HTTPS_Key","/home/renlin/dev/libressl/sample/privkey.pem"))
lhs_web::set_config(lhs_web::#conf_HTTPS_Key_Pass, ReadPreferenceString("HTTPS_Key_Pass",""))
lhs_web::set_config(lhs_web::#conf_HTTPS_Port, ReadPreferenceString("HTTPS_Port","8444"))
lhs_web::set_config(lhs_web::#conf_HTTPS_Binding, ReadPreferenceString("HTTPS_Binding","127.0.0.1"))
lhs_web::set_config(lhs_web::#conf_HTTPS_Enable, ReadPreferenceString("HTTPS_enable","0"))
lhs_web::set_config(lhs_web::#conf_defaultfile, ReadPreferenceString("Defaultfile","/index.html"))
lhs_web::set_config(lhs_web::#conf_basedir, ReadPreferenceString("Basedirectory","/home/renlin/testweb/"))
lhs_web::set_config(lhs_web::#conf_error400, ReadPreferenceString("Error400_Handling","integrated"))
lhs_web::set_config(lhs_web::#conf_max_HTTP_clients, ReadPreferenceString("Max_HTTP_Clients","10"))
lhs_web::set_config(lhs_web::#conf_max_HTTPS_clients, ReadPreferenceString("Max_HTTPS_Clients","100"))
lhs_web::set_config(lhs_web::#conf_cache_enable, ReadPreferenceString("Filememorycache","0"))
Checkruntime = ReadPreferenceString("Checkrun","/tmp/lhttpd.run")
lhs_web::set_config(lhs_web::#conf_debug_logfile, ReadPreferenceString("Debug_logfile","/var/log/lhttpd-debug.log"))
lhs_web::set_config(lhs_web::#conf_debug_disable, ReadPreferenceString("Debug_disable","true"))
lhs_web::set_config(lhs_web::#conf_access_logfile, ReadPreferenceString("Access_logfile","/var/log/lhttpd-access.log"))
lhs_web::set_config(lhs_web::#conf_error_logfile, ReadPreferenceString("Error_logfile","/var/log/lhttpd-error.log"))
ClosePreferences()
PrintN("lhttpd Webserver "+Version)
If Len(Checkruntime) > 0
If ReadFile(0, Checkruntime)
CloseFile(0)
PrintN("PID File created --run="+Checkruntime)
Else
PrintN("No correct config file -> End")
PrintN("Error: PID File:["+Checkruntime+"] could Not be created.")
End
EndIf
Else
PrintN("Could not open config file.")
PrintN("NO PID File configured --run=file.pid")
PrintN("Exit")
End
EndIf
If CreateFile(0, Checkruntime)
CloseFile(0)
PrintN("PID File created")
;*
;* Server Config Start
;*
PrintN("Read Configuration:")
If lhs_web::server_initial("file:"+Configfile)
ldl::Logging("config succesfully loaded.")
Else
PrintN("Error: PID could not be created.")
ldl::Logging("config load failed.")
End
EndIf
PrintN("Configured HTTP at Port(s):"+lhs_web::server_get_config("ports_http"))
PrintN("Configured HTTPS at Port(s):"+lhs_web::server_get_config("ports_https"))
PrintN("Configuration read done.")
lhs_log::App_Name = "lhttpd Web Server Debug"
lhs_log::SetLogFile(lhs_web::get_config(lhs_web::#conf_debug_logfile))
lhs_log::SetMaxSize(32)
lhs_log::SetLogDateFormat("%yyyy.%mm.%dd %hh:%ii:%ss")
lhs_log::SetLogFileDateFormat("%yyyy_%mm_%dd_%hh_%ii_%ss")
lhs_log::Init()
PrintN("Start Server...")
;*
;* Enable extended Logging:
;*
Accesslog = lhs_log_ext::Create("Accesslog")
Errorlog = lhs_log_ext::Create("Errorlog")
lhs_log::Out("Errorlog UUID:"+Errorlog)
lhs_log::Out("Accesslog UUID:"+Accesslog)
lhs_web::set_config(lhs_web::#conf_Access_logUUID, Accesslog)
lhs_web::set_config(lhs_web::#conf_Error_logUUID, Errorlog)
lhs_log_ext::SetLogFile(Accesslog, lhs_web::get_config(lhs_web::#conf_access_logfile))
lhs_log_ext::SetLogFile(Errorlog, lhs_web::get_config(lhs_web::#conf_error_logfile))
lhs_log_ext::Init(Accesslog)
lhs_log_ext::Init(Errorlog)
;*
;* includes
;* Server Start
;*
If lhs_web::start_server()
lhs_log::Out("Server started:")
lhs_log::Out("HTTP Port:"+ lhs_web::get_config(lhs_web::#conf_HTTP_port))
lhs_log::Out("HTTPS Port:"+ lhs_web::get_config(lhs_web::#conf_HTTPS_port))
If lhs_web::server_start()
ldl::Logging("Server started:")
ldl::Logging("Configured HTTP at Port(s):"+lhs_web::server_get_config("ports_http"))
ldl::Logging("Configured HTTPS at Port(s):"+lhs_web::server_get_config("ports_https"))
Else
lhs_log::Out("Serverstart failed.")
ldl::Logging("Serverstart failed.")
PrintN("Serverstart failed.")
End
EndIf
PrintN("lhttpd Webserver")
PrintN("HTTP on Port:"+lhs_web::get_config(lhs_web::#conf_HTTP_port))
PrintN("HTTPS on Port:"+lhs_web::get_config(lhs_web::#conf_HTTPS_Port))
PrintN("Server Started.")
Exit_Web = 0
Repeat
Delay(100)

View File

@ -1,125 +0,0 @@
;************************
;* Library : lsocket.pbi
;*
;* Socket based Networkcommuncation Module.
;*
;* Created and develobed by Linder Hard- und Software
;*
;* Current only usable for Linux.
;*
;*
CompilerIf #PB_Compiler_OS <> #PB_OS_Linux
CompilerError "Only for Linux"
CompilerEndIf
DeclareModule lsocket
Structure sockaddr
sa_family.w
sa_data.s{14}
EndStructure
Structure in_addr
s_addr.l
EndStructure
Structure sockaddr_in
sin_family.w
sin_port.w
sin_addr.in_addr
sin_zero.a[8]
EndStructure
; Socket types:
#SOCK_STREAM = 1 ; stream (connection) socket
#SOCK_DGRAM = 2 ; datagram (conn.less) socket
#SOCK_RAW = 3 ; raw socket
#SOCK_RDM = 4 ; reliably-delivered message
#SOCK_SEQPACKET = 5 ; sequential packet socket
#SOCK_PACKET = 10 ; linux specific way of
; getting packets at the dev
; level. For writing rarp And
; other similar things on the
; user level.
; socket.h
#PF_INET = 2
#AF_INET = #PF_INET
Declare CreateSocket(Port.i, Queuelengt.i = 64, Type.i = #SOCK_STREAM, Protocol.i = #AF_INET, BindedIP.s = "127.0.0.1") ; Return Server Socket < 0 Error
Declare WaitSocket(ServerSocket.i) ;Return new SocketID
Declare ReadSocket(ClientSocket.i, *Buffer, Length.i) ;Return Effective Read
Declare WriteSocket(ClientSocket.i, *Buffer, Length.i) ;Return Effective Writen
Declare CloseSocket(Socket.i)
Declare.s GetSocketIP(Socket.i)
EndDeclareModule
Module lsocket
Global NewMap lsockets_server.sockaddr_in()
Global NewMap lsockets_client.sockaddr_in()
Procedure CreateSocket(Port.i, Queuelengt.i = 64, Type.i = #SOCK_STREAM, Protocol.i = #AF_INET, BindedIP.s = "127.0.0.1") ; Return Server Socket < 0 Error
Protected SocketID.i
SocketID = socket_(Protocol, Type, 0)
If SocketID = -1 : ProcedureReturn -1 : EndIf
lsockets_server(Str(SocketID))\sin_family = Protocol
lsockets_server(Str(SocketID))\sin_addr\s_addr = Inet_addr_(BindedIP)
lsockets_server(Str(SocketID))\sin_port = htons_(Port)
If bind_(SocketID, @lsockets_server(Str(SocketID)), SizeOf(sockaddr_in)) <> 0
Close_(SocketID)
DeleteMapElement(lsockets_server(), Str(SocketID))
ProcedureReturn -1
Else
If listen_(SocketID, Queuelengt) <> 0
Close_(SocketID)
DeleteMapElement(lsockets_server(), Str(SocketID))
ProcedureReturn -1
EndIf
EndIf
ProcedureReturn SocketID
EndProcedure
Procedure.s GetSocketIP(Socket.i)
Protected IPAddresse.s
If lsockets_client(Str(Socket))\sin_family = 0
IPAddresse = PeekS(Inet_ntoa_(lsockets_client(Str(Socket))\sin_addr\s_addr), -1, #PB_Ascii)
Else
IPAddresse = PeekS(Inet_ntoa_(lsockets_client(Str(Socket))\sin_addr\s_addr), -1, #PB_Ascii)
EndIf
Debug "Requested IP Information:" + IPAddresse
ProcedureReturn IPAddresse
EndProcedure
Procedure WaitSocket(ServerSocket.i) ;Return new ClientSocketID
Protected ClientSID.i, MapID.s, ClientLength
Protected memory
memory = AllocateMemory(SizeOf(sockaddr_in))
ClientLength = SizeOf(sockaddr_in)
ClientSID = accept_(ServerSocket, memory, @ClientLength)
If ClientSID < 0 : FreeMemory(memory) : ProcedureReturn ClientSID : EndIf
MapID = Str(ClientSID)
CopyMemory(memory, lsockets_client(MapID), ClientLength)
Debug "Connected IP:" + PeekS(Inet_ntoa_(lsockets_client(MapID)\sin_addr\s_addr), -1, #PB_Ascii)
FreeMemory(memory)
ProcedureReturn ClientSID
EndProcedure
Procedure ReadSocket(ClientSocket.i, Buffer, Length.i) ;Return Effective Read
Protected Effective.i
Effective = read_(ClientSocket, Buffer, Length)
ProcedureReturn Effective
EndProcedure
Procedure WriteSocket(ClientSocket.i, Buffer, Length.i) ;Return Effective Writen
Protected Effective.i
Effective = write_(ClientSocket, Buffer, Length)
ProcedureReturn Effective
EndProcedure
Procedure CloseSocket(Socket.i)
Protected Feedback.i
Feedback = close_(Socket)
ProcedureReturn Feedback
EndProcedure
EndModule

232
ltls.pbi
View File

@ -1,232 +0,0 @@
;************************
;* Library : ltls.pbi
;*
;* Server side TLS Implementation to communicate encrypted.
;*
;* Created and develobed by Linder Hard- und Software
;*
;* Current only usable for Linux.
;*
;*
CompilerIf #PB_Compiler_OS <> #PB_OS_Linux
CompilerError "Only for Linux"
CompilerEndIf
XIncludeFile "lsocket.pbi"
DeclareModule ltls
Structure s_tls_server
CA.s
Cert.s
Key.s
Password.s
EndStructure
Declare InitSimpleTLS(CA.s, Cert.s, Key.s, Password.s, TLSID.i = 0)
Declare InitTLS(*Settings.s_tls_server, TLSID.i = 0)
Declare WaitTLSSocket(ServerSocket.i, TLSID.i = 0)
Declare ReadTLSSocket(Connection.i, *Buffer, Length.i)
Declare WriteTLSSocket(Connection.i, *Buffer, Length.i)
Declare CloseTLSSocket(Connection.i)
Declare CloseTLS(TLSID.i = 0)
Declare.s ErrorTLSSrv(TLSID.i = 0)
Declare.s ErrorTLSCli(Connection)
Declare GetSocket(Connection.i)
EndDeclareModule
Module ltls
Structure tls_socket
server_id.i
client_id.i
tls_id.i
EndStructure
Global NewMap socket_sort.tls_socket()
PrototypeC.i Pr_tls_init()
PrototypeC.i Pr_tls_config_new()
PrototypeC.i Pr_tls_load_file_pw(FileName.p-utf8, Length, Password.p-utf8)
PrototypeC.i Pr_tls_load_file(FileName.p-utf8, Length, Passord.s = #Null$)
PrototypeC.i Pr_tls_config_set_ca_mem(*tls_config , Memory.i, Length.i)
PrototypeC.i Pr_tls_config_set_cert_mem(*tls_config , Memory.i, Length.i)
PrototypeC.i Pr_tls_config_set_key_mem(*tls_config , Memory.i, Length.i)
PrototypeC.i Pr_tls_server()
PrototypeC.i Pr_tls_configure(*ctx, *cfg)
PrototypeC.i Pr_tls_error(*ctx)
PrototypeC.i Pr_tls_accept_socket(*ctx, *cctx, Socket.l)
PrototypeC.i Pr_tls_accept_cbs(*ctx, *cctx, read_cb.i, write_cb.i, arg_ch.i = #Null)
PrototypeC.i Pr_tls_read(*cctx, *buffer, Size.i)
PrototypeC.i Pr_tls_write(*cctx, *buffer, Size.i)
PrototypeC.i Pr_tls_handshake(*cctx)
PrototypeC.i Pr_tls_close(*cctx)
PrototypeC.i Pr_tls_free(*ctx)
PrototypeC.i Pr_tls_config_free(*cfg)
#TLS_WANT_POLLIN = -2
#TLS_WANT_POLLOUT = -3
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
Define libressl_tls = OpenLibrary(#PB_Any, "/usr/lib64/libtls.so.20")
If Not IsLibrary(libressl_tls)
Define libressl_tls = OpenLibrary(#PB_Any, "/usr/lib64/libtls.so.17")
If Not IsLibrary(libressl_tls)
lhs_log::Out("Library not found: /usr/lib64/libtls.so.20 or .17")
End
EndIf
EndIf
CompilerElse
Define libressl_tls = OpenLibrary(#PB_Any, "/usr/lib/libtls.so.20")
If Not IsLibrary(libressl_tls)
Define libressl_tls = OpenLibrary(#PB_Any, "/usr/lib/libtls.so.17")
If Not IsLibrary(libressl_tls)
lhs_log::Out("Library not found: /usr/lib/libtls.so.20 or .17")
End
EndIf
EndIf
CompilerEndIf
If IsLibrary(libressl_tls)
Define Call_tls_init = GetFunction(libressl_tls, "tls_init")
Define Call_tls_config_new = GetFunction(libressl_tls, "tls_config_new")
Define Call_tls_load_file = GetFunction(libressl_tls, "tls_load_file")
Define Call_tls_config_set_ca_mem = GetFunction(libressl_tls, "tls_config_set_ca_mem")
Define Call_tls_config_set_cert_mem = GetFunction(libressl_tls, "tls_config_set_cert_mem")
Define Call_tls_config_set_key_mem = GetFunction(libressl_tls, "tls_config_set_key_mem")
Define Call_tls_server = GetFunction(libressl_tls, "tls_server")
Define Call_tls_configure = GetFunction(libressl_tls, "tls_configure")
Define Call_tls_error = GetFunction(libressl_tls, "tls_error")
Define Call_tls_accept_socket = GetFunction(libressl_tls, "tls_accept_socket")
Define Call_tls_accept_cbs = GetFunction(libressl_tls, "tls_accept_cbs")
Define Call_tls_read = GetFunction(libressl_tls, "tls_read")
Define Call_tls_write = GetFunction(libressl_tls, "tls_write")
Define Call_tls_handshake = GetFunction(libressl_tls, "tls_handshake")
Define Call_tls_close = GetFunction(libressl_tls, "tls_close")
Define Call_tls_free = GetFunction(libressl_tls, "tls_free")
Define Call_tls_config_free = GetFunction(libressl_tls, "tls_config_free")
Else
lhs_log::Out("libtls.so Library Not found")
End
EndIf
Global.Pr_tls_init tls_init = Call_tls_init
Global.Pr_tls_config_new tls_config_new = Call_tls_config_new
Global.Pr_tls_load_file tls_load_file = Call_tls_load_file
Global.Pr_tls_load_file_pw tls_load_file_pw = Call_tls_load_file
Global.Pr_tls_config_set_ca_mem tls_config_set_ca_mem = Call_tls_config_set_ca_mem
Global.Pr_tls_config_set_cert_mem tls_config_set_cert_mem = Call_tls_config_set_cert_mem
Global.Pr_tls_config_set_key_mem tls_config_set_key_mem = Call_tls_config_set_key_mem
Global.Pr_tls_server tls_server = Call_tls_server
Global.Pr_tls_configure tls_configure = Call_tls_configure
Global.Pr_tls_error tls_error = Call_tls_error
Global.Pr_tls_accept_socket tls_accept_socket = Call_tls_accept_socket
Global.Pr_tls_accept_cbs tls_accept_cbs = Call_tls_accept_cbs
Global.Pr_tls_read tls_read = Call_tls_read
Global.Pr_tls_write tls_write = Call_tls_write
Global.Pr_tls_handshake tls_handshake = Call_tls_handshake
Global.Pr_tls_close tls_close = Call_tls_close
Global.Pr_tls_free tls_free = Call_tls_free
Global.Pr_tls_config_free tls_config_free = Call_tls_config_free
Global *ctx, *cfg
Global tls_cfg = #Null
Global tls_ctx = #Null
Procedure InitSimpleTLS(CA.s, Cert.s, Key.s, Password.s, TLSID.i = 0)
Define Settings.s_tls_server
Define TLSInitReturn.i
Settings\CA = CA
Settings\Cert = Cert
Settings\Key = Key
Settings\Password = Password
TLSInitReturn = InitTLS(@Settings, TLSID)
ProcedureReturn TLSInitReturn
EndProcedure
Procedure InitTLS(*Settings.s_tls_server, TLSID.i = 0)
Protected mem_ptr.i, length.i, returns.i
If tls_init() <> 0 : ProcedureReturn -1 : EndIf
tls_cfg = tls_config_new()
lhs_log::Out("TLS cfg obj:"+Str(tls_cfg))
lhs_log::Out("CA:"+*Settings\CA)
mem_ptr = tls_load_file(*Settings\CA, @length)
If Not mem_ptr : tls_config_free(tls_cfg) : ProcedureReturn -2 : EndIf
tls_config_set_ca_mem(tls_cfg, mem_ptr, length)
lhs_log::Out("Cert:"+*Settings\Cert)
mem_ptr = tls_load_file(*Settings\Cert, @length)
If Not mem_ptr : tls_config_free(tls_cfg) : ProcedureReturn -3 : EndIf
tls_config_set_cert_mem(tls_cfg, mem_ptr, length)
If Len(*Settings\Password) > 0
lhs_log::Out("Key:"+*Settings\Key + " Password:"+*Settings\Password)
mem_ptr = tls_load_file_pw(*Settings\Key, @length, *Settings\Password)
If Not mem_ptr : tls_config_free(tls_cfg) : ProcedureReturn -4 : EndIf
tls_config_set_key_mem(tls_cfg, mem_ptr, length)
Else
lhs_log::Out("Key:"+*Settings\Key)
mem_ptr = tls_load_file(*Settings\Key, @length)
If Not mem_ptr : tls_config_free(tls_cfg) : ProcedureReturn -5 : EndIf
tls_config_set_key_mem(tls_cfg, mem_ptr, length)
EndIf
tls_ctx = tls_server()
lhs_log::Out("TLS Server obj:"+Str(tls_ctx))
If Not tls_ctx : tls_config_free(tls_cfg) : ProcedureReturn -6 : EndIf
returns = tls_configure(tls_ctx, tls_cfg)
lhs_log::Out("Configure Returns:"+Str(returns))
If returns <> 0 :lhs_log::Out(ErrorTLSSrv()): tls_free(tls_ctx) : tls_config_free(tls_cfg) : ProcedureReturn -7 : EndIf
ProcedureReturn 1
EndProcedure
Procedure WaitTLSSocket(ServerSocket.i, TLSID.i = 0)
Protected sockID.i , tlssID.i, cctx
sockID = lsocket::WaitSocket(ServerSocket)
If sockID < 0 : ProcedureReturn -1 : EndIf
tlssID = tls_accept_socket(tls_ctx, @cctx, sockID)
If tlssID = -1 : ProcedureReturn -2 : EndIf
socket_sort(Str(cctx))\client_id = sockID
socket_sort(Str(cctx))\tls_id = cctx
socket_sort(Str(cctx))\server_id = ServerSocket
ProcedureReturn cctx
EndProcedure
Procedure ReadTLSSocket(Connection.i, Buffer, Length.i)
Protected Received.i
Received = tls_read(Connection, Buffer, Length)
ProcedureReturn Received
EndProcedure
Procedure WriteTLSSocket(Connection.i, Buffer, Length.i)
Protected Received.i
Received = tls_write(Connection, Buffer, Length)
ProcedureReturn Received
EndProcedure
Procedure CloseTLSSocket(Connection.i)
tls_close(Connection)
DeleteMapElement(socket_sort(), Str(Connection))
EndProcedure
Procedure GetSocket(Connection.i)
ProcedureReturn socket_sort(Str(Connection))\client_id
EndProcedure
Procedure.s ErrorTLSSrv(TLSID.i = 0)
Protected Error.s
Error = PeekS(tls_error(tls_ctx),-1,#PB_Ascii)
ProcedureReturn Error
EndProcedure
Procedure.s ErrorTLSCli(Connection.i)
Protected Error.s
Error = PeekS(tls_error(Connection),-1,#PB_Ascii)
ProcedureReturn Error
EndProcedure
Procedure CloseTLS(TLSID.i = 0)
tls_free(tls_ctx)
tls_config_free(tls_cfg)
EndProcedure
EndModule

1354
lweb.pbi

File diff suppressed because it is too large Load Diff

182
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 5.73 LTS (Linux - x64)">
<project xmlns="http://www.purebasic.com/namespace" version="1.0" creator="PureBasic 6.04 LTS (Linux - x64)">
<section name="config">
<options closefiles="1" openmode="0" name="LiHaSo Webserver Modul"/>
<comment>Projekt ist inklusive Beispiel Code</comment>
@ -8,89 +8,187 @@
<section name="data">
<explorer view="../../../bin/purebasic/examples/" pattern="0"/>
<log show="1"/>
<lastopen date="2021-05-24 22:01" user="renlin" host="linux-3z3y"/>
<lastopen date="2024-03-13 07:44" user="renlin" host="renlin-office"/>
</section>
<section name="files">
<file name="inc/lweb_file_cache.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+-"/>
<fingerprint md5="46864140ab7bcff85ebd199d13f4584b"/>
<file name="build_tools/src/default_host_xml_export.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="1" panelstate="+--"/>
<fingerprint md5="e3e8de2f4e852905bf6410aad61d5565"/>
</file>
<file name="inc/lweb_file_cache_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" panelstate="+-"/>
<fingerprint md5="3228c16f329808e2e6e3c6866861ae59"/>
<file name="build_tools/src/status_xml_export.pb">
<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="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="4" panelstate="+-"/>
<fingerprint md5="a3c3072e4eb0a8d09d9e02b2d57b707d"/>
</file>
<file name="inc/lweb_header_privat.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="5" panelstate="+-"/>
<fingerprint md5="c4a9ada9f85b43584cc6e154d6465fdf"/>
</file>
<file name="inc/lweb_helper.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+-"/>
<fingerprint md5="61c3c05e25271724318327b0bbd97f87"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="6" panelstate="+-"/>
<fingerprint md5="e6b5d486bd08b6de7f34a94316df2543"/>
</file>
<file name="inc/lweb_helper_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="0" panelstate="+-"/>
<fingerprint md5="c250ce791b691f679782e5016a3346be"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="7" panelstate="+-"/>
<fingerprint md5="6ea3e5baa62f8e66063e3b45e17d7e91"/>
</file>
<file name="inc/lweb_http.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+-"/>
<fingerprint md5="e8efea69d459079a6afb3454e20a3b93"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="8" panelstate="+-"/>
<fingerprint md5="a42cddb6a1102779589facc17ba96cd8"/>
</file>
<file name="inc/lweb_http_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+-"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="9" panelstate="+-"/>
<fingerprint md5="d7df8e152291b0f91e8316ad8e00191c"/>
</file>
<file name="inc/lweb_http_status.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="10" panelstate="+-"/>
<fingerprint md5="84fe14cca9af928faee3869b6c3d079f"/>
</file>
<file name="inc/lweb_http_status_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="11" panelstate="+-"/>
<fingerprint md5="ad8d9313172646d803164eaa5431d2f4"/>
</file>
<file name="inc/lweb_http_status_header_private.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="12" panelstate="+-"/>
<fingerprint md5="c7736a7cdc87c1ed676b17d9757ba135"/>
</file>
<file name="inc/lweb_IP.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+-"/>
<fingerprint md5="8c770722dc3dde3f15c774e31ae2038f"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="13" panelstate="+-"/>
<fingerprint md5="502f26844f0a4b7d7f25924f76b17473"/>
</file>
<file name="inc/lweb_IP_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+-"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="14" panelstate="+-"/>
<fingerprint md5="636558037ff2cab03552fb129e2a4f52"/>
</file>
<file name="lhs_lib/SYS/lhs_log.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+--"/>
<fingerprint md5="6b31d19e01b0030f0864597f48e078de"/>
<file name="inc/lweb_server_cfg.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="15" panelstate="+-"/>
<fingerprint md5="16d83dbd505bc2f267b630b9e2d173d1"/>
</file>
<file name="inc/lweb_server_cfg_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="16" panelstate="+-"/>
<fingerprint md5="57787e1e3db6c77d81fc5576e124beae"/>
</file>
<file name="installation.pb">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="17" 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="18" panelstate="+--"/>
<fingerprint md5="09f5575be4e23abbb593d2f735a795ae"/>
</file>
<file name="lhs_lib/NET/lhs_net_tls.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="19" panelstate="+--"/>
<fingerprint md5="c586d25a1493f437c7461374a891a715"/>
</file>
<file name="lhs_lib/NET/lhs_web_helper.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="20" panelstate="+--"/>
<fingerprint md5="52ed1675b88a463b7ada8cf2003430e1"/>
</file>
<file name="lhs_lib/SYS/lhs_log_ext.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+--"/>
<fingerprint md5="e71a63777923aebca7171593016d9b8f"/>
<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" panelstate="+"/>
<fingerprint md5="ebf734d9cd3289f62402f2e53926a082"/>
</file>
<file name="lsocket.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+"/>
<fingerprint md5="be7d2d564a84dfe303c8e59c7ec78878"/>
</file>
<file name="ltls.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+"/>
<fingerprint md5="03aa93c8873d761cfdc9763b38196677"/>
<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" panelstate="+"/>
<fingerprint md5="4d4c182994443de2dffc808a941bbfa3"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="24" panelstate="+"/>
<fingerprint md5="719ce9141b0a0c8a3729465a411a4c90"/>
</file>
<file name="lweb_header.pbi">
<config load="0" scan="1" panel="1" warn="1" lastopen="1" panelstate="+"/>
<fingerprint md5="33f134da4f3fefc97231572147d3be64"/>
<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" panelstate="+"/>
<fingerprint md5="5c49bb34e4235b4ca2d10b87ca4777f4"/>
<config load="0" scan="1" panel="1" warn="1" lastopen="1" sortindex="26" panelstate="+"/>
<fingerprint md5="bb89312c572cb9d1d3c81349252f0f4f"/>
</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="89b911359d8203d81c3aabbbd6f0dcf1"/>
</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">
<inputfile value="server_example.pb"/>
<outputfile value="server_example"/>
<compiler version="PureBasic 6.01 LTS - C Backend (Linux - x64)"/>
<executable value="server_example"/>
<options thread="1" xpskin="1" debug="1"/>
<options thread="1" xpskin="1" debug="1" optimizer="0"/>
<format exe="console" cpu="0"/>
<debugger custom="1" type="standalone"/>
<debugger custom="1" type="ide"/>
</target>
<target name="lhttpd" enabled="1" default="0">
<inputfile value="lhttpd.pb"/>
<outputfile value="lhttpd"/>
<compiler version="PureBasic 6.01 LTS - C Backend (Linux - x64)"/>
<executable value="lhttpd"/>
<options thread="1"/>
<options thread="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)"/>
<executable value="build_tools/status_xml_export"/>
<options optimizer="0"/>
<format exe="console" cpu="0"/>
</target>
<target name="build_tools/default_config_xml_export" enabled="1" default="0">
<inputfile value="build_tools/src/default_config_xml_export.pb"/>
<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="0"/>
<format exe="console" cpu="0"/>
</target>
<target name="build_tools/default_host_xml_export" enabled="1" default="0">
<inputfile value="build_tools/src/default_host_xml_export.pb"/>
<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="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

@ -10,7 +10,8 @@
;*
EnableExplicit
XIncludeFile "lhs_lib/SYS/lhs_log.pbi"
XIncludeFile "lhs_lib/NET/lhs_web_helper.pbi"
CompilerIf #PB_Compiler_Thread = 0
CompilerError "Muss Threadsicher Kompiliert werden"
@ -30,6 +31,8 @@ DeclareModule lhs_web
#conf_error400
#conf_max_HTTP_clients
#conf_max_HTTPS_clients
#conf_File_max_in_Memory
#conf_File_BlockSize
#conf_server_type
#conf_cache_enable
#conf_HTTPS_CA
@ -39,12 +42,14 @@ DeclareModule lhs_web
#conf_HTTPS_Port
#conf_HTTPS_Binding
#conf_HTTPS_Enable
#conf_debug_logfile
#conf_debug_disable
#conf_Access_logfile
#conf_Access_logUUID
#conf_Error_logfile
#conf_Error_logUUID
#conf_Cache_logfile
#conf_Cache_logUUID
#conf_Debug_logUUID
#conf_runfile
EndEnumeration
@ -55,9 +60,12 @@ DeclareModule lhs_web
EndEnumeration
Enumeration e_handler_prototype 1
#handler_proto_universal
#handler_proto_post
#handler_proto_get
#handler_proto_universal ;Used for Dynamic Librarys
#handler_proto_post ;Used for Dynamic Librarys
#handler_proto_get ;Used for Dynamic Librarys
#handler_proto_i_universal ;Used for internal Procedures
#handler_proto_i_post ;Used for internal Procedures
#handler_proto_i_get ;Used for internal Procedures
EndEnumeration
Enumeration cli_handler_app 1
@ -78,13 +86,13 @@ DeclareModule lhs_web
#cha_R_MemoryAdress = "MemoryAdress" ;Element MemoryAdress :Converted to String
#cha_R_MemorySize = "MemorySize" ;Element MemorySize :Converted to String
#cha_R_StringBase64 = "StringBase64" ;Element StringBase64 :Base64 Encoded String
#cha_R_http_head_status = "HeaderStatus" ;200 OK 300 Error 500 Server Error usw.
#cha_R_http_head_status = "HeaderStatus" ;200 OK 300 Error 500 Server Error usw.
#error_string = "error"
#http_head_method = "method"
#http_head_request = "request"
#http_head_protocol = "protocol"
#http_head_query = "query"
#http_head_status = "status"
#http_head_method = "method:"
#http_head_request = "request:"
#http_head_protocol = "protocol:"
#http_head_query = "query:"
#http_head_status = "status:"
#http_head_date = "date:"
#http_head_server = "server:"
#http_head_content_length = "content-length:"
@ -93,16 +101,27 @@ DeclareModule lhs_web
#http_head_keep_alive = "keep-alive:"
#http_head_cookie = "cookie:"
#http_head_set_cookie = "set-cookie:"
#http_head_redirect = "location:"
#http_content_type_application_x_www_form_urlencoded = "application/x-www-form-urlencoded"
#http_content_type_multipart_form_data = "multipart/form-data"
Declare set_config(parameter.i=#conf_defaultfile, setting.s="index.html")
Declare.s get_config(parameter.i=#conf_defaultfile)
Declare start_server()
Declare.s register_client_handler(Route.s, Callback.i, AppPrototype.i = #handler_proto_get, RouteType.i = #handler_sub)
;Declare.s get_config(parameter.i=#conf_defaultfile)
Declare.s http_server_prepare(http_port.i = 8080, http_binding.s = "127.0.0.1", https_port.i=8443, https_binding.s="127.0.0.1", https_enabled.b = #False)
Declare main_server(id.i)
Declare server_start()
XIncludeFile "inc/lweb_server_cfg_header.pbi"
Declare server_reload(UUID.s)
Declare server_config(UUID.s, XMLStructure.s)
Declare server_stop(UUID.s = "all")
Declare.s register_client_handler(Route.s, Callback.i, AppPrototype.i = #handler_proto_get, RouteType.i = #handler_sub, Host.s = "")
XIncludeFile "inc/lweb_IP_header.pbi"
XIncludeFile "inc/lweb_helper_header.pbi"
XIncludeFile "inc/lweb_http_status_header.pbi"
EndDeclareModule

View File

@ -4,18 +4,19 @@
;*
;* HTTP/HTTPS example extended Server
;*
;* (c)2015 - 2021 by Linder Hard- und Software
;* (c)2015 - 2024 by Linder Hard- und Software
;*
;*
EnableExplicit
OpenConsole("server_example Console")
PrintN("Server_Sample and tests")
;*
;* Includes:
;*
XIncludeFile "lhs_lib/SYS/lhs_log.pbi" ;Currently for Debugging
XIncludeFile "lhs_lib/SYS/lhs_log_ext.pbi" ;User for Access Log, Error Access Log, Error Log and maybe more.
XIncludeFile "lhs_lib/SYS/lhs_sys_debug_wrapper.pbi"
XIncludeFile "lweb_header.pbi"
XIncludeFile "lweb.pbi"
@ -24,174 +25,64 @@ XIncludeFile "lweb.pbi"
;*
Define counter, v_lweb_srv_stop
Define Accesslog.s, Errorlog.s
;*
;* Basic Debug Log initialization:
;*
lhs_log::App_Name = "http-s_server_example"
lhs_log::SetLogFile("http-s_server_example_debug.log")
lhs_log::SetMaxSize(32)
lhs_log::SetLogDateFormat("%yyyy.%mm.%dd %hh:%ii:%ss")
lhs_log::SetLogFileDateFormat("%yyyy_%mm_%dd_%hh_%ii_%ss")
lhs_log::Init()
Global Accesslog.s, Errorlog.s, Cachelog.s, DebugLog.s, Debuggings.s
;*
;* Enable extended Logging:
;*
Accesslog = lhs_log_ext::Create("Accesslog")
Errorlog = lhs_log_ext::Create("Errorlog")
lhs_log::Out("Errorlog UUID:"+Errorlog)
lhs_log::Out("Accesslog UUID:"+Accesslog)
lhs_log_ext::SetLogFile(Accesslog, "http-s_access.log")
lhs_log_ext::SetLogFile(Errorlog, "http-s_error.log")
lhs_log_ext::Init(Accesslog)
lhs_log_ext::Init(Errorlog)
lhs_web::set_config(lhs_web::#conf_log_Accesslog, Accesslog)
lhs_web::set_config(lhs_web::#conf_log_Errorlog, ErrorLog)
lhs_web::set_config(lhs_web::#conf_HTTP_port, "8084")
;lhs_web::set_config(lhs_web::#conf_binding, "127.0.0.1")
lhs_web::set_config(lhs_web::#conf_HTTP_binding, "0.0.0.0")
lhs_web::set_config(lhs_web::#conf_HTTPS_CA, "fullchain.pem")
lhs_web::set_config(lhs_web::#conf_HTTPS_Cert, "cert.pem")
lhs_web::set_config(lhs_web::#conf_HTTPS_Key, "privkey.pem")
lhs_web::set_config(lhs_web::#conf_HTTPS_Key_Pass, "")
lhs_web::set_config(lhs_web::#conf_HTTPS_Binding, "0.0.0.0")
lhs_web::set_config(lhs_web::#conf_HTTPS_Port, "8446")
lhs_web::set_config(lhs_web::#conf_HTTPS_Enable, "1")
lhs_web::set_config(lhs_web::#conf_defaultfile, "/index.html")
lhs_web::set_config(lhs_web::#conf_basedir, "/home/renlin/testweb/")
lhs_web::set_config(lhs_web::#conf_error400, "integrated")
lhs_web::set_config(lhs_web::#conf_max_HTTP_clients, "100")
lhs_web::set_config(lhs_web::#conf_max_HTTPS_clients, "100")
lhs_web::set_config(lhs_web::#conf_cache_enable, "0")
DebugLog = lhs_log_ext::Create("DebugLog")
lhs_log_ext::SetLogFile(DebugLog, "lweb_debug.log")
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
;*
;* includes
;*
Procedure.s Sample_Header(Map Header.s())
Define *Text
Define.s Encoded, ZumSenden, TBD, Text
NewMap Response.s()
If Header("cookie:") <> ""
lhs_log::Out("A Cookie is set :" + Header("cookie:"))
Else
lhs_log::Out("No Cookie.")
EndIf
TBD="<div><div><h1>Header</h1></div><br/>"+#CRLF$
ResetMap(Header())
While NextMapElement(Header())
TBD = TBD+"<div>"+MapKey(Header())+" "+Header()+" </div><br/>"+#CRLF$
Wend
Text = "<!DOCTYPE html><html><header><title>Alle Client Headers</title></header><body>"+TBD+"</body></html>"
*Text = AllocateMemory(StringByteLength(Text))
PokeS(*Text, Text)
Encoded = Base64Encoder(*Text, MemorySize(*Text))
lhs_log::Out("Encoded: " + Encoded)
Response(lhs_web::#cha_R_ResponseContentType) = lhs_web::#response_string
Response(lhs_web::#cha_R_StringBase64) = Encoded
Response(lhs_web::#cha_R_ResponseType) = lhs_web::mimetype("html")
Response(lhs_web::#cha_R_http_head_status) = "200 OK"
If Header("cookie:") = ""
Response(lhs_web::#http_head_set_cookie) = "session=test"
EndIf
ZumSenden = lhs_web::MapToJSONString(Response())
lhs_log::Out("ZumSenden: " + ZumSenden)
ProcedureReturn ZumSenden
EndProcedure
Procedure.s Formular_Test(Map Header.s(), ContentData.s)
Define *Text
Define.s Encoded, ZumSenden, TBD, Text
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
lhs_log::Out("TBD:"+TBD)
lhs_log::Out("contentData:"+ContentData)
Text = "<!DOCTYPE html><html><header><title>Alle Client Headers</title></header><body>"+TBD+"<hr/><br/><h1>ConentJSON</h1><br/>"+ContentData+"</body></html>"
*Text = AllocateMemory(StringByteLength(Text))
PokeS(*Text, Text)
lhs_log::Out("Unencoded:"+PeekS(*Text, -1 , #PB_UTF8))
Encoded = Base64Encoder(*Text, MemorySize(*Text))
lhs_log::Out("Encoded: " + Encoded)
Response(lhs_web::#cha_R_ResponseContentType) = lhs_web::#response_string
Response(lhs_web::#cha_R_StringBase64) = Encoded
Response(lhs_web::#cha_R_ResponseType) = lhs_web::mimetype("html")
Response(lhs_web::#cha_R_http_head_status) = "200 OK"
ZumSenden = lhs_web::MapToJSONString(Response())
lhs_log::Out("ZumSenden: " + ZumSenden)
ProcedureReturn ZumSenden
EndProcedure
Procedure.s Php_Test(Map Header.s(), ContentData.s)
Define *Text, Php
Define.s Execute, Phpresult, Encoded, ZumSenden, Text
NewMap Response.s()
Execute = lhs_web::get_config(lhs_web::#conf_basedir) + Header(lhs_web::#http_head_request)
lhs_log::Out("To Execute:" + Execute)
Php = RunProgram("php", Execute, "", #PB_Program_Open | #PB_Program_Read)
Phpresult = ""
If Php
While ProgramRunning(Php)
If AvailableProgramOutput(Php)
Phpresult + ReadProgramString(Php) + #CRLF$
EndIf
Wend
CloseProgram(Php) ; Schließt die Verbindung zum Programm
EndIf
Text = Phpresult
*Text = AllocateMemory(StringByteLength(Text))
PokeS(*Text, Text)
lhs_log::Out("Unencoded:"+PeekS(*Text, -1 , #PB_UTF8))
Encoded = Base64Encoder(*Text, MemorySize(*Text))
lhs_log::Out("Encoded: " + Encoded)
Response(lhs_web::#cha_R_ResponseContentType) = lhs_web::#response_string
Response(lhs_web::#cha_R_StringBase64) = Encoded
Response(lhs_web::#cha_R_ResponseType) = lhs_web::mimetype("html")
Response(lhs_web::#cha_R_http_head_status) = "200 OK"
ZumSenden = lhs_web::MapToJSONString(Response())
lhs_log::Out("ZumSenden: " + ZumSenden)
ProcedureReturn ZumSenden
EndProcedure
lhs_web::register_client_handler("/server/show_client_headers", @Sample_Header(),lhs_web::#handler_proto_get, lhs_web::#handler_sub)
lhs_web::register_client_handler("/post_test", @Formular_Test(),lhs_web::#handler_proto_post, lhs_web::#handler_sub) ;Im zusammenspiel mit einem Formular
lhs_web::register_client_handler("php", @Php_Test(),lhs_web::#handler_proto_universal, lhs_web::#handler_type)
XIncludeFile "server_example_function.pbi"
PrintN("Read Configuration:")
;*
;* Start http & https Server
;* Read Configuration http & https Server
;*
If lhs_web::start_server()
lhs_log::Out("Server gestartet" + lhs_web::get_config(lhs_web::#conf_HTTP_port))
If lhs_web::server_initial("file:cfg/server_config.xml")
ldl::Logging("config succesfully loaded.")
Else
lhs_log::Out("Fehlgeschlagen")
ldl::Logging("config load failed.")
End
EndIf
PrintN("HTTP an Port:"+lhs_web::server_get_config("ports_http"))
PrintN("HTTPS an Port:"+lhs_web::server_get_config("ports_https"))
PrintN("Configuration read done.")
;*
;* Start Server
;*
PrintN("Start the Server")
lhs_web::main_server(0)
If lhs_web::server_start()
ldl::Logging("Server started")
Else
ldl::Logging("Start failed.")
End
EndIf
counter = 0
OpenConsole("Test")
PrintN("Webserver")
PrintN("HTTP an Port:"+lhs_web::get_config(lhs_web::#conf_HTTP_port))
PrintN("HTTPS an Port:"+lhs_web::get_config(lhs_web::#conf_HTTPS_Port))
PrintN("Server_Sample started.")
PrintN("Press Enter to Exit")
Input()
lhs_log::Close()
ldl::Logging("-------------------------------------------------------------------------------------------------------------------------------")
ldl::Logging("Server Stopped.")
ldl::Logging("-------------------------------------------------------------------------------------------------------------------------------")
lhs_log_ext::StopAllLogger()
lhs_web::server_stop()
PrintN("Finished")
End

107
server_example_function.pbi Normal file
View File

@ -0,0 +1,107 @@
Procedure.s Sample_Header(Map Header.s())
Define *Text
Define.s Encoded, ZumSenden, TBD, Text
NewMap Response.s()
If Header("cookie:") <> ""
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"A Cookie is set :" + Header("cookie:"))
Else
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"No Cookie.")
EndIf
TBD="<div><div><h1>Header</h1></div><br/>"+#CRLF$
ResetMap(Header())
While NextMapElement(Header())
TBD = TBD+"<div>"+MapKey(Header())+" "+Header()+" </div><br/>"+#CRLF$
Wend
Text = "<!DOCTYPE html><html><header><title>Alle Client Headers</title></header><body>"+TBD+"</body></html>"
*Text = AllocateMemory(StringByteLength(Text))
PokeS(*Text, Text)
Encoded = Base64Encoder(*Text, MemorySize(*Text))
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"Encoded: " + Encoded)
Response(lhs_web::#cha_R_ResponseContentType) = lhs_web::#response_string
Response(lhs_web::#cha_R_StringBase64) = Encoded
Response(lhs_web::#cha_R_ResponseType) = lhs_web::mimetype("html")
Response(lhs_web::#cha_R_http_head_status) = lhs_web::status_get_header("200")
If Header("cookie:") = ""
Response(lhs_web::#http_head_set_cookie) = "session=this will be after second call here"
EndIf
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"Status Header get: " + lhs_web::status_get_header("200"))
ZumSenden = lhs_web::MapToJSONString(Response())
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"ZumSenden: " + ZumSenden)
ProcedureReturn ZumSenden
EndProcedure
Procedure.s Formular_Test(Map Header.s(), ContentData.s)
Define *Text
Define.s Encoded, ZumSenden, TBD, Text
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
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"TBD:"+TBD)
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"contentData:"+ContentData)
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)
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"Unencoded:"+PeekS(*Text, -1 , #PB_UTF8))
Encoded = Base64Encoder(*Text, MemorySize(*Text))
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"Encoded: " + Encoded)
Response(lhs_web::#cha_R_ResponseContentType) = lhs_web::#response_string
Response(lhs_web::#cha_R_StringBase64) = Encoded
Response(lhs_web::#cha_R_ResponseType) = lhs_web::mimetype("html")
Response(lhs_web::#cha_R_http_head_status) = lhs_web::status_get_header("200")
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"Status Header get: " + lhs_web::status_get_header("200"))
ZumSenden = lhs_web::MapToJSONString(Response())
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"ZumSenden: " + ZumSenden)
ProcedureReturn ZumSenden
EndProcedure
Procedure.s Php_Test(Map Header.s(), ContentData.s)
Define *Text, Php
Define.s Execute, Phpresult, Encoded, ZumSenden, Text
NewMap Response.s()
Execute = lhs_web::get_config(lhs_web::#conf_basedir) + Header(lhs_web::#http_head_request)
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"To Execute:" + Execute)
Php = RunProgram("php", Execute, "", #PB_Program_Open | #PB_Program_Read)
Phpresult = ""
If Php
While ProgramRunning(Php)
If AvailableProgramOutput(Php)
Phpresult + ReadProgramString(Php) + #CRLF$
EndIf
Wend
CloseProgram(Php) ; Schließt die Verbindung zum Programm
EndIf
Text = Phpresult
*Text = AllocateMemory(StringByteLength(Text, #PB_UTF8))
PokeS(*Text, Text, -1, #PB_UTF8)
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"Unencoded:"+PeekS(*Text, -1 , #PB_UTF8))
Encoded = Base64Encoder(*Text, MemorySize(*Text))
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"Encoded: " + Encoded)
Response(lhs_web::#cha_R_ResponseContentType) = lhs_web::#response_string
Response(lhs_web::#cha_R_StringBase64) = Encoded
Response(lhs_web::#cha_R_ResponseType) = lhs_web::mimetype("html")
Response(lhs_web::#cha_R_http_head_status) = lhs_web::status_get_header("200")
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"Status Header get: " + lhs_web::status_get_header("200"))
ZumSenden = lhs_web::MapToJSONString(Response())
lhs_log_ext::OutL(lhs_web::get_config(lhs_web::#conf_Debug_logUUID), lhs_log_ext::#Debugging,"ZumSenden: " + ZumSenden)
ProcedureReturn ZumSenden
EndProcedure
lhs_web::register_client_handler("/server/show_client_headers", @Sample_Header(),lhs_web::#handler_proto_get, lhs_web::#handler_sub)
;lhs_web::register_client_handler("/post_test", @Formular_Test(),lhs_web::#handler_proto_post, lhs_web::#handler_sub) ;Im zusammenspiel mit einem Formular
lhs_web::register_client_handler("php", @Php_Test(),lhs_web::#handler_proto_universal, lhs_web::#handler_type)

View File

@ -0,0 +1,60 @@
;************************
;* server_example_function_library.pb
;*
;* Test library for the lweb server.
;*
;* Created and develobed by Linder Hard- und Software
;*
;*
XIncludeFile "lhs_lib/NET/lhs_web_helper.pbi"
Global.s ZumSenden
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