Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ if (WEBUI_BUILD_EXAMPLES)
add_executable(call_cpp_from_js ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/call_cpp_from_js/main.cpp)
add_executable(serve_a_folder_cpp ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/serve_a_folder/main.cpp)
add_executable(virtual_file_system_cpp ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/virtual_file_system/main.cpp)
add_executable(test_index_redirect_cpp ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/test_index_redirect/main.cpp)

# C examples
add_executable(minimal_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/minimal/main.c)
add_executable(call_js_from_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/call_js_from_c/main.c)
add_executable(call_c_from_js ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/call_c_from_js/main.c)
add_executable(serve_a_folder_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/serve_a_folder/main.c)
add_executable(virtual_file_system_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/virtual_file_system/main.c)
add_executable(test_index_redirect_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/test_index_redirect/main.c)
add_executable(public_network_access ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/public_network_access/main.c)
add_executable(web_app_multi_client ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/web_app_multi_client/main.c)
add_executable(chatgpt_api ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/chatgpt_api/main.c)
Expand All @@ -146,12 +148,14 @@ if (WEBUI_BUILD_EXAMPLES)
target_link_libraries(call_cpp_from_js webui)
target_link_libraries(serve_a_folder_cpp webui)
target_link_libraries(virtual_file_system_cpp webui)
target_link_libraries(test_index_redirect_cpp webui)

