blob: 503405f208b34fdb245c1dfe57a355e3e1af048c [file] [log] [blame]
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include <cstdio>
#include "fmt/format.h"
#include "wpi/EventLoopRunner.h"
#include "wpi/HttpServerConnection.h"
#include "wpi/UrlParser.h"
#include "wpi/uv/Loop.h"
#include "wpi/uv/Tcp.h"
namespace uv = wpi::uv;
class MyHttpServerConnection : public wpi::HttpServerConnection {
public:
explicit MyHttpServerConnection(std::shared_ptr<uv::Stream> stream)
: HttpServerConnection(stream) {}
protected:
void ProcessRequest() override;
};
void MyHttpServerConnection::ProcessRequest() {
fmt::print(stderr, "HTTP request: '{}'\n", m_request.GetUrl());
wpi::UrlParser url{m_request.GetUrl(),
m_request.GetMethod() == wpi::HTTP_CONNECT};
if (!url.IsValid()) {
// failed to parse URL
SendError(400);
return;
}
std::string_view path;
if (url.HasPath()) {
path = url.GetPath();
}
fmt::print(stderr, "path: \"{}\"\n", path);
std::string_view query;
if (url.HasQuery()) {
query = url.GetQuery();
}
fmt::print(stderr, "query: \"{}\"\n", query);
const bool isGET = m_request.GetMethod() == wpi::HTTP_GET;
if (isGET && path == "/") {
// build HTML root page
SendResponse(200, "OK", "text/html",
"<html><head><title>WebServer Example</title></head>"
"<body><p>This is an example root page from the webserver."
"</body></html>");
} else {
SendError(404, "Resource not found");
}
}
int main() {
// Kick off the event loop on a separate thread
wpi::EventLoopRunner loop;
loop.ExecAsync([](uv::Loop& loop) {
auto tcp = uv::Tcp::Create(loop);
// bind to listen address and port
tcp->Bind("", 8080);
// when we get a connection, accept it and start reading
tcp->connection.connect([srv = tcp.get()] {
auto tcp = srv->Accept();
if (!tcp) {
return;
}
std::fputs("Got a connection\n", stderr);
auto conn = std::make_shared<MyHttpServerConnection>(tcp);
tcp->SetData(conn);
});
// start listening for incoming connections
tcp->Listen();
std::fputs("Listening on port 8080\n", stderr);
});
// wait for a keypress to terminate
std::getchar();
}