Commit d3d93dac authored by Tom Niget's avatar Tom Niget

Finish webserver demo

parent 667466a4
...@@ -23,14 +23,14 @@ ...@@ -23,14 +23,14 @@
#endif #endif
#define COMMA() , #define COMMA() ,
#define METHOD(ret, name, args, ...) \ #define METHOD(ret, name, args, ...) \
struct { \ struct { \
ret operator() args __VA_ARGS__ type *self; \ ret operator() args __VA_ARGS__ type *self; \
} name{this}; } name{this};
#define FUNCTION(ret, name, args, ...) \ #define FUNCTION(ret, name, args, ...) \
struct { \ struct { \
ret operator() args __VA_ARGS__ \ ret operator() args __VA_ARGS__ \
} name; } name;
using namespace std::literals; using namespace std::literals;
...@@ -130,6 +130,51 @@ public: ...@@ -130,6 +130,51 @@ public:
#include "builtins/set.hpp" #include "builtins/set.hpp"
#include "builtins/str.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" #include "../typon/generator.hpp"
#endif // TYPON_BUILTINS_HPP #endif // TYPON_BUILTINS_HPP
...@@ -21,6 +21,7 @@ public: ...@@ -21,6 +21,7 @@ public:
PyStr(const char *s) : std::string(s) {} PyStr(const char *s) : std::string(s) {}
PyStr(const std::string &s) : std::string(s) {} PyStr(const std::string &s) : std::string(s) {}
PyStr(std::string &&s) : std::string(std::move(s)) {} PyStr(std::string &&s) : std::string(std::move(s)) {}
PyStr(size_t count, char ch) : std::string(count, ch) {}
template <class InputIterator> template <class InputIterator>
PyStr(InputIterator first, InputIterator last) : std::string(first, last) {} PyStr(InputIterator first, InputIterator last) : std::string(first, last) {}
...@@ -31,7 +32,6 @@ public: ...@@ -31,7 +32,6 @@ public:
template <typename... T> PyStr format(T &&...args) const { template <typename... T> PyStr format(T &&...args) const {
return PyStr(fmt::format(fmt::runtime(*this), std::forward<T>(args)...)); 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 { ...@@ -24,6 +24,9 @@ struct socket_t {
struct type { struct type {
METHOD(typon::Task<std::tuple<type COMMA() std::string>>, accept, (), { METHOD(typon::Task<std::tuple<type COMMA() std::string>>, accept, (), {
int connfd = co_await typon::io::accept(self->fd, NULL, NULL); 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 co_return std::make_tuple(type(connfd), std::string("")); // TODO
}) })
...@@ -62,7 +65,6 @@ struct socket_t { ...@@ -62,7 +65,6 @@ struct socket_t {
}) })
METHOD(typon::Task<void>, send, (PyBytes data), { 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); if (int sbytes = co_await typon::io::send(self->fd, data, 0);
sbytes < 0) { sbytes < 0) {
co_await self->close(); co_await self->close();
...@@ -70,12 +72,11 @@ struct socket_t { ...@@ -70,12 +72,11 @@ struct socket_t {
} }
}) })
type(int fd = -1) : fd(fd) { } type(int fd = -1) : fd(fd) {}
type(const type &other) type(const type &other)
: fd(other.fd), accept(this), close(this), listen(this), : 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; int fd;
}; };
......
Bclang-format==15.0.7 Bclang-format==15.0.7
......
...@@ -86,4 +86,10 @@ assert lambda x: [x].__add__ ...@@ -86,4 +86,10 @@ assert lambda x: [x].__add__
assert next(range(6), None) assert next(range(6), None)
\ No newline at end of file
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): ...@@ -21,10 +21,16 @@ def create_listening_socket(port):
sockfd.listen(BACKLOG) sockfd.listen(BACKLOG)
return sockfd return sockfd
def read_file(path):
fd = open(path, "r")
content = fd.read()
fd.close()
return content
def handle_connection(connfd: socket, filepath): def handle_connection(connfd: socket, filepath):
buf = connfd.recv(1024).decode("utf-8") buf = connfd.recv(1024).decode("utf-8")
length = buf.find("\r\n\r\n") length = buf.find("\r\n\r\n")
content = "Hello world" content = read_file(filepath)
response = response_fmt.format(len(content), content) response = response_fmt.format(len(content), content)
connfd.send(response.encode("utf-8")) connfd.send(response.encode("utf-8"))
connfd.close() connfd.close()
...@@ -34,10 +40,9 @@ def server_loop(sockfd: socket, filepath): ...@@ -34,10 +40,9 @@ def server_loop(sockfd: socket, filepath):
connfd, _ = sockfd.accept() connfd, _ = sockfd.accept()
fork(lambda: handle_connection(connfd, filepath)) fork(lambda: handle_connection(connfd, filepath))
break
def server_loops(sockfd, filepath): def server_loops(sockfd, filepath):
for i in range(1): for i in range(20):
fork(lambda: server_loop(sockfd, filepath)) fork(lambda: server_loop(sockfd, filepath))
if __name__ == "__main__": if __name__ == "__main__":
...@@ -45,7 +50,7 @@ if __name__ == "__main__": ...@@ -45,7 +50,7 @@ if __name__ == "__main__":
print("Usage: webserver [ filepath ]") print("Usage: webserver [ filepath ]")
sys.exit(1) 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) print("Serving", filepath, "on port", PORT)
sockfd = create_listening_socket(PORT) sockfd = create_listening_socket(PORT)
......
...@@ -179,6 +179,8 @@ class TypeOperator(BaseType, ABC): ...@@ -179,6 +179,8 @@ class TypeOperator(BaseType, ABC):
# c'est pété => utiliser le truc de la boucle en bas # c'est pété => utiliser le truc de la boucle en bas
# TODO: pas implémenté
if not (self.variadic or other.variadic): if not (self.variadic or other.variadic):
raise IncompatibleTypesError(f"Cannot unify {self} and {other} with different number of arguments") raise IncompatibleTypesError(f"Cannot unify {self} and {other} with different number of arguments")
if len(self.args) == 0: 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