Skip to content
This repository was archived by the owner on Aug 27, 2024. It is now read-only.

Commit a0b428d

Browse files
committed
Added webinterface option for C++ chat client, small Rust config changes
1 parent f86adc3 commit a0b428d

File tree

12 files changed

+233
-23
lines changed

12 files changed

+233
-23
lines changed

demos/chat-client/c++/Enarx.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
args = [
2+
"--webinterface"
3+
]
4+
5+
[[files]]
6+
kind = "stdin"
7+
8+
[[files]]
9+
kind = "stdout"
10+
11+
[[files]]
12+
kind = "stderr"
13+
14+
[[files]]
15+
name = "server"
16+
kind = "connect"
17+
port = 50000
18+
prot = "tcp"
19+
host = "127.0.0.1"
20+
21+
[[files]]
22+
name = "web"
23+
kind = "listen"
24+
port = 8080
25+
prot = "tcp"
26+
host = "127.0.0.1"

demos/chat-client/c++/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Compile to WASM first, then run with --wasmcfgfile directed to Enarx.toml
2+
Use the --webinterface argument in the Enarx.toml to switch to a web interface, at localhost:8080

demos/chat-client/c++/assets.h

Lines changed: 2 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>Chat Client</title>
7+
<script src="/jquery.js"></script>
8+
<script>
9+
function sendMessage() {
10+
$.ajax({
11+
method: 'PUT',
12+
data: {
13+
message: document.getElementById("message").value,
14+
}
15+
});
16+
}
17+
</script>
18+
</head>
19+
20+
<body>
21+
<input type="text" id="message" maxlength="1000"/>
22+
<button onclick="sendMessage()">Send Message</button>
23+
</body>
24+
25+
</html>

demos/chat-client/c++/assets/jquery-3.6.0.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
# WASI_SDK_PATH defined in https://github.com/WebAssembly/wasi-sdk
4+
$WASI_SDK_PATH/bin/clang++ main.cpp --sysroot $WASI_SDK_PATH/share/wasi-sysroot -o main.wasm &&
5+
enarx run --wasmcfgfile Enarx.toml main.wasm

