Skip to content
This repository has been archived by the owner on May 24, 2023. It is now read-only.

Trying to use session middleware #152

Open
idc77 opened this issue Feb 15, 2023 · 1 comment
Open

Trying to use session middleware #152

idc77 opened this issue Feb 15, 2023 · 1 comment

Comments

@idc77
Copy link

idc77 commented Feb 15, 2023

I'm trying to use the session middleware with websocket

cmd using cobra

package cmd

import (
	"code.local/idc77/socktest/websocket/handler"
	"errors"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/session"
	"github.com/gofiber/websocket/v2"
	"github.com/spf13/cobra"
	"net"
	"os"
	"strings"
)

const (
	prefixTCP  = "tcp:"
	prefixUNIX = "unix:"
)

var websocketAddr = ""

// websocketCmd represents the websocket command
var websocketCmd = &cobra.Command{
	Use:   "websocket",
	Short: "A brief description of your command",
	RunE: func(cmd *cobra.Command, args []string) error {
		app := fiber.New()
		sconf := session.ConfigDefault
		store := session.New(sconf)
		app.Use("/ws", func(c *fiber.Ctx) error {
			sess, e := store.Get(c)
			if e != nil {
				return e
			}
			// IsWebSocketUpgrade returns true if the client
			// requested upgrade to the WebSocket protocol.
			if websocket.IsWebSocketUpgrade(c) {
				c.Locals("sess", sess)
				return c.Next()
			}
			return fiber.ErrUpgradeRequired
		})
		h := handler.NewHandler()
		ws := app.Group("/ws")
		ws.Get("/test", websocket.New(h.Gate))
		return fiberServe(app)
	},
}

func init() {
	rootCmd.AddCommand(websocketCmd)
	websocketCmd.Flags().StringVar(&websocketAddr, "addr", "tcp:127.0.0.1:3000", "tpc:addr:port or unix:/path/to/socket")
}

func fiberServe(r *fiber.App) error {
	if strings.HasPrefix(websocketAddr, prefixTCP) {
		addr := strings.TrimPrefix(websocketAddr, prefixTCP)
		return r.Listen(addr)
	} else if strings.HasPrefix(websocketAddr, prefixUNIX) {
		addr := strings.TrimPrefix(websocketAddr, prefixUNIX)
		if _, e := os.Stat(addr); errors.Is(e, os.ErrNotExist) {
			l, el := net.Listen("unix", addr)
			if el != nil {
				return el
			}
			return r.Listener(l)
		} else {
			if e := os.Remove(addr); e != nil {
				return e
			} else {
				l, el := net.Listen("unix", addr)
				if el != nil {
					return el
				}
				return r.Listener(l)
			}
		}
	} else {
		return nil
	}
}

websocket/handler/handler.go

package handler

import (
	"github.com/gofiber/fiber/v2/middleware/session"
	"github.com/gofiber/websocket/v2"
	jsoniter "github.com/json-iterator/go"
	"log"
)

const (
	CommandSet = "SET"
	CommandGet = "GET"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

type Handler struct {
}

func NewHandler() *Handler {
	h := new(Handler)
	return h
}

type Message struct {
	Command string `json:"command"`
	Key     string `json:"key,omitempty"`
	Value   string `json:"value,omitempty"`
}

type Response struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

func (h *Handler) Gate(c *websocket.Conn) {
	sess, ok := c.Locals("sess").(*session.Session)
	if !ok {
		log.Println("sesson not ok")
	}
	for {
		mt, msg, e := c.ReadMessage()
		if e != nil {
			log.Println("read:", e)
			break
		}
		m := new(Message)
		if e := json.Unmarshal(msg, m); e != nil {
			log.Println("marshall", e)
			break
		}
		switch m.Command {
		case CommandSet:
			sess.Set(m.Key, m.Value)
			if e := sess.Save(); e != nil {
				log.Println("session save:", e)
				break
			}
		case CommandGet:
			rsp := new(Response)
			rsp.Key = m.Key
			rsp.Value = sess.Get(m.Key).(string)
			rspb, e := json.Marshal(rsp)
			if e != nil {
				log.Println("unmarshall", e)
			}
			if e := c.WriteMessage(mt, rspb); e != nil {
				log.Println("write:", e)
				break
			}
		default:

		}
		log.Printf("recv: %d, %s", mt, msg)
	}
}

result


panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0xaef4c2]

goroutine 11 [running]:
github.com/gofiber/fiber/v2.(*Ctx).Response(...)
        /home/idc77/go/pkg/mod/github.com/gofiber/fiber/[email protected]/ctx.go:526
github.com/gofiber/fiber/v2/middleware/session.(*Session).setSession(0xc00027e500)
        /home/idc77/go/pkg/mod/github.com/gofiber/fiber/[email protected]/middleware/session/session.go:213 +0x662
github.com/gofiber/fiber/v2/middleware/session.(*Session).Save(0xc00027e500)
        /home/idc77/go/pkg/mod/github.com/gofiber/fiber/[email protected]/middleware/session/session.go:150 +0x6a
code.local/idc77/socktest/websocket/handler.(*Handler).Gate(0x400?, 0xc000318570)
        /home/idc77/go/src/code.local/idc77/socktest/websocket/handler/handler.go:55 +0x432
github.com/gofiber/websocket/v2.New.func2.4(0x0?)
        /home/idc77/go/pkg/mod/github.com/gofiber/websocket/[email protected]/websocket.go:121 +0x75
github.com/fasthttp/websocket.(*FastHTTPUpgrader).Upgrade.func1({0xddc298, 0xc000318660})
        /home/idc77/go/pkg/mod/github.com/fasthttp/[email protected]/server_fasthttp.go:201 +0x1ad
github.com/valyala/fasthttp.hijackConnHandler(0x0?, {0xdd2fc0?, 0xc000332000}, {0xddc3f8, 0xc0000156d8}, 0xc0001d1600, 0xc00027e5c0)
        /home/idc77/go/pkg/mod/github.com/valyala/[email protected]/server.go:2512 +0x68
created by github.com/valyala/fasthttp.(*Server).serveConn
        /home/idc77/go/pkg/mod/github.com/valyala/[email protected]/server.go:2467 +0x1c5c

Process finished with the exit code 2

On yeah payload, I forgot.

I used https://websocketking.com/
to connect to ws://127.0.0.1:3000/ws/test
with the payload

{
  "command": "SET",
  "key": "t1",
  "value": "100"
}
@idc77
Copy link
Author

idc77 commented Feb 15, 2023

Well it's clear that once the connection has been upgraded no cookie can be set.
So when I remove the session.Save() it doesn't segfault
And it's also safe for individual connections.
But don't I have to save a session?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant