Rename our allwpilib (which is now 2020) to not have 2019 in the name

Change-Id: I3c07f85ed32ab8b97db765a9b43f2a6ce7da964a
diff --git a/wpiutil/examples/webserver/webserver.cpp b/wpiutil/examples/webserver/webserver.cpp
new file mode 100644
index 0000000..e112d04
--- /dev/null
+++ b/wpiutil/examples/webserver/webserver.cpp
@@ -0,0 +1,86 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include <cstdio>
+
+#include "wpi/EventLoopRunner.h"
+#include "wpi/HttpServerConnection.h"
+#include "wpi/UrlParser.h"
+#include "wpi/raw_ostream.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() {
+  wpi::errs() << "HTTP request: '" << m_request.GetUrl() << "'\n";
+  wpi::UrlParser url{m_request.GetUrl(),
+                     m_request.GetMethod() == wpi::HTTP_CONNECT};
+  if (!url.IsValid()) {
+    // failed to parse URL
+    SendError(400);
+    return;
+  }
+
+  wpi::StringRef path;
+  if (url.HasPath()) path = url.GetPath();
+  wpi::errs() << "path: \"" << path << "\"\n";
+
+  wpi::StringRef query;
+  if (url.HasQuery()) query = url.GetQuery();
+  wpi::errs() << "query: \"" << query << "\"\n";
+
+  const bool isGET = m_request.GetMethod() == wpi::HTTP_GET;
+  if (isGET && path.equals("/")) {
+    // build HTML root page
+    wpi::SmallString<256> buf;
+    wpi::raw_svector_ostream os{buf};
+    os << "<html><head><title>WebServer Example</title></head>";
+    os << "<body><p>This is an example root page from the webserver.";
+    os << "</body></html>";
+    SendResponse(200, "OK", "text/html", os.str());
+  } 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;
+      wpi::errs() << "Got a connection\n";
+      auto conn = std::make_shared<MyHttpServerConnection>(tcp);
+      tcp->SetData(conn);
+    });
+
+    // start listening for incoming connections
+    tcp->Listen();
+
+    wpi::errs() << "Listening on port 8080\n";
+  });
+
+  // wait for a keypress to terminate
+  std::getchar();
+}