demos/chat-client/c++/main.cpp

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#include <iostream>
2+
#include <cstdlib>
3+
#include <unistd.h>
4+
#include <string>
5+
#include <cstring>
6+
#include <sys/types.h>
7+
#include <sys/select.h>
8+
#include <netinet/in.h>
9+
#include <sys/socket.h>
10+
#include "assets.h"
11+
12+
// C backend code based on https://github.com/rjzak/web_wordpuzzle
13+
14+
const unsigned char HTTP_OK[14] = "HTTP/1.0 200\n";
15+
const unsigned char HTTP_NOT_FOUND[14] = "HTTP/1.0 404\n";
16+
const unsigned char CONTENT_TYPE_HTML[26] = "Content-Type: text/html\n\n";
17+
const unsigned char CONTENT_TYPE_PLAIN[27] = "Content-Type: text/plain\n\n";
18+
const unsigned char CONTENT_TYPE_JAVASCRIPT[32] = "Content-Type: text/javascript\n\n";
19+
20+
const unsigned int PORT = 8080;
21+
22+
ssize_t write_all(const int fd, const unsigned char *buf, const size_t n);
23+
24+
// Pass --webinterface in Enarx.toml to use webinterface, uses std::in otherwise
25+
26+
int main(int argc, char *argv[])
27+
{
28+
if (argc > 2) {
29+
std::cout << "Too many arguments provided" << std::endl;
30+
return 1;
31+
}
32+
33+
bool isWebInterface = false;
34+
if (argc == 2) {
35+
if (strcmp("--webinterface", argv[1]) == 0) {
36+
isWebInterface = true;
37+
}
38+
}
39+
40+
int envVarCount = atoi(std::getenv("FD_COUNT"));
41+
if (envVarCount != 5)
42+
{
43+
std::cout << "expected exactly 5 pre-opened file descriptors" << std::endl;
44+
return 1;
45+
}
46+
47+
int serverFd, interfaceFd, newSocket;
48+
interfaceFd = envVarCount - 1;
49+
serverFd = envVarCount - 2;
50+
51+
if (isWebInterface) {
52+
std::cout << "Running in web interface mode..." << std::endl;
53+
54+
struct sockaddr_in addr;
55+
socklen_t addrlen = 0;
56+
57+
addr.sin_port = htons(PORT);
58+
addr.sin_family = AF_INET;
59+
addr.sin_addr.s_addr = INADDR_ANY;
60+
61+
char buffer[4096] = { 0 };
62+
63+
while (1) {
64+
if ((newSocket = accept(interfaceFd, (struct sockaddr*)&addr, (socklen_t*) &addrlen)) < 0) {
65+
std::cout << "Error accepting interface fd" << std::endl;
66+
break;
67+
}
68+
69+
ssize_t bytes_read = read(newSocket, buffer, 4096);
70+
if (bytes_read < 0) {
71+
std::cout << "Error reading into buffer" << std::endl;
72+
break;
73+
}
74+
75+
if (buffer[0] != 0x47 || buffer[1] != 0x45 || buffer[2] != 0x54) { // !GET
76+
if (buffer[0] == 0x50 && buffer[1] == 0x55 && buffer[2] == 0x54) { // PUT
77+
char* loc = strstr(buffer, "message=");
78+
loc += strlen("message=");
79+
if (write(serverFd, loc, strlen(loc)) < 0) {
80+
std::cout << "failed to write" << std::endl;
81+
}
82+
write(serverFd, "\n", 1);
83+
}
84+
}
85+
86+
if (buffer[4] == 0x2F && buffer[5] == 0x20) { // Forward slash and space
87+
write(newSocket, HTTP_OK, sizeof(HTTP_OK) - 1);
88+
write(newSocket, CONTENT_TYPE_HTML, sizeof(CONTENT_TYPE_HTML) - 1);
89+
write_all(newSocket, chat, sizeof(chat));
90+
}
91+
92+
if (buffer[4] == 0x2F && buffer[5] == 0x6A && buffer[6] == 0x71 && buffer[7] == 0x75) { // Forward slash and jqu
93+
write(newSocket, HTTP_OK, sizeof(HTTP_OK) - 1);
94+
write(newSocket, CONTENT_TYPE_JAVASCRIPT, sizeof(CONTENT_TYPE_JAVASCRIPT) - 1);
95+
write_all(newSocket, jquery, sizeof(jquery));
96+
}
97+
98+
memset(buffer, 0, 4096);
99+
close(newSocket);
100+
newSocket = 0;
101+
}
102+
103+
close(newSocket);
104+
} else {
105+
std::cout << "Running in stdin mode..." << std::endl;
106+
107+
std::string input;
108+
while (std::cin >> input)
109+
{
110+
input += "\n";
111+
if (write(serverFd, input.c_str(), strlen(input.c_str())) < 0) {
112+
std::cout << "Error writing input to server" << std::endl;
113+
}
114+
}
115+
}
116+
117+
close(interfaceFd);
118+
close(serverFd);
119+
return 0;
120+
}
121+
122+
ssize_t write_all(const int fd, const unsigned char *buf, const size_t n) {
123+
size_t total_written = 0;
124+
while(total_written < n) {
125+
size_t written = write(fd, buf+total_written, n-total_written);
126+
if (written < 0)
127+
return written;
128+
total_written += written;
129+
}
130+
return total_written;
131+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!env python3
2+
3+
# Python script from https://github.com/rjzak/web_wordpuzzle
4+
5+
ASSETS = ( ("jquery", open("assets/jquery-3.6.0.min.js", "rb").read()), ("chat", open("assets/chat.html", "rb").read()), )
6+
7+
output_file = open("assets.h", "w")
8+
9+
for asset in ASSETS:
10+
name = asset[0]
11+
data = asset[1]
12+
output_file.write("const unsigned char %s[%d]= {" % (name, len(data)));
13+
output_file.write(",".join(["0x%02X"%x for x in data]))
14+
output_file.write("};\n")
15+
16+
17+
output_file.close()

demos/chat-client/rust/Cargo.lock

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demos/chat-client/Enarx.toml renamed to demos/chat-client/rust/Enarx.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ name = "server"
1212
kind = "connect"
1313
port = 50000
1414
prot = "tcp"
15-
host = "127.0.0.1"
15+
host = "127.0.0.1"

0 commit comments

Comments
 (0)