Skip to content

Commit

Permalink
added code and data for the 2024-11-27 Milano presentation
Browse files Browse the repository at this point in the history
  • Loading branch information
dietmarkuehl committed Nov 28, 2024
1 parent 5e10a31 commit 12faf5b
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ set(EXAMPLES
client
task
cppcon-2024
milano
)

foreach(EXAMPLE ${EXAMPLES})
Expand Down
10 changes: 10 additions & 0 deletions examples/data/index-milano.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<html>
<head>
<title>Ciao Milano!</title>
</head>
<body>
<img src="/logo.png"/>
<h1>Ciao Milano!</h1>
<img src="/itcpp.png"/>
</body>
</html>
Binary file added examples/data/itcpp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
97 changes: 97 additions & 0 deletions examples/milano.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// examples/http-server.cpp -*-C++-*-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/net29/net.hpp>
#include <beman/execution26/execution.hpp>
#include "demo_algorithm.hpp"
#include "demo_error.hpp"
#include "demo_scope.hpp"
#include "demo_task.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <string_view>
#include <unordered_map>

namespace ex = beman::execution26;
namespace net = beman::net29;
using namespace std::chrono_literals;

// ----------------------------------------------------------------------------

std::unordered_map<std::string, std::string> files{
{"/", "examples/data/index-milano.html"},
{"/favicon.ico", "examples/data/favicon.ico"},
{"/logo.png", "examples/data/logo.png"},
{"/itcpp.png", "examples/data/itcpp.png"},
};

auto timeout(auto scheduler, auto dur, ex::sender auto sender) {
return demo::when_any(
net::resume_after(scheduler, dur)
| demo::into_error([]{ return std::error_code(); }),
std::move(sender)
);
}

using on_exit = std::unique_ptr<char const, decltype([](auto msg){ std::cout << msg << "\n"; })>;
demo::task<> run_client(auto client, auto s) {
on_exit exit("client exiting");
char buffer[8194];
std::ostringstream out;
try {
while (true) {
auto n = co_await timeout(s, 1s, net::async_receive(client, net::buffer(buffer)));
if (n == 0u)
co_return;
// std::cout << "received=" << std::string_view(buffer, n) << "\n";
std::istringstream in(std::string(buffer, n));
std::string method, url, version;
if (!(in >> method >> url >> version))
co_return;
auto it = files.find(url);
std::cout << "url=" << url << " found=" << (it == files.end()? "no": "yes") << "\n";
std::string content;
if (it != files.end()) {
std::ifstream fin(it->second);
out.str({});
out << fin.rdbuf();
content = out.str();
}
out.str(std::string());
out << "HTTP/1.1 200 found\r\n"
<< "Content-Length: " << content.size() << "\r\n"
<< "\r\n"
<< content;

content = out.str();
co_await net::async_send(client, net::buffer(content));
//break;
}
} catch (std::exception const& ex) {
std::cout << "received timeout! ex=" << ex.what() << "\n";
} catch (...) {
std::cout << "received timeout!\n";
}
}

auto main() -> int
{
demo::scope scope;
net::io_context context;

scope.spawn([](auto& context, auto& scope)->demo::task<> {
net::ip::tcp::endpoint ep(net::ip::address_v4::any(), 12345);
net::ip::tcp::acceptor acceptor(context, ep);
while (true) {
auto[client, address] = co_await net::async_accept(acceptor);
std::cout << "received a connection from " << address << "\n";
scope.spawn(run_client(std::move(client), context.get_scheduler()));
}
}(context, scope));

context.run();


}

0 comments on commit 12faf5b

Please sign in to comment.