1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-26 13:48:53 +08:00
Mainflux.mainflux/ws/api/endpoints.go
Sammy Kerata Oina 9b4c2b24c8
UV-267 - Update WS service to mproxy (#1917)
* update WS service to mproxy

Signed-off-by: SammyOina <sammyoina@gmail.com>

* Fix brokerstracing initialization in main.go

The commit fixes the initialization of the brokerstracing package in the main.go file. The target server configuration is now correctly passed to the NewPubSub function, ensuring that the correct host and port are used for the PubSub service. This resolves an issue where the wrong server configuration was being used, leading to incorrect behavior.

Signed-off-by: SammyOina <sammyoina@gmail.com>

* Fix goroutine issue in main.go

The commit fixes a goroutine issue in the main.go file. Previously, the `hs.Start()` function was not being executed in a goroutine, which caused the program to block. This commit wraps the `hs.Start()` function call in a goroutine to ensure it runs concurrently. This resolves the issue and allows the program to continue execution without blocking.

Signed-off-by: SammyOina <sammyoina@gmail.com>

* update to current mproxy

Signed-off-by: SammyOina <sammyoina@gmail.com>

* update dependencies

Signed-off-by: SammyOina <sammyoina@gmail.com>

* Fix targetWSHost value in proxyWS function

The targetWSHost value in the proxyWS function was empty. This commit fixes the issue by setting the targetWSHost value to "localhost". Additionally, the target variable in the proxyWS function is updated to include the "ws://" protocol prefix.

Signed-off-by: SammyOina <sammyoina@gmail.com>

* update deps

Signed-off-by: SammyOina <sammyoina@gmail.com>

* remove authorize from unsubscribe

Signed-off-by: SammyOina <sammyoina@gmail.com>

---------

Signed-off-by: SammyOina <sammyoina@gmail.com>
2023-10-23 16:22:09 +02:00

126 lines
2.8 KiB
Go

// Copyright (c) Mainflux
// SPDX-License-Identifier: Apache-2.0
package api
import (
"context"
"fmt"
"net/http"
"net/url"
"regexp"
"strings"
"github.com/go-zoo/bone"
"github.com/mainflux/mainflux/pkg/errors"
"github.com/mainflux/mainflux/ws"
)
var channelPartRegExp = regexp.MustCompile(`^/channels/([\w\-]+)/messages(/[^?]*)?(\?.*)?$`)
func handshake(ctx context.Context, svc ws.Service) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
req, err := decodeRequest(r)
if err != nil {
encodeError(w, err)
return
}
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
logger.Warn(fmt.Sprintf("Failed to upgrade connection to websocket: %s", err.Error()))
return
}
req.conn = conn
client := ws.NewClient(conn)
if err := svc.Subscribe(ctx, req.thingKey, req.chanID, req.subtopic, client); err != nil {
req.conn.Close()
return
}
logger.Debug(fmt.Sprintf("Successfully upgraded communication to WS on channel %s", req.chanID))
}
}
func decodeRequest(r *http.Request) (connReq, error) {
authKey := r.Header.Get("Authorization")
if authKey == "" {
authKeys := bone.GetQuery(r, "authorization")
if len(authKeys) == 0 {
logger.Debug("Missing authorization key.")
return connReq{}, errUnauthorizedAccess
}
authKey = authKeys[0]
}
chanID := bone.GetValue(r, "chanID")
req := connReq{
thingKey: authKey,
chanID: chanID,
}
channelParts := channelPartRegExp.FindStringSubmatch(r.RequestURI)
if len(channelParts) < 2 {
logger.Warn("Empty channel id or malformed url")
return connReq{}, errors.ErrMalformedEntity
}
subtopic, err := parseSubTopic(channelParts[2])
if err != nil {
return connReq{}, err
}
req.subtopic = subtopic
return req, nil
}
func parseSubTopic(subtopic string) (string, error) {
if subtopic == "" {
return subtopic, nil
}
subtopic, err := url.QueryUnescape(subtopic)
if err != nil {
return "", errMalformedSubtopic
}
subtopic = strings.ReplaceAll(subtopic, "/", ".")
elems := strings.Split(subtopic, ".")
filteredElems := []string{}
for _, elem := range elems {
if elem == "" {
continue
}
if len(elem) > 1 && (strings.Contains(elem, "*") || strings.Contains(elem, ">")) {
return "", errMalformedSubtopic
}
filteredElems = append(filteredElems, elem)
}
subtopic = strings.Join(filteredElems, ".")
return subtopic, nil
}
func encodeError(w http.ResponseWriter, err error) {
var statusCode int
switch err {
case ws.ErrEmptyID, ws.ErrEmptyTopic:
statusCode = http.StatusBadRequest
case errUnauthorizedAccess:
statusCode = http.StatusForbidden
case errMalformedSubtopic, errors.ErrMalformedEntity:
statusCode = http.StatusBadRequest
default:
statusCode = http.StatusNotFound
}
logger.Warn(fmt.Sprintf("Failed to authorize: %s", err.Error()))
w.WriteHeader(statusCode)
}