target_link_libraries(minimal_c webui)
target_link_libraries(call_js_from_c webui)
target_link_libraries(call_c_from_js webui)
target_link_libraries(serve_a_folder_c webui)
target_link_libraries(virtual_file_system_c webui)
target_link_libraries(test_index_redirect_c webui)
target_link_libraries(public_network_access webui)
target_link_libraries(web_app_multi_client webui)
target_link_libraries(chatgpt_api webui)
Expand All @@ -166,11 +170,13 @@ if (WEBUI_BUILD_EXAMPLES)
set_target_properties(call_cpp_from_js PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(serve_a_folder_cpp PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(virtual_file_system_cpp PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(test_index_redirect_cpp PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(minimal_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(call_js_from_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(call_c_from_js PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(serve_a_folder_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(virtual_file_system_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(test_index_redirect_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(public_network_access PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(web_app_multi_client PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
set_target_properties(chatgpt_api PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
Expand Down
1 change: 1 addition & 0 deletions examples/C++/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The only requirement to build the examples is a a C++11 compiler.
- `call_js_from_cpp`: Calls JavaScript from C++ using class methods and member-function bind.
- `serve_a_folder`: Uses WebUI to serve a folder with multiple files (class-based example using member-function bind).
- `virtual_file_system`: Embeds files using a virtual file system.
- `test_index_redirect`: Tests index fallback and custom entry behavior for `/`, `/sub`, and `/sub/foo`.

To build an example, cd into its directory and run the make command.

Expand Down
138 changes: 138 additions & 0 deletions examples/C++/test_index_redirect/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# WebUI C++ Example

# == 1. VARIABLES =============================================================

MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
TARGET := $(firstword $(MAKECMDGOALS))
LIB_DIR := $(PROJECT_DIR)/dist
ifeq ($(TARGET), debug)
LIB_DIR := $(LIB_DIR)/debug
endif
INCLUDE_DIR := $(PROJECT_DIR)/include
WEBUI_LIB_NAME = webui-2
ifeq ($(WEBUI_USE_TLS), 1)
WEBUI_LIB_NAME = webui-2-secure
endif

# ARGS
# Set a compiler when running on Linux via `make CC=g++` / `make CC=clang`
CC = g++
# Build the WebUI library if running via `make BUILD_LIB=true`
BUILD_LIB ?=

# BUILD FLAGS
STATIC_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
DYN_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"

# Platform conditions
ifeq ($(OS),Windows_NT)
# Windows
PLATFORM := windows
SHELL := CMD
STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
STATIC_OUT := main.exe
DYN_OUT := main-dyn.exe
LWS2_OPT := -lws2_32 -lole32
STRIP_OPT := --strip-all
CONSOLE_APP := -Wl,-subsystem=console
GUI_APP := -Wl,-subsystem=windows
else
STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
STATIC_OUT := main
DYN_OUT := main-dyn
ifeq ($(shell uname),Darwin)
# MacOS
PLATFORM := macos
CC = clang
COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
else
# Linux
PLATFORM := linux
COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
STRIP_OPT := --strip-all
ifeq ($(CC),clang)
LLVM_OPT := llvm-
endif
endif
endif

# == 2.TARGETS ================================================================

all: release

debug: --validate-args
ifeq ($(BUILD_LIB),true)
@cd "$(PROJECT_DIR)" && $(MAKE) debug
endif
# Static with Debug info
ifneq ($(WEBUI_USE_TLS), 1)
@echo "Build C++ Example ($(CC) debug static)..."
@$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
endif
# Dynamic with Debug info
@echo "Build C++ Example ($(CC) debug dynamic)..."
$(COPY_LIB_CMD)
@$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
# Clean
ifeq ($(PLATFORM),windows)
@- del *.o >nul 2>&1
else
@- rm -f *.o
@- rm -rf *.dSYM # macOS
endif
@echo "Done."

release: --validate-args
ifeq ($(BUILD_LIB),true)
@cd "$(PROJECT_DIR)" && $(MAKE)
endif
# Static Release
ifneq ($(WEBUI_USE_TLS), 1)
@echo "Build C++ Example ($(CC) release static)..."
@$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
@$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
endif
# Dynamic Release
@echo "Build C++ Example ($(CC) release dynamic)..."
$(COPY_LIB_CMD)
@$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
@$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
# Clean
ifeq ($(PLATFORM),windows)
@- del *.o >nul 2>&1
else
@- rm -f *.o
@- rm -rf *.dSYM # macOS
endif
@echo "Done."

clean: --clean-$(PLATFORM)

# INTERNAL TARGETS

--validate-args:
ifneq ($(filter $(CC),g++ clang aarch64-linux-gnu-g++ arm-linux-gnueabihf-g++ musl-g++),$(CC))
$(error Invalid compiler specified: `$(CC)`)
endif

--clean-linux: --clean-unix

--clean-macos: --clean-unix

--clean-unix:
- rm -f *.o
- rm -f *.a
- rm -f *.so
- rm -f *.dylib
- rm -rf *.dSYM

--clean-windows:
- del *.o >nul 2>&1
- del *.dll >nul 2>&1
- del *.a >nul 2>&1
- del *.exe >nul 2>&1
65 changes: 65 additions & 0 deletions examples/C++/test_index_redirect/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# WebUI C++ Example
# Windows - Microsoft Visual C++

SHELL = CMD
LIB_DIR = ../../../dist
INCLUDE_DIR = ../../../include
WEBUI_LIB_NAME = webui-2
!IF "$(WEBUI_USE_TLS)" == "1"
WEBUI_LIB_NAME = webui-2-secure
!ENDIF

# Build the WebUI library if running `nmake BUILD_LIB=true`
BUILD_LIB =

all: release

debug:
!IF "$(BUILD_LIB)" == "true"
@cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
!ENDIF
# Static with Debug info
!IF "$(WEBUI_USE_TLS)" != "1"
@echo Build C++ Example (Debug Static)...
@cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
!ENDIF
# Dynamic with Debug info
@echo Build C++ Example (Debug Dynamic)...
@copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
@cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
# Clean
@- del *.exp >nul 2>&1
@- del *.ilk >nul 2>&1
@- del *.lib >nul 2>&1
@- del *.obj >nul 2>&1
@- del *.pdb >nul 2>&1
@echo Done.

release:
!IF "$(BUILD_LIB)" == "true"
@cd "$(LIB_DIR)" && cd .. && $(MAKE)
!ENDIF
# Static Release
!IF "$(WEBUI_USE_TLS)" != "1"
@echo Build C++ Example (Release Static)...
@cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
!ENDIF
# Dynamic Release
@echo Build C++ Example (Release Dynamic)...
@copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
@cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
# Clean
@- del *.exp >nul 2>&1
@- del *.ilk >nul 2>&1
@- del *.lib >nul 2>&1
@- del *.obj >nul 2>&1
@- del *.pdb >nul 2>&1
@echo Done.

clean:
- del *.obj >nul 2>&1
- del *.ilk >nul 2>&1
- del *.pdb >nul 2>&1
- del *.exp >nul 2>&1
- del *.exe >nul 2>&1
- del *.lib >nul 2>&1
87 changes: 87 additions & 0 deletions examples/C++/test_index_redirect/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "webui.hpp"
#include "vfs.h"

// This example is used to verify redirect and fallback behavior for:
// /, /sub, /sub/foo
// in both storage modes:
// 1) set_root_folder(...)
// 2) set_file_handler(vfs)
//
// Server mode is the primary redirect test path because it exposes the raw
// HTTP behavior (302 Location targets) without mixing in window lifecycle.
//
// The expected server behavior is:
// - start_server("custom.html") prefers custom.html in every directory
// - an explicit filename is strict; if it does not exist, the request fails
// - start_server() or start_server("") means "fallback mode", which probes
// index.html, index.htm, index.ts, then index.js
//
// Note: index.ts and index.js can still be valid fallback targets for
// runtime/script-first scenarios, but they are not equivalent to an HTML GUI
// entry page. For normal GUI testing, HTML/HTM are the page-like entries.
int main(int argc, char *argv[])
{
bool serverMode = false;
bool vfsEnabled = false;
for (int i = 1; i < argc; ++i)
{
if (std::string(argv[i]) == "--server")
{
serverMode = true;
}
else if (std::string(argv[i]) == "--vfs")
{
vfsEnabled = true;
}
}

webui::window window_;
webui::set_config(use_cookies, false);

if (vfsEnabled)
{
window_.set_file_handler(vfs);
}
else
{
window_.set_root_folder("/home/gordon/Dokumenty/PlatformIO/Projects/webui/examples/C++/test_index_redirect/ui/");

// Absolute paths:
// window_.set_root_folder("/path/to/ui/");
// window_.set_root_folder("/path/to/ui");

// Relative if ui folder is next to executable:
// window_.set_root_folder("ui/");
// window_.set_root_folder("ui");
}

if (serverMode)
{
window_.set_port(8080);

// Explicit custom entry file:
window_.start_server("custom.html");

// Redirect to the hardcoded index.* fallback list:
// window_.start_server();

}
else
{
// Explicit custom entry file:
window_.show("custom.html");
// window_.show_browser("custom.html"); // AnyBrowser is the default second argument in C++.

// Redirect to the hardcoded index.* fallback list:
// window_.show();
// window_.show_browser();
}

webui::wait();

return 0;
}

#if defined(_MSC_VER)
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(__argc, __argv); }
#endif
29 changes: 29 additions & 0 deletions examples/C++/test_index_redirect/ui/custom.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ui/custom.html</title>
</head>
<body>
<h1>ui/custom.html</h1>
<p>IDENTIFIER: ui/custom.html</p>
<p>Directory routes: <a href="/">/</a> | <a href="/sub">/sub</a> | <a href="/sub/foo">/sub/foo</a></p>
<h2>All test files</h2>
<ul>
<li><a href="/custom.html">/custom.html</a></li>
<li><a href="/index.html">/index.html</a></li>
<li><a href="/index.css">/index.css</a></li>
<li><a href="/index.js">/index.js</a></li>
<li><a href="/sub/custom.html">/sub/custom.html</a></li>
<li><a href="/sub/index.html">/sub/index.html</a></li>
<li><a href="/sub/index.css">/sub/index.css</a></li>
<li><a href="/sub/index.js">/sub/index.js</a></li>
<li><a href="/sub/foo/custom.html">/sub/foo/custom.html</a></li>
<li><a href="/sub/foo/index.html">/sub/foo/index.html</a></li>
<li><a href="/sub/foo/index.css">/sub/foo/index.css</a></li>
<li><a href="/sub/foo/index.js">/sub/foo/index.js</a></li>
</ul>
<script src="/webui.js"></script>
</body>
</html>
4 changes: 4 additions & 0 deletions examples/C++/test_index_redirect/ui/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* IDENTIFIER: ui/index.css */
/* Directory routes: / | /sub | /sub/foo */
/* All files: /custom.html /index.html /index.css /index.js /sub/custom.html /sub/index.html /sub/index.css /sub/index.js /sub/foo/custom.html /sub/foo/index.html /sub/foo/index.css /sub/foo/index.js */
body { font-family: monospace; }
Loading
Loading