Create a library for serving static files

It serves files that are in a given directory, and this could be
extended to html files.

In order to validate the functionality we also added a simple
`ScoutingServer` that you can `Start()` and `Stop()`.  The unit test
makes use of this. The `main` binary that ties all the components
together also makes use of this.

See the README for an overview of everything we added in this patch.

Change-Id: Id496b032d6aa70fd8502eeb347895ac52b5d1ddd
Signed-off-by: Het Satasiya <satasiyahet@gmail.com>
Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
diff --git a/scouting/webserver/static/BUILD b/scouting/webserver/static/BUILD
new file mode 100644
index 0000000..008d719
--- /dev/null
+++ b/scouting/webserver/static/BUILD
@@ -0,0 +1,21 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+    name = "static",
+    srcs = ["static.go"],
+    importpath = "github.com/frc971/971-Robot-Code/scouting/webserver/static",
+    target_compatible_with = ["@platforms//cpu:x86_64"],
+    visibility = ["//visibility:public"],
+    deps = ["//scouting/webserver/server"],
+)
+
+go_test(
+    name = "static_test",
+    srcs = ["static_test.go"],
+    data = [
+        "test_pages/page.txt",
+        "test_pages/root.txt",
+    ],
+    embed = [":static"],
+    deps = ["//scouting/webserver/server"],
+)
diff --git a/scouting/webserver/static/static.go b/scouting/webserver/static/static.go
new file mode 100644
index 0000000..e921b0b
--- /dev/null
+++ b/scouting/webserver/static/static.go
@@ -0,0 +1,14 @@
+package static
+
+// A year agnostic way to serve static http files.
+import (
+	"net/http"
+
+	"github.com/frc971/971-Robot-Code/scouting/webserver/server"
+)
+
+// Serve pages given a port, directory to serve from, and an channel to pass the errors back to the caller.
+func ServePages(scoutingServer server.ScoutingServer, directory string) {
+	// Serve the / endpoint given a folder of pages.
+	scoutingServer.Handle("/", http.FileServer(http.Dir(directory)))
+}
diff --git a/scouting/webserver/static/static_test.go b/scouting/webserver/static/static_test.go
new file mode 100644
index 0000000..15bd872
--- /dev/null
+++ b/scouting/webserver/static/static_test.go
@@ -0,0 +1,57 @@
+package static
+
+import (
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"testing"
+
+	"github.com/frc971/971-Robot-Code/scouting/webserver/server"
+)
+
+func TestServing(t *testing.T) {
+	cases := []struct {
+		// The path to request from the server.
+		path string
+		// The data that the server is expected to return at the
+		// specified path.
+		expectedData string
+	}{
+		{"/root.txt", "Hello, this is the root page!"},
+		{"/page.txt", "Hello from a page!"},
+	}
+
+	scoutingServer := server.NewScoutingServer()
+	ServePages(scoutingServer, "test_pages")
+	scoutingServer.Start(8080)
+
+	// Go through all the test cases, and run them against the running webserver.
+	for _, c := range cases {
+		dataReceived := getData(c.path, t)
+		if dataReceived != c.expectedData {
+			t.Errorf("Got %q, but expected %q", dataReceived, c.expectedData)
+		}
+	}
+
+	scoutingServer.Stop()
+}
+
+// Retrieves the data at the specified path. If an error occurs, the test case
+// is terminated and failed.
+func getData(path string, t *testing.T) string {
+	resp, err := http.Get(fmt.Sprintf("http://localhost:8080/%s", path))
+	if err != nil {
+		t.Fatalf("Failed to get data ", err)
+	}
+	// Error out if the return status is anything other than 200 OK.
+	if resp.Status != "200 OK" {
+		t.Fatalf("Received a status code other than 200")
+	}
+	// Read the response body.
+	body, err := ioutil.ReadAll(resp.Body)
+	if err != nil {
+		t.Fatalf("Failed to read body")
+	}
+	// Decode the body and return it.
+	return string(body)
+}
diff --git a/scouting/webserver/static/test_pages/page.txt b/scouting/webserver/static/test_pages/page.txt
new file mode 100644
index 0000000..3bb47e8
--- /dev/null
+++ b/scouting/webserver/static/test_pages/page.txt
@@ -0,0 +1 @@
+Hello from a page!
\ No newline at end of file
diff --git a/scouting/webserver/static/test_pages/root.txt b/scouting/webserver/static/test_pages/root.txt
new file mode 100644
index 0000000..8f75b7d
--- /dev/null
+++ b/scouting/webserver/static/test_pages/root.txt
@@ -0,0 +1 @@
+Hello, this is the root page!
\ No newline at end of file