diff --git a/examples/net/webserver-httphi/main.go b/examples/net/webserver-httphi/main.go new file mode 100644 index 000000000..57b955d34 --- /dev/null +++ b/examples/net/webserver-httphi/main.go @@ -0,0 +1,210 @@ +// This example is the webserver example using the heapless httphi router +// from github.com/soypat/lneto instead of "net/http". +// +// $ curl http://10.0.0.2 + +//go:build ninafw || wioterminal + +package main + +import ( + "log" + "machine" + "net" + "strconv" + "time" + + "github.com/soypat/lneto/http/httphi" + "github.com/soypat/lneto/http/httpraw" + + "tinygo.org/x/drivers/netlink" + "tinygo.org/x/drivers/netlink/probe" +) + +var ( + ssid string + pass string + port string = ":80" +) + +const ( + numWorkers = 2 + memoryPerConn = 1024 +) + +var led = machine.LED + +func main() { + + // wait a bit for serial + time.Sleep(2 * time.Second) + + led.Configure(machine.PinConfig{Mode: machine.PinOutput}) + + link, _ := probe.Probe() + + err := link.NetConnect(&netlink.ConnectParams{ + Ssid: ssid, + Passphrase: pass, + }) + if err != nil { + log.Fatal(err) + } + + var mux httphi.MuxSlice + mux.Handle("GET /{$}", root) + mux.Handle("GET /hello", hello) + mux.Handle("/cnt", cnt) + mux.Handle("GET /6", sixlines) + mux.Handle("GET /off", LED_OFF) + mux.Handle("GET /on", LED_ON) + + var router httphi.Router + cfg := httphi.DefaultRouterConfig(numWorkers, memoryPerConn, mux.MaxPathValues()) + err = router.Configure(&mux, cfg) + if err != nil { + log.Fatal(err) + } + + listener, err := net.Listen("tcp", port) + if err != nil { + log.Fatal(err) + } + + for { + conn, err := listener.Accept() + if err != nil { + println("accept:", err.Error()) + time.Sleep(time.Second) + continue + } + if err := router.Handle(conn); err != nil { + conn.Close() + } + } +} + +func root(ex *httphi.Exchange) { + access := int64(1) + + var cookie httpraw.Cookie + var cookieBuf [128]byte + cookie.Reset(cookieBuf[:0], 4) + if ex.RequestParseCookie(&cookie, "Cookie") == nil { + if v := cookie.Get("access"); v != nil { + n, err := strconv.ParseInt(string(v), 10, 0) + if err != nil { + ex.RespondString(httphi.StatusBadRequest, "text/plain", "invalid cookie value") + return + } + access = n + 1 + } + } + + var setCookie [32]byte + ex.StageHeaderBytes("Set-Cookie", strconv.AppendInt(append(setCookie[:0], "access="...), access, 10)) + ex.StageHeader("Content-Type", "text/html; charset=UTF-8") + ex.StageHeader("Connection", "close") + + var num [20]byte + ex.WriteBodyString(rootHead) + ex.WriteBody(strconv.AppendInt(num[:0], access, 10)) + ex.WriteBodyString(rootTail) +} + +const rootHead = ` + +
++ access: ` + +const rootTail = ` +
+ + /hello
+
+
diff --git a/examples/net/webstatic-httphi/main.go b/examples/net/webstatic-httphi/main.go
new file mode 100644
index 000000000..cd45b32de
--- /dev/null
+++ b/examples/net/webstatic-httphi/main.go
@@ -0,0 +1,123 @@
+// This example is the webstatic example using the heapless httphi router
+// from github.com/soypat/lneto instead of "net/http".
+
+//go:build ninafw || wioterminal
+
+package main
+
+import (
+ "embed"
+ "log"
+ "net"
+ "path"
+ "time"
+
+ "github.com/soypat/lneto/http/httphi"
+
+ "tinygo.org/x/drivers/netlink"
+ "tinygo.org/x/drivers/netlink/probe"
+)
+
+var (
+ ssid string
+ pass string
+ port string = ":80"
+)
+
+const (
+ numWorkers = 2
+ memoryPerConn = 1024
+)
+
+//go:embed index.html main.go images
+var fs embed.FS
+
+func main() {
+ // wait a bit for console
+ time.Sleep(2 * time.Second)
+
+ link, _ := probe.Probe()
+
+ err := link.NetConnect(&netlink.ConnectParams{
+ Ssid: ssid,
+ Passphrase: pass,
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ var mux httphi.MuxSlice
+ mux.Handle("GET /", serveFile)
+
+ var router httphi.Router
+ cfg := httphi.DefaultRouterConfig(numWorkers, memoryPerConn, mux.MaxPathValues())
+ err = router.Configure(&mux, cfg)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ listener, err := net.Listen("tcp", port)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for {
+ conn, err := listener.Accept()
+ if err != nil {
+ println("accept:", err.Error())
+ time.Sleep(time.Second)
+ continue
+ }
+ if err := router.Handle(conn); err != nil {
+ conn.Close()
+ }
+ }
+}
+
+func serveFile(ex *httphi.Exchange) {
+ name := string(ex.RequestPath()[1:])
+ if name == "" {
+ name = "index.html"
+ }
+
+ f, err := fs.Open(name)
+ if err != nil {
+ ex.RespondString(httphi.StatusNotFound, "text/plain", "404 page not found")
+ return
+ }
+ defer f.Close()
+
+ info, err := f.Stat()
+ if err != nil || info.IsDir() {
+ ex.RespondString(httphi.StatusNotFound, "text/plain", "404 page not found")
+ return
+ }
+
+ ex.StageHeader("Content-Type", contentType(name))
+ ex.StageHeaderInt("Content-Length", info.Size())
+ ex.StageHeader("Connection", "close")
+
+ var buf [512]byte
+ for {
+ n, err := f.Read(buf[:])
+ if n > 0 {
+ if _, werr := ex.WriteBody(buf[:n]); werr != nil {
+ return
+ }
+ }
+ if err != nil {
+ return
+ }
+ }
+}
+
+func contentType(name string) string {
+ switch path.Ext(name) {
+ case ".html":
+ return "text/html; charset=utf-8"
+ case ".png":
+ return "image/png"
+ default:
+ return "text/plain; charset=utf-8"
+ }
+}
diff --git a/go.mod b/go.mod
index 432c77ae0..9ce9b8054 100644
--- a/go.mod
+++ b/go.mod
@@ -1,14 +1,13 @@
module tinygo.org/x/drivers
-go 1.22.1
-
-toolchain go1.23.1
+go 1.24
require (
github.com/eclipse/paho.mqtt.golang v1.2.0
github.com/frankban/quicktest v1.10.2
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/orsinium-labs/tinymath v1.1.0
+ github.com/soypat/lneto v0.4.0
github.com/soypat/natiu-mqtt v0.5.1
github.com/tinygo-org/pio v0.3.0
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d
diff --git a/go.sum b/go.sum
index 673d984d8..8a889e8e4 100644
--- a/go.sum
+++ b/go.sum
@@ -15,6 +15,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/orsinium-labs/tinymath v1.1.0 h1:KomdsyLHB7vE3f1nRAJF2dyf1m/gnM2HxfTeV1vS5UA=
github.com/orsinium-labs/tinymath v1.1.0/go.mod h1:WPXX6ei3KSXG7JfA03a+ekCYaY9SWN4I+JRl2p6ck+A=
+github.com/soypat/lneto v0.4.0 h1:oBTcMnhEIBERXmAfwK4uDpItRaF7RiT1K2pljFVxtQc=
+github.com/soypat/lneto v0.4.0/go.mod h1:Be5PjwoYukvHFiUXxpYi8+ppH2F/gw/vjGBvFdv+Ti8=
github.com/soypat/natiu-mqtt v0.5.1 h1:rwaDmlvjzD2+3MCOjMZc4QEkDkNwDzbct2TJbpz+TPc=
github.com/soypat/natiu-mqtt v0.5.1/go.mod h1:xEta+cwop9izVCW7xOx2W+ct9PRMqr0gNVkvBPnQTc4=
github.com/tinygo-org/pio v0.3.0 h1:opEnOtw58KGB4RJD3/n/Rd0/djYGX3DeJiXLI6y/yDI=
diff --git a/smoketest.go b/smoketest.go
index 174526986..6219308ec 100644
--- a/smoketest.go
+++ b/smoketest.go
@@ -97,6 +97,7 @@ func runSmokeTest(filename string) error {
_ = flagSet.String("size", "", "")
_ = flagSet.String("o", "", "")
_ = flagSet.String("stack-size", "", "")
+ _ = flagSet.String("tags", "", "")
targetFlag := flagSet.String("target", "", "")
err = flagSet.Parse(fields[2:])
if err != nil {
diff --git a/smoketest.sh b/smoketest.sh
index b9f2c4995..8fdb530c8 100755
--- a/smoketest.sh
+++ b/smoketest.sh
@@ -176,11 +176,14 @@ tinygo build -size short -o ./build/test.hex -target=arduino-nano33 -stack-size
tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/websocket/dial/
tinygo build -size short -o ./build/test.hex -target=metro-m4-airlift -stack-size 8kb ./examples/net/socket/
tinygo build -size short -o ./build/test.hex -target=matrixportal-m4 -stack-size 8kb ./examples/net/webstatic/
+tinygo build -size short -o ./build/test.hex -tags=noslog -target=matrixportal-m4 -stack-size 8kb ./examples/net/webstatic-httphi/
+tinygo build -size short -o ./build/test.hex -tags=noslog -target=arduino-nano33 -stack-size 4kb ./examples/net/webserver-httphi/
tinygo build -size short -o ./build/test.hex -target=arduino-mkrwifi1010 -stack-size 8kb ./examples/net/tlsclient/
tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/mqttclient/natiu/
# network examples (rtl8720dn)
tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webclient/
tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webserver/
+tinygo build -size short -o ./build/test.hex -tags=noslog -target=wioterminal -stack-size 8kb ./examples/net/webserver-httphi/
tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/mqttclient/paho/
# network examples (comboat)
tinygo build -size short -o ./build/test.hex -target=elecrow-rp2040 -stack-size 8kb ./examples/net/tlsclient/