Individuell bearbeitete Subdirs
- Post - Get - Fixes in diversen bereichen... - Test Routinen erweitert - uvm.
This commit is contained in:
parent
47eb089154
commit
c6584ccb8f
3 changed files with 731 additions and 300 deletions
728
lweb.pbi
728
lweb.pbi
|
@ -80,6 +80,7 @@ Module lhs_web
|
||||||
Structure s_client_memory
|
Structure s_client_memory
|
||||||
Buffer.i
|
Buffer.i
|
||||||
Initialized.b
|
Initialized.b
|
||||||
|
Size.i
|
||||||
EndStructure
|
EndStructure
|
||||||
|
|
||||||
Structure s_file_cache
|
Structure s_file_cache
|
||||||
|
@ -100,6 +101,19 @@ Module lhs_web
|
||||||
client_test_srv.i
|
client_test_srv.i
|
||||||
EndStructure
|
EndStructure
|
||||||
|
|
||||||
|
Structure s_request_handler
|
||||||
|
call.i
|
||||||
|
type.i
|
||||||
|
routetype.i
|
||||||
|
EndStructure
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Enumeration cli_handler_infos 1
|
||||||
|
#get_handler_procedure ;Funktion die Aufgerufen werden muss
|
||||||
|
#get_handler_prototype ;Welcher Prototype
|
||||||
|
EndEnumeration
|
||||||
|
|
||||||
Global.i server_id
|
Global.i server_id
|
||||||
Global.i server_mutex = CreateMutex() ;Dieser Mutex dient zu der Sicherheit der Element Liste.
|
Global.i server_mutex = CreateMutex() ;Dieser Mutex dient zu der Sicherheit der Element Liste.
|
||||||
Global.i file_cache_mutex = CreateMutex()
|
Global.i file_cache_mutex = CreateMutex()
|
||||||
|
@ -108,9 +122,19 @@ Module lhs_web
|
||||||
Global NewMap m_file_cache_map.i()
|
Global NewMap m_file_cache_map.i()
|
||||||
Global NewMap m_file_cache.s_file_cache()
|
Global NewMap m_file_cache.s_file_cache()
|
||||||
Global NewMap m_clients.s_clients(conf_max_clients)
|
Global NewMap m_clients.s_clients(conf_max_clients)
|
||||||
|
Global NewMap m_request.s_request_handler()
|
||||||
|
|
||||||
;}
|
;}
|
||||||
|
|
||||||
|
;********************************
|
||||||
|
;*
|
||||||
|
;* Handler Prototypen
|
||||||
|
;*
|
||||||
|
|
||||||
|
Prototype.s WebHandler_Get(Map handler_Map.s())
|
||||||
|
Prototype.s WebHandler_Post(Map handler_Map.s(), ContentString.s)
|
||||||
|
Prototype.s WebHandler_Universal(Map handler_Map.s(), ContentString.s)
|
||||||
|
|
||||||
;********************************
|
;********************************
|
||||||
;*
|
;*
|
||||||
;* Proceduren Deklarierung
|
;* Proceduren Deklarierung
|
||||||
|
@ -120,12 +144,12 @@ Module lhs_web
|
||||||
Declare client(network_client_id.i)
|
Declare client(network_client_id.i)
|
||||||
Declare AddFileToCache(MemoryID.i, FileName.s, Size.i)
|
Declare AddFileToCache(MemoryID.i, FileName.s, Size.i)
|
||||||
Declare FileCache(Information.i)
|
Declare FileCache(Information.i)
|
||||||
|
Declare call_request(RequestString.s, Info.i=#get_handler_procedure)
|
||||||
Declare.s mimetype(file.s)
|
|
||||||
Declare.s http_day(Tag.i)
|
Declare.s http_day(Tag.i)
|
||||||
Declare.s http_month(Monat.i)
|
Declare.s http_month(Monat.i)
|
||||||
Declare.s http_header_generate(Map Header.s())
|
Declare.s http_header_generate(Map Header.s())
|
||||||
Declare.s Work_Header_to_JSONMap(String.s)
|
Declare.s Work_Header_to_JSONMap(String.s)
|
||||||
|
Declare.s Work_Post_ToJSON_x_www_form_urlencoded(ContentLength.i, MemorSize.i, Memory.i)
|
||||||
Declare.s GetFileFromCache(FileName.s, MemoryID.i)
|
Declare.s GetFileFromCache(FileName.s, MemoryID.i)
|
||||||
|
|
||||||
Procedure set_config(parameter.i=#conf_defaultfile, setting.s="index.html")
|
Procedure set_config(parameter.i=#conf_defaultfile, setting.s="index.html")
|
||||||
|
@ -174,6 +198,8 @@ Module lhs_web
|
||||||
ProcedureReturn Str(conf_max_clients)
|
ProcedureReturn Str(conf_max_clients)
|
||||||
Case #conf_server_type
|
Case #conf_server_type
|
||||||
ProcedureReturn Str(conf_server_type)
|
ProcedureReturn Str(conf_server_type)
|
||||||
|
Case #conf_port
|
||||||
|
ProcedureReturn Str(conf_port)
|
||||||
Default
|
Default
|
||||||
ProcedureReturn ""
|
ProcedureReturn ""
|
||||||
EndSelect
|
EndSelect
|
||||||
|
@ -208,7 +234,7 @@ Module lhs_web
|
||||||
thread_alive = #True
|
thread_alive = #True
|
||||||
Debug "AllOk"
|
Debug "AllOk"
|
||||||
Repeat
|
Repeat
|
||||||
;Daten Sendeauftrag vorhanden?
|
;Ist etwas passiert ?
|
||||||
|
|
||||||
network_event = NetworkServerEvent(network_server_id)
|
network_event = NetworkServerEvent(network_server_id)
|
||||||
Select network_event
|
Select network_event
|
||||||
|
@ -311,15 +337,17 @@ Module lhs_web
|
||||||
|
|
||||||
Procedure client(network_client_id.i)
|
Procedure client(network_client_id.i)
|
||||||
Protected thread_cli_id = network_client_id
|
Protected thread_cli_id = network_client_id
|
||||||
Protected cli_stop, MyThreadJSON
|
Protected cli_stop, MyThreadJSON, ToCall, ToCallType
|
||||||
Protected thread_temp_string.s, thread_temp_cache.s, thread_temp_cache_memory, temp_receivelength
|
Protected thread_temp_string.s, thread_temp_cache.s, thread_temp_cache_memory, temp_receivelength, thread_temp_decode_memory
|
||||||
Protected thread_command_length, thread_max_pos, thread_pos, thread_reasign
|
Protected thread_command_length, thread_max_pos, thread_pos, thread_reasign
|
||||||
Protected thread_file_size, thread_file_handle
|
Protected thread_data_size, thread_file_handle
|
||||||
Protected.s thread_requested, thread_type, thread_date, thread_header, thread_work, JSONStringToMap
|
Protected.s thread_requested, thread_type, thread_date, thread_header, thread_work, JSONStringToMap, Handler_Response, response_status, PostMapString
|
||||||
Protected thread_buffer, thread_buffer_offset, thread_buffer_length, buffer_sent
|
Protected thread_buffer, thread_buffer_offset, thread_buffer_length, buffer_sent
|
||||||
Protected.b thread_alive = #True, error_message = #False
|
Protected.b thread_alive = #True, error_message = #False
|
||||||
Define NewMap Header.s()
|
Define NewMap Header.s()
|
||||||
;{
|
Define NewMap Response.s()
|
||||||
|
Define NewMap Post.s()
|
||||||
|
|
||||||
Debug "Client Thread Started. ID:" + Str(network_client_id)
|
Debug "Client Thread Started. ID:" + Str(network_client_id)
|
||||||
Repeat
|
Repeat
|
||||||
;Prüfen ob der Thread was zu tun hat.
|
;Prüfen ob der Thread was zu tun hat.
|
||||||
|
@ -340,8 +368,10 @@ Module lhs_web
|
||||||
EndIf
|
EndIf
|
||||||
temp_receivelength = ReceiveNetworkData(thread_cli_id, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer, 65536)
|
temp_receivelength = ReceiveNetworkData(thread_cli_id, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer, 65536)
|
||||||
If temp_receivelength = -1
|
If temp_receivelength = -1
|
||||||
|
Debug "Empfangsfehler."
|
||||||
Break
|
Break
|
||||||
ElseIf temp_receivelength = 65536
|
ElseIf temp_receivelength = 65536
|
||||||
|
m_clients(Str(thread_cli_id))\datenbuffer()\Size = temp_receivelength
|
||||||
counter_mem_buffers = 2
|
counter_mem_buffers = 2
|
||||||
Repeat
|
Repeat
|
||||||
AddElement(m_clients(Str(thread_cli_id))\datenbuffer())
|
AddElement(m_clients(Str(thread_cli_id))\datenbuffer())
|
||||||
|
@ -353,11 +383,14 @@ Module lhs_web
|
||||||
Break 2
|
Break 2
|
||||||
EndIf
|
EndIf
|
||||||
temp_receivelength = ReceiveNetworkData(thread_cli_id, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer, 65536)
|
temp_receivelength = ReceiveNetworkData(thread_cli_id, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer, 65536)
|
||||||
|
m_clients(Str(thread_cli_id))\datenbuffer()\Size = temp_receivelength
|
||||||
counter_mem_buffers + 1
|
counter_mem_buffers + 1
|
||||||
If temp_receivelength = -1
|
If temp_receivelength = -1
|
||||||
Break 2
|
Break 2
|
||||||
EndIf
|
EndIf
|
||||||
Until temp_receivelength < 65536
|
Until temp_receivelength < 65536
|
||||||
|
Else
|
||||||
|
m_clients(Str(thread_cli_id))\datenbuffer()\Size = temp_receivelength
|
||||||
EndIf
|
EndIf
|
||||||
;Alle Daten empfangen.
|
;Alle Daten empfangen.
|
||||||
Debug "Anzahl Buffer:" + Str(ListSize(m_clients(Str(thread_cli_id))\datenbuffer()))
|
Debug "Anzahl Buffer:" + Str(ListSize(m_clients(Str(thread_cli_id))\datenbuffer()))
|
||||||
|
@ -383,6 +416,8 @@ Module lhs_web
|
||||||
;Empfang abgeschlossen
|
;Empfang abgeschlossen
|
||||||
;Buffer Bearbeiten
|
;Buffer Bearbeiten
|
||||||
;Thread in Bearbeitungsmodus Setzen.
|
;Thread in Bearbeitungsmodus Setzen.
|
||||||
|
;TODO: Was ist mit zusammenhängenden Datenbuffern grosse Post/Put z.B.
|
||||||
|
|
||||||
;{
|
;{
|
||||||
Debug "Daten vollständig empfangen. Abarbeiten."
|
Debug "Daten vollständig empfangen. Abarbeiten."
|
||||||
m_clients(Str(thread_cli_id))\client_do_cli = #CLI_DO_DataWorking
|
m_clients(Str(thread_cli_id))\client_do_cli = #CLI_DO_DataWorking
|
||||||
|
@ -390,8 +425,9 @@ Module lhs_web
|
||||||
ResetList(m_clients(Str(thread_cli_id))\datenbuffer())
|
ResetList(m_clients(Str(thread_cli_id))\datenbuffer())
|
||||||
While NextElement(m_clients(Str(thread_cli_id))\datenbuffer())
|
While NextElement(m_clients(Str(thread_cli_id))\datenbuffer())
|
||||||
|
|
||||||
thread_work = PeekS(m_clients(Str(thread_cli_id))\datenbuffer()\Buffer, 16384, #PB_Ascii) ;Header solte wohl nicht grösser als 16KB sein
|
thread_work = PeekS(m_clients(Str(thread_cli_id))\datenbuffer()\Buffer, m_clients(Str(thread_cli_id))\datenbuffer()\Size, #PB_Ascii)
|
||||||
;Header to Map
|
;Header to Map
|
||||||
|
Debug "Datenbuffer:"+ Mid(thread_work,1,256)
|
||||||
JSONStringToMap = Work_Header_to_JSONMap(thread_work)
|
JSONStringToMap = Work_Header_to_JSONMap(thread_work)
|
||||||
If JSONStringToMap <> #error_string
|
If JSONStringToMap <> #error_string
|
||||||
MyThreadJSON = ParseJSON(#PB_Any, JSONStringToMap)
|
MyThreadJSON = ParseJSON(#PB_Any, JSONStringToMap)
|
||||||
|
@ -401,30 +437,82 @@ Module lhs_web
|
||||||
FreeJSON(MyThreadJSON)
|
FreeJSON(MyThreadJSON)
|
||||||
Else
|
Else
|
||||||
;WTF ???
|
;WTF ???
|
||||||
Break ; Thread abschiessen
|
Break 2 ; Thread abschiessen
|
||||||
EndIf
|
EndIf
|
||||||
Else
|
Else
|
||||||
error_message = #True
|
error_message = #True
|
||||||
EndIf
|
EndIf
|
||||||
|
|
||||||
|
|
||||||
Debug Mid(thread_work,1,256)
|
|
||||||
Debug JSONStringToMap
|
|
||||||
|
|
||||||
If Header(#http_head_method) = #http_method_get
|
Debug "JSONString:"+ JSONStringToMap
|
||||||
thread_command_length = 3
|
thread_type = ""
|
||||||
|
Select Header(#http_head_method)
|
||||||
|
Case #http_method_get
|
||||||
;********************************
|
;********************************
|
||||||
;*
|
;*
|
||||||
;* Default GET
|
;* Default GET
|
||||||
;*
|
;*
|
||||||
|
;{
|
||||||
Debug #http_method_get
|
Debug #http_method_get
|
||||||
If Header(#http_head_request) = "/"
|
If Header(#http_head_request) = "/"
|
||||||
thread_requested = conf_defaultfile
|
thread_requested = conf_defaultfile
|
||||||
Else
|
Else
|
||||||
thread_requested = Header(#http_head_request)
|
thread_requested = Header(#http_head_request)
|
||||||
EndIf
|
EndIf
|
||||||
If conf_cache_enable = 1
|
Debug "Requested:"+thread_requested
|
||||||
|
ToCallType = call_request(thread_requested, #get_handler_prototype)
|
||||||
|
If ToCallType = #handler_proto_universal Or ToCallType = #handler_proto_get
|
||||||
|
ToCall = call_request(thread_requested)
|
||||||
|
Else
|
||||||
|
ToCall = 0
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
If ToCall > 0 ;Dann ist eine Funktion hinterlegt und zulässig aufgerufen zu werden.
|
||||||
|
;{ Dynamischer WebHandler
|
||||||
|
|
||||||
|
Select ToCallType
|
||||||
|
Case #handler_proto_universal
|
||||||
|
Define.WebHandler_Universal ToCallProcedure = ToCall
|
||||||
|
Handler_Response = ToCallProcedure(Header(), "")
|
||||||
|
|
||||||
|
Case #handler_proto_get
|
||||||
|
Define.WebHandler_Get ToCallProcedure = ToCall
|
||||||
|
Handler_Response = ToCallProcedure(Header())
|
||||||
|
|
||||||
|
EndSelect
|
||||||
|
Debug "Main Client Response :"+Handler_Response
|
||||||
|
MyThreadJSON = ParseJSON(#PB_Any, Handler_Response)
|
||||||
|
If MyThreadJSON
|
||||||
|
ClearMap(Response())
|
||||||
|
ExtractJSONMap(JSONValue(MyThreadJSON), Response())
|
||||||
|
FreeJSON(MyThreadJSON)
|
||||||
|
Else
|
||||||
|
;WTF ???
|
||||||
|
Debug "Fehler Absturz"
|
||||||
|
Break 2 ; Thread abschiessen
|
||||||
|
EndIf
|
||||||
|
Debug "Response Content:"+Response(#cha_R_ResponseContentType)
|
||||||
|
Select Response(#cha_R_ResponseContentType)
|
||||||
|
Case #response_Memory
|
||||||
|
thread_data_size = Val(Response(#cha_R_MemorySize))
|
||||||
|
thread_temp_cache_memory = Val(Response(#cha_R_MemoryAdress))
|
||||||
|
thread_type = Response(#cha_R_ResponseType)
|
||||||
|
Case #response_string
|
||||||
|
thread_temp_decode_memory = AllocateMemory(StringByteLength(Response(#cha_R_StringBase64)))
|
||||||
|
thread_data_size = Base64Decoder(Response(#cha_R_StringBase64), thread_temp_decode_memory, StringByteLength(Response(#cha_R_StringBase64)))
|
||||||
|
thread_temp_cache_memory = AllocateMemory(thread_data_size)
|
||||||
|
CopyMemory(thread_temp_decode_memory, thread_temp_cache_memory, thread_data_size)
|
||||||
|
FreeMemory(thread_temp_decode_memory)
|
||||||
|
thread_type = Response(#cha_R_ResponseType)
|
||||||
|
Default
|
||||||
|
;Solte ja nicht passieren.
|
||||||
|
EndSelect
|
||||||
|
Debug "Content Finished"
|
||||||
|
;}
|
||||||
|
|
||||||
|
ElseIf conf_cache_enable = 1
|
||||||
|
;{ Cached File Handling BUGGY!!!!!!!
|
||||||
thread_temp_cache_memory = AllocateMemory(1024)
|
thread_temp_cache_memory = AllocateMemory(1024)
|
||||||
thread_temp_cache = GetFileFromCache(thread_requested, thread_temp_cache_memory)
|
thread_temp_cache = GetFileFromCache(thread_requested, thread_temp_cache_memory)
|
||||||
If thread_temp_cache = #error_string
|
If thread_temp_cache = #error_string
|
||||||
|
@ -434,41 +522,49 @@ Module lhs_web
|
||||||
;Alles Ok
|
;Alles Ok
|
||||||
Else
|
Else
|
||||||
thread_file_handle = ReadFile(#PB_Any, conf_basedir + conf_defaultfile,#PB_File_SharedRead)
|
thread_file_handle = ReadFile(#PB_Any, conf_basedir + conf_defaultfile,#PB_File_SharedRead)
|
||||||
Debug conf_basedir + conf_defaultfile
|
Debug "FileDir:" + conf_basedir + conf_defaultfile
|
||||||
If Not thread_file_handle
|
If Not thread_file_handle
|
||||||
thread_file_handle = ReadFile(#PB_Any, "error.html")
|
thread_file_handle = ReadFile(#PB_Any, "error.html")
|
||||||
EndIf
|
EndIf
|
||||||
|
|
||||||
EndIf
|
EndIf
|
||||||
thread_file_size = Lof(thread_file_handle)
|
thread_data_size = Lof(thread_file_handle)
|
||||||
thread_temp_cache_memory = ReAllocateMemory(thread_temp_cache_memory, thread_file_size)
|
thread_temp_cache_memory = ReAllocateMemory(thread_temp_cache_memory, thread_data_size)
|
||||||
ReadData(thread_file_handle, thread_temp_cache_memory, thread_file_size)
|
ReadData(thread_file_handle, thread_temp_cache_memory, thread_data_size)
|
||||||
CloseFile(thread_file_handle)
|
CloseFile(thread_file_handle)
|
||||||
AddFileToCache(thread_temp_cache_memory, thread_requested, thread_file_size)
|
AddFileToCache(thread_temp_cache_memory, thread_requested, thread_data_size)
|
||||||
|
|
||||||
Else
|
Else
|
||||||
thread_file_size = Val(StringField(thread_temp_cache, 1, ":"))
|
thread_data_size = Val(StringField(thread_temp_cache, 1, ":"))
|
||||||
thread_temp_cache_memory = Val(StringField(thread_temp_cache, 2, ":"))
|
thread_temp_cache_memory = Val(StringField(thread_temp_cache, 2, ":"))
|
||||||
EndIf
|
EndIf
|
||||||
|
;}
|
||||||
|
|
||||||
Else
|
Else
|
||||||
|
;{ Uncached File Handling scheint stabil zu funktionieren mit Getestet 200 Clients à 100 Requests
|
||||||
thread_file_handle = ReadFile(#PB_Any, conf_basedir + thread_requested,#PB_File_SharedRead)
|
thread_file_handle = ReadFile(#PB_Any, conf_basedir + thread_requested,#PB_File_SharedRead)
|
||||||
If Not thread_file_handle
|
If Not thread_file_handle
|
||||||
thread_file_handle = ReadFile(#PB_Any, conf_basedir + conf_defaultfile,#PB_File_SharedRead)
|
thread_file_handle = ReadFile(#PB_Any, conf_basedir + conf_defaultfile,#PB_File_SharedRead)
|
||||||
Debug conf_basedir + conf_defaultfile
|
Debug "FileDir:" + conf_basedir + conf_defaultfile
|
||||||
If Not thread_file_handle
|
If Not thread_file_handle
|
||||||
thread_file_handle = ReadFile(#PB_Any, "error.html")
|
thread_file_handle = ReadFile(#PB_Any, "error.html")
|
||||||
EndIf
|
EndIf
|
||||||
EndIf
|
EndIf
|
||||||
|
|
||||||
thread_file_size = Lof(thread_file_handle)
|
thread_data_size = Lof(thread_file_handle)
|
||||||
thread_temp_cache_memory = AllocateMemory(thread_file_size)
|
thread_temp_cache_memory = AllocateMemory(thread_data_size)
|
||||||
ReadData(thread_file_handle, thread_temp_cache_memory, thread_file_size)
|
ReadData(thread_file_handle, thread_temp_cache_memory, thread_data_size)
|
||||||
CloseFile(thread_file_handle)
|
CloseFile(thread_file_handle)
|
||||||
|
;}
|
||||||
|
|
||||||
EndIf
|
EndIf
|
||||||
|
|
||||||
|
|
||||||
If thread_file_size
|
If thread_data_size
|
||||||
|
If thread_type =""
|
||||||
thread_type = mimetype(GetExtensionPart(thread_requested))
|
thread_type = mimetype(GetExtensionPart(thread_requested))
|
||||||
|
EndIf
|
||||||
|
|
||||||
thread_date = http_day(DayOfWeek(Date())) +
|
thread_date = http_day(DayOfWeek(Date())) +
|
||||||
Str(Day(Date())) +
|
Str(Day(Date())) +
|
||||||
http_month(Month(Date())) +
|
http_month(Month(Date())) +
|
||||||
|
@ -479,27 +575,150 @@ Module lhs_web
|
||||||
|
|
||||||
;lweb_srv_mod_mss()
|
;lweb_srv_mod_mss()
|
||||||
ClearMap(Header())
|
ClearMap(Header())
|
||||||
|
If Response(#cha_R_http_head_status) <> ""
|
||||||
|
Header(#http_head_status) = Response(#cha_R_http_head_status)
|
||||||
|
ElseIf response_status <> ""
|
||||||
|
Header(#http_head_status) = response_status
|
||||||
|
Else
|
||||||
Header(#http_head_status) = "200 OK"
|
Header(#http_head_status) = "200 OK"
|
||||||
Header(#http_head_content_length) = Str(thread_file_size)
|
EndIf
|
||||||
|
|
||||||
|
Header(#http_head_content_length) = Str(thread_data_size)
|
||||||
Header(#http_head_content_type) = thread_type
|
Header(#http_head_content_type) = thread_type
|
||||||
Header(#http_head_connection) = "Keep-Alive"
|
Header(#http_head_connection) = "Keep-Alive"
|
||||||
Header(#http_head_keep_alive) = "timeout=15, max=1000"
|
Header(#http_head_keep_alive) = "timeout=15, max=1000"
|
||||||
thread_header = http_header_generate(Header())
|
thread_header = http_header_generate(Header())
|
||||||
thread_buffer = AllocateMemory(thread_file_size+StringByteLength(thread_header)+12)
|
thread_buffer = AllocateMemory(thread_data_size+StringByteLength(thread_header)+12)
|
||||||
thread_buffer_offset = thread_buffer
|
thread_buffer_offset = thread_buffer
|
||||||
thread_buffer_length = PokeS(thread_buffer_offset, thread_header,-1, #PB_UTF8|#PB_String_NoZero) : thread_buffer_offset + thread_buffer_length
|
thread_buffer_length = PokeS(thread_buffer_offset, thread_header,-1, #PB_UTF8|#PB_String_NoZero) : thread_buffer_offset + thread_buffer_length
|
||||||
Debug "Header Finished"
|
Debug "Header Finished"
|
||||||
EndIf
|
EndIf
|
||||||
|
;}
|
||||||
|
Case #http_method_post
|
||||||
|
|
||||||
|
|
||||||
ElseIf Header(#http_head_method) = #http_method_post
|
|
||||||
;********************************
|
;********************************
|
||||||
;*
|
;*
|
||||||
;* POST
|
;* POST
|
||||||
;*
|
;*
|
||||||
Debug #http_method_post
|
Debug #http_method_post
|
||||||
;PrintN("POST")
|
;PrintN("POST")
|
||||||
|
If LCase(Header(#http_head_content_type)) = #http_content_type_application_x_www_form_urlencoded
|
||||||
|
PostMapString = Work_Post_ToJSON_x_www_form_urlencoded(Val(Header(#http_head_content_length)), m_clients(Str(thread_cli_id))\datenbuffer()\Size, m_clients(Str(thread_cli_id))\datenbuffer()\Buffer)
|
||||||
|
MyThreadJSON = ParseJSON(#PB_Any, PostMapString)
|
||||||
|
If MyThreadJSON
|
||||||
|
ClearMap(Post())
|
||||||
|
ExtractJSONMap(JSONValue(MyThreadJSON), Post())
|
||||||
|
FreeJSON(MyThreadJSON)
|
||||||
|
Else
|
||||||
|
;WTF ???
|
||||||
|
Debug "Fehler Absturz"
|
||||||
|
Break 2 ; Thread abschiessen
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
If Header(#http_head_request) = "/"
|
||||||
|
thread_requested = conf_defaultfile
|
||||||
|
Else
|
||||||
|
thread_requested = Header(#http_head_request)
|
||||||
|
EndIf
|
||||||
|
Debug "Requested:"+thread_requested
|
||||||
|
ToCallType = call_request(thread_requested, #get_handler_prototype)
|
||||||
|
If ToCallType = #handler_proto_universal Or ToCallType = #handler_proto_post
|
||||||
|
ToCall = call_request(thread_requested)
|
||||||
|
Else
|
||||||
|
ToCall = 0
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
If ToCall > 0 ;Dann ist eine Funktion hinterlegt und zulässig aufgerufen zu werden.
|
||||||
|
;{ Dynamischer WebHandler
|
||||||
|
|
||||||
|
Select ToCallType
|
||||||
|
Case #handler_proto_universal
|
||||||
|
Define.WebHandler_Universal ToCallProcedure = ToCall
|
||||||
|
Handler_Response = ToCallProcedure(Header(), PostMapString )
|
||||||
|
|
||||||
|
Case #handler_proto_post
|
||||||
|
Define.WebHandler_Post ToCallProcedure = ToCall
|
||||||
|
Handler_Response = ToCallProcedure(Header(), PostMapString)
|
||||||
|
|
||||||
|
EndSelect
|
||||||
|
Debug "Main Client Response :"+Handler_Response
|
||||||
|
MyThreadJSON = ParseJSON(#PB_Any, Handler_Response)
|
||||||
|
If MyThreadJSON
|
||||||
|
ClearMap(Response())
|
||||||
|
ExtractJSONMap(JSONValue(MyThreadJSON), Response())
|
||||||
|
FreeJSON(MyThreadJSON)
|
||||||
|
Else
|
||||||
|
;WTF ???
|
||||||
|
Debug "Fehler Absturz"
|
||||||
|
Break 2 ; Thread abschiessen
|
||||||
|
EndIf
|
||||||
|
Debug "Response Content:"+Response(#cha_R_ResponseContentType)
|
||||||
|
Select Response(#cha_R_ResponseContentType)
|
||||||
|
Case #response_Memory
|
||||||
|
thread_data_size = Val(Response(#cha_R_MemorySize))
|
||||||
|
thread_temp_cache_memory = Val(Response(#cha_R_MemoryAdress))
|
||||||
|
thread_type = Response(#cha_R_ResponseType)
|
||||||
|
Case #response_string
|
||||||
|
thread_temp_decode_memory = AllocateMemory(StringByteLength(Response(#cha_R_StringBase64)))
|
||||||
|
thread_data_size = Base64Decoder(Response(#cha_R_StringBase64), thread_temp_decode_memory, StringByteLength(Response(#cha_R_StringBase64)))
|
||||||
|
thread_temp_cache_memory = AllocateMemory(thread_data_size)
|
||||||
|
CopyMemory(thread_temp_decode_memory, thread_temp_cache_memory, thread_data_size)
|
||||||
|
FreeMemory(thread_temp_decode_memory)
|
||||||
|
thread_type = Response(#cha_R_ResponseType)
|
||||||
|
Default
|
||||||
|
;Solte ja nicht passieren.
|
||||||
|
EndSelect
|
||||||
|
Debug "Content Finished"
|
||||||
|
;}
|
||||||
|
|
||||||
|
ElseIf conf_cache_enable = 1
|
||||||
|
;{ Cached File Handling BUGGY!!!!!!!
|
||||||
|
thread_temp_cache_memory = AllocateMemory(1024)
|
||||||
|
thread_temp_cache = GetFileFromCache(thread_requested, thread_temp_cache_memory)
|
||||||
|
If thread_temp_cache = #error_string
|
||||||
|
thread_file_handle = ReadFile(#PB_Any, conf_basedir + thread_requested,#PB_File_SharedRead)
|
||||||
|
|
||||||
|
If thread_file_handle
|
||||||
|
;Alles Ok
|
||||||
|
Else
|
||||||
|
thread_file_handle = ReadFile(#PB_Any, conf_basedir + conf_defaultfile,#PB_File_SharedRead)
|
||||||
|
Debug "FileDir:" + conf_basedir + conf_defaultfile
|
||||||
|
If Not thread_file_handle
|
||||||
|
thread_file_handle = ReadFile(#PB_Any, "error.html")
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
EndIf
|
||||||
|
thread_data_size = Lof(thread_file_handle)
|
||||||
|
thread_temp_cache_memory = ReAllocateMemory(thread_temp_cache_memory, thread_data_size)
|
||||||
|
ReadData(thread_file_handle, thread_temp_cache_memory, thread_data_size)
|
||||||
|
CloseFile(thread_file_handle)
|
||||||
|
AddFileToCache(thread_temp_cache_memory, thread_requested, thread_data_size)
|
||||||
|
|
||||||
|
Else
|
||||||
|
thread_data_size = Val(StringField(thread_temp_cache, 1, ":"))
|
||||||
|
thread_temp_cache_memory = Val(StringField(thread_temp_cache, 2, ":"))
|
||||||
|
EndIf
|
||||||
|
;}
|
||||||
|
|
||||||
|
Else
|
||||||
|
;{ Uncached File Handling scheint stabil zu funktionieren mit Getestet 200 Clients à 100 Requests
|
||||||
|
thread_file_handle = ReadFile(#PB_Any, conf_basedir + thread_requested,#PB_File_SharedRead)
|
||||||
|
If Not thread_file_handle
|
||||||
|
thread_file_handle = ReadFile(#PB_Any, conf_basedir + conf_defaultfile,#PB_File_SharedRead)
|
||||||
|
Debug "FileDir:" + conf_basedir + conf_defaultfile
|
||||||
|
If Not thread_file_handle
|
||||||
|
thread_file_handle = ReadFile(#PB_Any, "error.html")
|
||||||
|
EndIf
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
thread_data_size = Lof(thread_file_handle)
|
||||||
|
thread_temp_cache_memory = AllocateMemory(thread_data_size)
|
||||||
|
ReadData(thread_file_handle, thread_temp_cache_memory, thread_data_size)
|
||||||
|
CloseFile(thread_file_handle)
|
||||||
|
;}
|
||||||
|
|
||||||
|
EndIf
|
||||||
If Header(#http_head_request) = "/"
|
If Header(#http_head_request) = "/"
|
||||||
thread_requested = conf_defaultfile
|
thread_requested = conf_defaultfile
|
||||||
Else
|
Else
|
||||||
|
@ -510,15 +729,17 @@ Module lhs_web
|
||||||
|
|
||||||
If Not thread_file_handle
|
If Not thread_file_handle
|
||||||
thread_file_handle = ReadFile(#PB_Any, conf_basedir + conf_defaultfile,#PB_File_SharedRead)
|
thread_file_handle = ReadFile(#PB_Any, conf_basedir + conf_defaultfile,#PB_File_SharedRead)
|
||||||
Debug conf_basedir + thread_requested
|
Debug "FileDir:" + conf_basedir + thread_requested
|
||||||
If Not thread_file_handle
|
If Not thread_file_handle
|
||||||
thread_file_handle = ReadFile(#PB_Any, "error.html")
|
thread_file_handle = ReadFile(#PB_Any, "error.html")
|
||||||
EndIf
|
EndIf
|
||||||
|
|
||||||
EndIf
|
EndIf
|
||||||
If thread_file_handle
|
If thread_data_size
|
||||||
thread_file_size = Lof(thread_file_handle)
|
If thread_type =""
|
||||||
thread_type = mimetype(GetExtensionPart(thread_requested))
|
thread_type = mimetype(GetExtensionPart(thread_requested))
|
||||||
|
EndIf
|
||||||
|
|
||||||
thread_date = http_day(DayOfWeek(Date())) +
|
thread_date = http_day(DayOfWeek(Date())) +
|
||||||
Str(Day(Date())) +
|
Str(Day(Date())) +
|
||||||
http_month(Month(Date())) +
|
http_month(Month(Date())) +
|
||||||
|
@ -526,83 +747,50 @@ Module lhs_web
|
||||||
" " +
|
" " +
|
||||||
FormatDate("%hh:%ii:%ss GMT+1", Date())
|
FormatDate("%hh:%ii:%ss GMT+1", Date())
|
||||||
|
|
||||||
thread_buffer = AllocateMemory(thread_file_size+500)
|
|
||||||
thread_buffer_offset = thread_buffer
|
|
||||||
|
|
||||||
|
|
||||||
;HEADER and Strings:
|
|
||||||
; POST /login.mss HTTP/1.1
|
|
||||||
; Host: localhost:61000
|
|
||||||
; User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0
|
|
||||||
; Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
|
||||||
; Accept-Language: de,en-US;q=0.7,en;q=0.3
|
|
||||||
; Accept-Encoding: gzip, deflate
|
|
||||||
; Referer: http://localhost:61000/index.html
|
|
||||||
; Connection: keep-alive
|
|
||||||
; Content-Type: application/x-www-form-urlencoded
|
|
||||||
; Content-Length: 27
|
|
||||||
;
|
|
||||||
; username=test&passwort=test
|
|
||||||
|
|
||||||
;********************************3
|
|
||||||
;* Script öffnen
|
|
||||||
;*
|
|
||||||
;* Akzeptierte Parameter:
|
|
||||||
;*
|
|
||||||
;* username
|
|
||||||
;* passwort
|
|
||||||
;* sid
|
|
||||||
;*
|
|
||||||
;* Identifikation und übergabe des paramters an script ...
|
|
||||||
;Fixe Loginfunktion mit user und pasd
|
|
||||||
; Position_String = FindString(Temp_String, "Content-Length:")
|
|
||||||
;
|
|
||||||
; If Position_String > 0
|
|
||||||
; ;Länge Content identifizieren.
|
|
||||||
;
|
|
||||||
;
|
|
||||||
; EndIf
|
|
||||||
;
|
|
||||||
; While NextElement(HTTP_List())
|
|
||||||
; If HTTP_List()\ID = Event_Network_Client
|
|
||||||
; HTTP_List()\Login = 1
|
|
||||||
; Break
|
|
||||||
; Else
|
|
||||||
; ;Do Nothing
|
|
||||||
;
|
|
||||||
; EndIf
|
|
||||||
; Wend
|
|
||||||
|
|
||||||
;lweb_srv_mod_mss()
|
;lweb_srv_mod_mss()
|
||||||
ClearMap(Header())
|
ClearMap(Header())
|
||||||
|
If Response(#cha_R_http_head_status) <> ""
|
||||||
|
Header(#http_head_status) = Response(#cha_R_http_head_status)
|
||||||
|
ElseIf response_status <> ""
|
||||||
|
Header(#http_head_status) = response_status
|
||||||
|
Else
|
||||||
Header(#http_head_status) = "200 OK"
|
Header(#http_head_status) = "200 OK"
|
||||||
Header(#http_head_content_length) = Str(thread_file_size)
|
EndIf
|
||||||
|
|
||||||
|
Header(#http_head_content_length) = Str(thread_data_size)
|
||||||
Header(#http_head_content_type) = thread_type
|
Header(#http_head_content_type) = thread_type
|
||||||
|
Header(#http_head_connection) = "Keep-Alive"
|
||||||
|
Header(#http_head_keep_alive) = "timeout=15, max=1000"
|
||||||
thread_header = http_header_generate(Header())
|
thread_header = http_header_generate(Header())
|
||||||
|
thread_buffer = AllocateMemory(thread_data_size+StringByteLength(thread_header)+12)
|
||||||
|
thread_buffer_offset = thread_buffer
|
||||||
thread_buffer_length = PokeS(thread_buffer_offset, thread_header,-1, #PB_UTF8|#PB_String_NoZero) : thread_buffer_offset + thread_buffer_length
|
thread_buffer_length = PokeS(thread_buffer_offset, thread_header,-1, #PB_UTF8|#PB_String_NoZero) : thread_buffer_offset + thread_buffer_length
|
||||||
Debug "Header Finished"
|
Debug "Header Finished"
|
||||||
EndIf
|
EndIf
|
||||||
Else
|
|
||||||
|
Default
|
||||||
;************************************
|
;************************************
|
||||||
;*
|
;*
|
||||||
;* Not a supported Command in HTTP Header Cleanup.
|
;* Not a supported Command in HTTP Header Cleanup.
|
||||||
;*
|
;*
|
||||||
;* Read Buffer to Memory and Clear Buffer to Zero until the complete Networkbuffer from this Client is Cleaned.
|
;* Read Buffer to Memory and Clear Buffer to Zero until the complete Networkbuffer from this Client is Cleaned.
|
||||||
;*
|
;*
|
||||||
|
EndSelect
|
||||||
|
|
||||||
EndIf
|
CopyMemory(thread_temp_cache_memory, thread_buffer_offset, thread_data_size)
|
||||||
|
|
||||||
CopyMemory(thread_temp_cache_memory, thread_buffer_offset, thread_file_size)
|
|
||||||
FreeMemory(thread_temp_cache_memory)
|
FreeMemory(thread_temp_cache_memory)
|
||||||
; EndIf
|
; EndIf
|
||||||
|
|
||||||
Debug "HTTP File Buffer Cleaned."
|
Debug "HTTP File Buffer Cleaned."
|
||||||
;Löschen des eingang Speichers.
|
;Löschen des eingang Speichers.
|
||||||
|
If m_clients(Str(thread_cli_id))\datenbuffer()\Buffer > 0
|
||||||
FreeMemory(m_clients(Str(thread_cli_id))\datenbuffer()\Buffer)
|
FreeMemory(m_clients(Str(thread_cli_id))\datenbuffer()\Buffer)
|
||||||
|
EndIf
|
||||||
DeleteElement(m_clients(Str(thread_cli_id))\datenbuffer())
|
DeleteElement(m_clients(Str(thread_cli_id))\datenbuffer())
|
||||||
;Daten Senden...
|
;Daten Senden...
|
||||||
|
|
||||||
If SendNetworkData(thread_cli_id, thread_buffer , thread_file_size+(thread_buffer_offset-thread_buffer)) = thread_file_size+(thread_buffer_offset-thread_buffer)
|
If SendNetworkData(thread_cli_id, thread_buffer , thread_data_size+(thread_buffer_offset-thread_buffer)) = thread_data_size+(thread_buffer_offset-thread_buffer)
|
||||||
;Ok
|
;Ok
|
||||||
;Debug "Gesendet:" + PeekS(thread_buffer,thread_buffer_length, #PB_Ascii)
|
;Debug "Gesendet:" + PeekS(thread_buffer,thread_buffer_length, #PB_Ascii)
|
||||||
FreeMemory(thread_buffer)
|
FreeMemory(thread_buffer)
|
||||||
|
@ -623,6 +811,7 @@ Module lhs_web
|
||||||
|
|
||||||
EndSelect
|
EndSelect
|
||||||
EndIf
|
EndIf
|
||||||
|
;}
|
||||||
|
|
||||||
Until thread_alive = #False
|
Until thread_alive = #False
|
||||||
ResetList(m_clients(Str(thread_cli_id))\datenbuffer())
|
ResetList(m_clients(Str(thread_cli_id))\datenbuffer())
|
||||||
|
@ -637,109 +826,10 @@ Module lhs_web
|
||||||
|
|
||||||
DeleteMapElement(m_clients(), Str(thread_cli_id))
|
DeleteMapElement(m_clients(), Str(thread_cli_id))
|
||||||
Debug "Thread Beendet."
|
Debug "Thread Beendet."
|
||||||
;}
|
|
||||||
EndProcedure
|
|
||||||
|
|
||||||
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
|
|
||||||
conf_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
|
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 = conf_cache_maxsize * 1024 * 1024
|
|
||||||
FileCacheCleanerThread = CreateThread(@FileCacheCleaner(), MaxSize)
|
|
||||||
|
|
||||||
Repeat
|
|
||||||
WaitSemaphore(file_cache_semaphore)
|
|
||||||
Debug "Adresse:"+m_file_cache()\Buffer
|
|
||||||
If (m_file_cache()\Size + conf_cache_current) <= MaxSize
|
|
||||||
conf_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 = conf_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(conf_cache_maxsize*1024*1024)+" Actual Size:"+Str(conf_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)
|
|
||||||
Else
|
|
||||||
Debug "File not in cache was to full:"+FileName+ " MaxSize:"+Str(conf_cache_maxsize)+" Actual Size:"+Str(conf_cache_current/1024/1024)
|
|
||||||
EndIf
|
|
||||||
|
|
||||||
UnlockMutex(file_cache_mutex)
|
|
||||||
EndProcedure
|
|
||||||
|
|
||||||
Procedure.s GetFileFromCache(FileName.s, MemoryID.i)
|
|
||||||
Protected String.s
|
|
||||||
|
|
||||||
If TryLockMutex(file_cache_mutex)
|
|
||||||
If m_file_cache(FileName)\Is
|
|
||||||
MemoryID = ReAllocateMemory(MemoryID, m_file_cache(FileName)\Size)
|
|
||||||
CopyMemory(m_file_cache(FileName)\Buffer, MemoryID, m_file_cache(FileName)\Size)
|
|
||||||
String.s = Str(m_file_cache(FileName)\Size) + ":" + Str(MemoryID)
|
|
||||||
Else
|
|
||||||
String.s = #error_string
|
|
||||||
EndIf
|
|
||||||
UnlockMutex(file_cache_mutex)
|
|
||||||
Debug "Get from cache: "+FileName+">"+String+"-------------------------------------------------------------<"
|
|
||||||
ProcedureReturn String.s
|
|
||||||
Else
|
|
||||||
ProcedureReturn #error_string
|
|
||||||
EndIf
|
|
||||||
|
|
||||||
EndProcedure
|
|
||||||
|
|
||||||
Procedure.s mimetype(file.s)
|
Procedure.s mimetype(file.s)
|
||||||
Select file
|
Select file
|
||||||
Case "png"
|
Case "png"
|
||||||
|
@ -896,11 +986,275 @@ Module lhs_web
|
||||||
|
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
Procedure.s Work_Post_Header(InMemory.i)
|
Procedure.s Work_Post_Header(ContentLength.i, InMemory.i, Length.i)
|
||||||
|
|
||||||
|
;HEADER and Strings:
|
||||||
|
; POST /login.mss HTTP/1.1
|
||||||
|
; Host: localhost:61000
|
||||||
|
; User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:37.0) Gecko/20100101 Firefox/37.0
|
||||||
|
; Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||||
|
; Accept-Language: de,en-US;q=0.7,en;q=0.3
|
||||||
|
; Accept-Encoding: gzip, deflate
|
||||||
|
; Referer: http://localhost:61000/index.html
|
||||||
|
; Connection: keep-alive
|
||||||
|
; Content-Type: application/x-www-form-urlencoded
|
||||||
|
; Content-Length: 27
|
||||||
|
;
|
||||||
|
; username=test&passwort=test
|
||||||
|
|
||||||
|
;********************************3
|
||||||
|
;* Script öffnen
|
||||||
|
;*
|
||||||
|
;* Akzeptierte Parameter:
|
||||||
|
;*
|
||||||
|
;* username
|
||||||
|
;* passwort
|
||||||
|
;* sid
|
||||||
|
;*
|
||||||
|
;* Identifikation und übergabe des paramters an script ...
|
||||||
|
;Fixe Loginfunktion mit user und pasd
|
||||||
|
; Position_String = FindString(Temp_String, "Content-Length:")
|
||||||
|
;
|
||||||
|
; If Position_String > 0
|
||||||
|
; ;Länge Content identifizieren.
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; EndIf
|
||||||
|
;
|
||||||
|
; While NextElement(HTTP_List())
|
||||||
|
; If HTTP_List()\ID = Event_Network_Client
|
||||||
|
; HTTP_List()\Login = 1
|
||||||
|
; Break
|
||||||
|
; Else
|
||||||
|
; ;Do Nothing
|
||||||
|
;
|
||||||
|
; EndIf
|
||||||
|
; Wend
|
||||||
|
|
||||||
|
;lweb_srv_mod_mss()
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
Procedure call_request(RequestString.s, Info.i = #get_handler_procedure)
|
||||||
|
Protected CurrPos, Count, Counter, PartString.s
|
||||||
|
If m_request(GetExtensionPart(RequestString))\routetype = #handler_type
|
||||||
|
Select Info
|
||||||
|
Case #get_handler_procedure
|
||||||
|
ProcedureReturn m_request(GetExtensionPart(RequestString))\call
|
||||||
|
Case #get_handler_prototype
|
||||||
|
ProcedureReturn m_request(GetExtensionPart(RequestString))\type
|
||||||
|
Default
|
||||||
|
ProcedureReturn 0
|
||||||
|
EndSelect
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
If m_request(RequestString)\routetype = #handler_only Or m_request(RequestString)\routetype = #handler_sub
|
||||||
|
Select Info
|
||||||
|
Case #get_handler_procedure
|
||||||
|
ProcedureReturn m_request(RequestString)\call
|
||||||
|
Case #get_handler_prototype
|
||||||
|
ProcedureReturn m_request(RequestString)\type
|
||||||
|
Default
|
||||||
|
ProcedureReturn 0
|
||||||
|
EndSelect
|
||||||
|
ElseIf m_request(GetExtensionPart(RequestString))\routetype = #handler_sub
|
||||||
|
Select Info
|
||||||
|
Case #get_handler_procedure
|
||||||
|
ProcedureReturn m_request(GetExtensionPart(RequestString))\call
|
||||||
|
Case #get_handler_prototype
|
||||||
|
ProcedureReturn m_request(GetExtensionPart(RequestString))\type
|
||||||
|
Default
|
||||||
|
ProcedureReturn 0
|
||||||
|
EndSelect
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
;Check auf Sub
|
||||||
|
Counter = CountString(RequestString, "/")
|
||||||
|
Count = 0
|
||||||
|
CurrPos = 0
|
||||||
|
While Count < Counter
|
||||||
|
CurrPos = FindString(RequestString, "/", 2 + CurrPos )
|
||||||
|
PartString = Mid(RequestString, 1, CurrPos)
|
||||||
|
If m_request(PartString)\routetype = #handler_sub
|
||||||
|
Select Info
|
||||||
|
Case #get_handler_procedure
|
||||||
|
ProcedureReturn m_request(PartString)\call
|
||||||
|
Case #get_handler_prototype
|
||||||
|
ProcedureReturn m_request(PartString)\type
|
||||||
|
Default
|
||||||
|
ProcedureReturn 0
|
||||||
|
EndSelect
|
||||||
|
EndIf
|
||||||
|
Count + 1
|
||||||
|
Wend
|
||||||
|
|
||||||
|
ProcedureReturn 0
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
Procedure.s MapStringToJSONString(Map ConvertMap.s())
|
||||||
|
Protected MyJSON
|
||||||
|
Protected.s Response
|
||||||
|
MyJSON = CreateJSON(#PB_Any)
|
||||||
|
If MyJSON
|
||||||
|
InsertJSONMap(JSONValue(MyJSON), ConvertMap())
|
||||||
|
Response = ComposeJSON(MyJSON)
|
||||||
|
FreeJSON(MyJSON)
|
||||||
|
ProcedureReturn Response
|
||||||
|
EndIf
|
||||||
|
ProcedureReturn #error_string
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
Procedure.s Work_Post_ToJSON_x_www_form_urlencoded(ContentLength.i, MemorSize.i, Memory.i)
|
||||||
|
Define.s JSONString, Working, ContentString
|
||||||
|
Define CountParams, Count, JSON
|
||||||
|
Protected NewMap Posts.s()
|
||||||
|
|
||||||
|
If ContentLength > 0
|
||||||
|
OffsetMemory = Memory + (MemorSize - ContentLength)
|
||||||
|
ContentString = PeekS(OffsetMemory, ContentLength, #PB_UTF8)
|
||||||
|
;Zerlegen &
|
||||||
|
;Mapname = Content
|
||||||
|
If Len(ContentString) > 0
|
||||||
|
CountParams = CountString(ContentString,"&")
|
||||||
|
If CountParams = 0
|
||||||
|
If CountString(ContentString, "=")
|
||||||
|
Posts(StringField(ContentString, 1, "=")) = StringField(ContentString,2, "=")
|
||||||
|
Else
|
||||||
|
ProcedureReturn ""
|
||||||
|
EndIf
|
||||||
|
ElseIf CountParams > 0
|
||||||
|
Count = 0
|
||||||
|
Repeat
|
||||||
|
Posts(StringField(StringField(ContentString, Count + 1, "&"),1,"=")) = StringField(StringField(ContentString, Count + 1, "&"),2,"=")
|
||||||
|
;Debug "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
|
EndProcedure
|
||||||
|
|
||||||
Procedure.s Work_Get_Header(InMemory.i)
|
Procedure.s register_client_handler(Route.s, Callback.i, AppPrototype.i = #handler_proto_get, RouteType.i = #handler_sub)
|
||||||
|
m_request(Route)\type = AppPrototype
|
||||||
|
m_request(Route)\call = Callback
|
||||||
|
m_request(Route)\routetype = RouteType
|
||||||
|
Debug "Handler Registriert:"+Route
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
;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
|
||||||
|
conf_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 = conf_cache_maxsize * 1024 * 1024
|
||||||
|
FileCacheCleanerThread = CreateThread(@FileCacheCleaner(), MaxSize)
|
||||||
|
|
||||||
|
Repeat
|
||||||
|
WaitSemaphore(file_cache_semaphore)
|
||||||
|
Debug "Adresse:"+m_file_cache()\Buffer
|
||||||
|
If (m_file_cache()\Size + conf_cache_current) <= MaxSize
|
||||||
|
conf_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 = conf_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(conf_cache_maxsize*1024*1024)+" Actual Size:"+Str(conf_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)
|
||||||
|
Else
|
||||||
|
Debug "File not in cache was to full:"+FileName+ " MaxSize:"+Str(conf_cache_maxsize)+" Actual Size:"+Str(conf_cache_current/1024/1024)
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
UnlockMutex(file_cache_mutex)
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
Procedure.s GetFileFromCache(FileName.s, MemoryID.i)
|
||||||
|
Protected String.s
|
||||||
|
|
||||||
|
If TryLockMutex(file_cache_mutex)
|
||||||
|
If m_file_cache(FileName)\Is
|
||||||
|
MemoryID = ReAllocateMemory(MemoryID, m_file_cache(FileName)\Size)
|
||||||
|
CopyMemory(m_file_cache(FileName)\Buffer, MemoryID, m_file_cache(FileName)\Size)
|
||||||
|
String.s = Str(m_file_cache(FileName)\Size) + ":" + Str(MemoryID)
|
||||||
|
Else
|
||||||
|
String.s = #error_string
|
||||||
|
EndIf
|
||||||
|
UnlockMutex(file_cache_mutex)
|
||||||
|
Debug "Get from cache: "+FileName+">"+String+"-------------------------------------------------------------<"
|
||||||
|
ProcedureReturn String.s
|
||||||
|
Else
|
||||||
|
ProcedureReturn #error_string
|
||||||
|
EndIf
|
||||||
|
|
||||||
EndProcedure
|
EndProcedure
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,37 @@ DeclareModule lhs_web
|
||||||
#conf_cache_enable
|
#conf_cache_enable
|
||||||
EndEnumeration
|
EndEnumeration
|
||||||
|
|
||||||
Enumeration cli_handler
|
Enumeration cli_handler 1
|
||||||
#handler_only ;Reagiert nur auf die Url (Bsp. /rest/v1/test aber nicht auf /rest/v1/test/sub)
|
#handler_only ;Reagiert nur auf die Url (Bsp. /rest/v1/test aber nicht auf /rest/v1/test/sub)
|
||||||
#handler_sub ;Reagiert auf eine ganze Url die begint. (Bsp. /rest/v1/test sowie auch auf /rest/v1/test/sub)
|
#handler_sub ;Reagiert auf eine ganze Url die begint. (Bsp. /rest/v1/test sowie auch auf /rest/v1/test/sub)
|
||||||
#handler_type ;Reagiert auf datentypen (zb. *.php)
|
#handler_type ;Reagiert auf datentypen (zb. *.php = "php")
|
||||||
EndEnumeration
|
EndEnumeration
|
||||||
|
|
||||||
|
Enumeration e_handler_prototype 1
|
||||||
|
#handler_proto_universal
|
||||||
|
#handler_proto_post
|
||||||
|
#handler_proto_get
|
||||||
|
EndEnumeration
|
||||||
|
|
||||||
|
Enumeration cli_handler_app 1
|
||||||
|
#app_handler_map_string ;.s App(Requested.s, Map HandlerMap.s())
|
||||||
|
#app_handler_json ;.s App(Requested.s, JSONString.s)
|
||||||
|
#app_handler_string ;.s App(Requested.s, String.s)
|
||||||
|
#app_handler_ressource ;.s App(Requested.s)
|
||||||
|
EndEnumeration
|
||||||
|
|
||||||
|
#response_string = "response_string"
|
||||||
|
#response_Memory = "response_memory"
|
||||||
|
|
||||||
|
|
||||||
|
;cli_handler_app Return:
|
||||||
|
;Map.s() to JSONString
|
||||||
|
#cha_R_ResponseType = "ResponseType" ;Element ResponseType :Mimetype
|
||||||
|
#cha_R_ResponseContentType = "ResponseContentType" ;Element ResponseContentType :#response_string , #response_Memory
|
||||||
|
#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.
|
||||||
#error_string = "error"
|
#error_string = "error"
|
||||||
#http_head_method = "method"
|
#http_head_method = "method"
|
||||||
#http_head_request = "request"
|
#http_head_request = "request"
|
||||||
|
@ -50,13 +75,15 @@ DeclareModule lhs_web
|
||||||
#http_head_connection = "connection:"
|
#http_head_connection = "connection:"
|
||||||
#http_head_keep_alive = "keep-alive:"
|
#http_head_keep_alive = "keep-alive:"
|
||||||
|
|
||||||
|
#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 set_config(parameter.i=#conf_defaultfile, setting.s="index.html")
|
||||||
Declare.s get_config(parameter.i=#conf_defaultfile)
|
Declare.s get_config(parameter.i=#conf_defaultfile)
|
||||||
Declare start_server()
|
Declare start_server()
|
||||||
;Declare.s register_client_handler(Route.s, Callback.i, Parameter.i = #handler_sub)
|
Declare.s register_client_handler(Route.s, Callback.i, AppPrototype.i = #handler_proto_get, RouteType.i = #handler_sub)
|
||||||
;Declare.s register_client_handler_JSON(Route.s, Callback.i, JSONString.s, Parameter.i = #handler_sub)
|
Declare.s mimetype(file.s)
|
||||||
|
Declare.s MapStringToJSONString(Map ConvertMap.s())
|
||||||
;Declare register_client_handler(Type.s)
|
|
||||||
Declare IsIPStringValid(Adress.s)
|
Declare IsIPStringValid(Adress.s)
|
||||||
|
|
||||||
EndDeclareModule
|
EndDeclareModule
|
|
@ -24,8 +24,8 @@ lhs_web::set_config(lhs_web::#conf_port, "8099")
|
||||||
;lhs_web::set_config(lhs_web::#conf_binding, "127.0.0.1")
|
;lhs_web::set_config(lhs_web::#conf_binding, "127.0.0.1")
|
||||||
lhs_web::set_config(lhs_web::#conf_binding, "0.0.0.0")
|
lhs_web::set_config(lhs_web::#conf_binding, "0.0.0.0")
|
||||||
|
|
||||||
lhs_web::set_config(lhs_web::#conf_defaultfile, "index.html")
|
lhs_web::set_config(lhs_web::#conf_defaultfile, "/index.html")
|
||||||
lhs_web::set_config(lhs_web::#conf_basedir, "/srv/www/htdocs/")
|
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_error400, "integrated")
|
||||||
lhs_web::set_config(lhs_web::#conf_max_clients, "100")
|
lhs_web::set_config(lhs_web::#conf_max_clients, "100")
|
||||||
lhs_web::set_config(lhs_web::#conf_cache_enable, "0")
|
lhs_web::set_config(lhs_web::#conf_cache_enable, "0")
|
||||||
|
@ -33,7 +33,56 @@ lhs_web::set_config(lhs_web::#conf_cache_enable, "0")
|
||||||
;* includes
|
;* includes
|
||||||
;*
|
;*
|
||||||
|
|
||||||
|
Procedure.s Sample_Header(Map Header.s())
|
||||||
|
Define *Text
|
||||||
|
Define.s Encoded, ZumSenden, TBD
|
||||||
|
NewMap Response.s()
|
||||||
|
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 = UTF8("<!DOCTYPE html><html><header><title>Alle Client Headers</title></header><body>"+TBD+"</body></html>")
|
||||||
|
Encoded = Base64Encoder(*Text, MemorySize(*Text))
|
||||||
|
Debug "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::MapStringToJSONString(Response())
|
||||||
|
Debug "ZumSenden: " + ZumSenden
|
||||||
|
ProcedureReturn ZumSenden
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
Procedure.s Formular_Test(Map Header.s(), ContentData.s)
|
||||||
|
Define *Text
|
||||||
|
Define.s Encoded, ZumSenden, TBD
|
||||||
|
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
|
||||||
|
Debug "TBD:"+TBD
|
||||||
|
Debug "contentData:"+ContentData
|
||||||
|
*Text = UTF8("<!DOCTYPE html><html><header><title>Alle Client Headers</title></header><body>"+TBD+"<hr/><br/><h1>ConentJSON</h1><br/>"+ContentData+"</body></html>")
|
||||||
|
Debug "Unencoded:"+PeekS(*Text, -1 , #PB_UTF8)
|
||||||
|
Encoded = Base64Encoder(*Text, MemorySize(*Text))
|
||||||
|
Debug "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::MapStringToJSONString(Response())
|
||||||
|
Debug "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)
|
||||||
|
|
||||||
;*
|
;*
|
||||||
;* Initialisierung Netzwerk
|
;* Initialisierung Netzwerk
|
||||||
|
@ -49,7 +98,7 @@ Else
|
||||||
EndIf
|
EndIf
|
||||||
|
|
||||||
If lhs_web::start_server()
|
If lhs_web::start_server()
|
||||||
Debug "Server gestartet"
|
Debug "Server gestartet" + lhs_web::get_config(lhs_web::#conf_port)
|
||||||
Else
|
Else
|
||||||
Debug "Fehlgeschlagen"
|
Debug "Fehlgeschlagen"
|
||||||
End
|
End
|
||||||
|
@ -57,6 +106,7 @@ EndIf
|
||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
OpenConsole("Test")
|
OpenConsole("Test")
|
||||||
|
PrintN("Webserver an Port:"+lhs_web::get_config(lhs_web::#conf_port))
|
||||||
PrintN("Press Enter to Exit")
|
PrintN("Press Enter to Exit")
|
||||||
Input()
|
Input()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue