aboutsummaryrefslogtreecommitdiff
path: root/main.go
blob: 41d69c86d5cbda938c0e87ed2445e4d961552b85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package main

import (
	"os"
	"net/http"
	"log"
	"github.com/gotk3/gotk3/glib"
	"github.com/gotk3/gotk3/gtk"
	"context"
	"sync"
	"fmt"
)

func serve(port, dir string, wg *sync.WaitGroup) *http.Server {
	mux := http.NewServeMux()
	mux.Handle("/", http.FileServer(http.Dir(dir)))
    server := &http.Server{Addr: ":" + port, Handler: mux}

    go func() {
        defer wg.Done()

        if err := server.ListenAndServe(); err != http.ErrServerClosed {
			// TODO: show error in GTK error window
            log.Fatalf("ListenAndServe(): %v", err)
        }
    }()

    return server
}


func main() {
	app, _ := gtk.ApplicationNew("net.mikunonaka.fileserver", glib.APPLICATION_FLAGS_NONE)
	app.Connect("activate", func() { onActivate(app) })
	app.Run(os.Args)
}

func onActivate(app *gtk.Application) {
	win, _ := gtk.ApplicationWindowNew(app)
	win.SetTitle("HTTP File Server")
	win.SetDefaultSize(400, 400)

	box, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)

	dirBox, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0)
	dirLabel, _ := gtk.LabelNew("Directory to serve: ")
	dirBox.PackStart(dirLabel, false, false, 5)
	dirInput, _ := gtk.EntryNew()
	dirBox.PackEnd(dirInput, false, false, 5)
	box.PackStart(dirBox, false, false, 5)

	portBox, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0)
	portLabel, _ := gtk.LabelNew("Port:")
	portBox.PackStart(portLabel, false, false, 5)
	portInput, _ := gtk.EntryNew()
	portBox.PackEnd(portInput, false, false, 5)
	box.PackStart(portBox, false, false, 5)

	buttonBox, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0)
	buttonSwitch, _ := gtk.ButtonNew()
	buttonSwitch.SetLabel("Start")
	buttonBox.PackStart(buttonSwitch, true, true, 0)
	box.PackStart(buttonBox, false, false, 5)

	statusLabel, _ := gtk.LabelNew("")
	box.PackStart(statusLabel, false, true, 10)

	var on = false
	var server *http.Server
	buttonSwitch.Connect("clicked", func() {
		// TODO: validate dir and port
		port, _ := portInput.GetText()
		dir, _ := dirInput.GetText()

		if on {
			server.Shutdown(context.TODO())
		} else {
			go func() {
				killServerDone := &sync.WaitGroup{}
				server = serve(port, dir, killServerDone)
				killServerDone.Add(1)
				// do this after server starts
				on = true
				buttonSwitch.SetLabel("Stop")
				statusLabel.SetText(fmt.Sprintf("Serving directory '%s' on PORT %s", dir, port))

				killServerDone.Wait()
				// do this after server shuts down
				on = false
				buttonSwitch.SetLabel("Start")
				statusLabel.SetText("")
			}()
		}
	})

	win.Add(box)
	win.ShowAll()
}