Commit 7fd31869 authored by Tom Niget's avatar Tom Niget

Finish webserver demo

parent 7b7f4d0d
......@@ -23,14 +23,14 @@
#endif
#define COMMA() ,
#define METHOD(ret, name, args, ...) \
#define METHOD(ret, name, args, ...) \
struct { \
ret operator() args __VA_ARGS__ type *self; \
ret operator() args __VA_ARGS__ type *self; \
} name{this};
#define FUNCTION(ret, name, args, ...) \
#define FUNCTION(ret, name, args, ...) \
struct { \
ret operator() args __VA_ARGS__ \
ret operator() args __VA_ARGS__ \
} name;
using namespace std::literals;
......@@ -130,6 +130,51 @@ public:
#include "builtins/set.hpp"
#include "builtins/str.hpp"
struct {
struct type {
METHOD(
typon::Task<PyStr>, read, (size_t size = -1), const {
if (size == -1) {
size = self->len;
}
PyStr buf(size, '\0');
int nbytes = co_await typon::io::read(self->fd, buf.data(), size);
if (nbytes < 0) {
system_error(-nbytes, "read()");
}
co_return std::move(buf);
})
METHOD(
typon::Task<void>, close, (),
const { co_await typon::io::close(self->fd); })
type(int fd = -1, size_t len = 0) : fd(fd), len(len) {}
type(const type &other)
: fd(other.fd), len(other.len), read(this), close(this) {}
int fd;
size_t len;
};
} file;
namespace typon {
using PyFile = decltype(file)::type;
}
typon::Task<typon::PyFile> open(const PyStr &path, std::string_view mode) {
const char *path_c = path.c_str();
struct statx statxbuf;
if (int err = co_await typon::io::statx(AT_FDCWD, path_c, 0, STATX_SIZE, &statxbuf)) {
system_error(-err, "statx()");
}
int fd = co_await typon::io::openat(AT_FDCWD, path_c, O_RDONLY, 0);
if (fd < 0) {
system_error(-fd, "openat()");
}
co_return typon::PyFile(fd, statxbuf.stx_size);
}
#include "../typon/generator.hpp"
#endif // TYPON_BUILTINS_HPP
......@@ -21,6 +21,7 @@ public:
PyStr(const char *s) : std::string(s) {}
PyStr(const std::string &s) : std::string(s) {}
PyStr(std::string &&s) : std::string(std::move(s)) {}
PyStr(size_t count, char ch) : std::string(count, ch) {}
template <class InputIterator>
PyStr(InputIterator first, InputIterator last) : std::string(first, last) {}
......@@ -31,7 +32,6 @@ public:
template <typename... T> PyStr format(T &&...args) const {
return PyStr(fmt::format(fmt::runtime(*this), std::forward<T>(args)...));
//return std::format(*this, std::forward<T>(args)...);
}
};
......
......@@ -24,6 +24,9 @@ struct socket_t {
struct type {
METHOD(typon::Task<std::tuple<type COMMA() std::string>>, accept, (), {
int connfd = co_await typon::io::accept(self->fd, NULL, NULL);
if (connfd < 0) {
system_error(-connfd, "accept()");
}
co_return std::make_tuple(type(connfd), std::string("")); // TODO
})
......@@ -62,7 +65,6 @@ struct socket_t {
})
METHOD(typon::Task<void>, send, (PyBytes data), {
std::cout << self->fd << std::endl;
if (int sbytes = co_await typon::io::send(self->fd, data, 0);
sbytes < 0) {
co_await self->close();
......@@ -70,12 +72,11 @@ struct socket_t {
}
})
type(int fd = -1) : fd(fd) { }
type(int fd = -1) : fd(fd) {}
type(const type &other)
: fd(other.fd), accept(this), close(this), listen(this),
setsockopt(this), bind(this), recv(this), send(this) {
}
setsockopt(this), bind(this), recv(this), send(this) {}
int fd;
};
......
......@@ -86,4 +86,10 @@ assert lambda x: [x].__add__
assert next(range(6), None)
\ No newline at end of file
assert next(range(6), None)
class file:
def read(self) -> Task[str]: ...
def close(self) -> Task[None]: ...
def open(filename: str, mode: str) -> Task[file]: ...
\ No newline at end of file
......@@ -21,10 +21,16 @@ def create_listening_socket(port):
sockfd.listen(BACKLOG)
return sockfd
def read_file(path):
fd = open(path, "r")
content = fd.read()
fd.close()
return content
def handle_connection(connfd: socket, filepath):
buf = connfd.recv(1024).decode("utf-8")
length = buf.find("\r\n\r\n")
content = "Hello world"
content = read_file(filepath)
response = response_fmt.format(len(content), content)
connfd.send(response.encode("utf-8"))
connfd.close()
......@@ -34,10 +40,9 @@ def server_loop(sockfd: socket, filepath):
connfd, _ = sockfd.accept()
fork(lambda: handle_connection(connfd, filepath))
break
def server_loops(sockfd, filepath):
for i in range(1):
for i in range(20):
fork(lambda: server_loop(sockfd, filepath))
if __name__ == "__main__":
......@@ -45,7 +50,7 @@ if __name__ == "__main__":
print("Usage: webserver [ filepath ]")
sys.exit(1)
filepath = sys.argv[1] if len(sys.argv) == 2 else "webserver.cpp"
filepath = sys.argv[1] if len(sys.argv) == 2 else "requirements.txt"
print("Serving", filepath, "on port", PORT)
sockfd = create_listening_socket(PORT)
......
......@@ -179,6 +179,8 @@ class TypeOperator(BaseType, ABC):
# c'est pété => utiliser le truc de la boucle en bas
# TODO: pas implémenté
if not (self.variadic or other.variadic):
raise IncompatibleTypesError(f"Cannot unify {self} and {other} with different number of arguments")
if len(self.args) == 0:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment