mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-12-24 08:07:00 +08:00
274 lines
6.6 KiB
Go
274 lines
6.6 KiB
Go
// Copyright © 2023 OpenIM. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package msggateway
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
|
|
|
|
"github.com/openimsdk/protocol/constant"
|
|
"github.com/openimsdk/tools/utils/encrypt"
|
|
"github.com/openimsdk/tools/utils/timeutil"
|
|
)
|
|
|
|
type UserConnContextInfo struct {
|
|
Token string `json:"token"`
|
|
UserID string `json:"userID"`
|
|
PlatformID int `json:"platformID"`
|
|
OperationID string `json:"operationID"`
|
|
Compression string `json:"compression"`
|
|
SDKType string `json:"sdkType"`
|
|
SendResponse bool `json:"sendResponse"`
|
|
Background bool `json:"background"`
|
|
SDKVersion string `json:"sdkVersion"`
|
|
}
|
|
|
|
type UserConnContext struct {
|
|
RespWriter http.ResponseWriter
|
|
Req *http.Request
|
|
Path string
|
|
Method string
|
|
RemoteAddr string
|
|
ConnID string
|
|
info *UserConnContextInfo
|
|
}
|
|
|
|
func (c *UserConnContext) Deadline() (deadline time.Time, ok bool) {
|
|
return
|
|
}
|
|
|
|
func (c *UserConnContext) Done() <-chan struct{} {
|
|
return nil
|
|
}
|
|
|
|
func (c *UserConnContext) Err() error {
|
|
return nil
|
|
}
|
|
|
|
func (c *UserConnContext) Value(key any) any {
|
|
switch key {
|
|
case constant.OpUserID:
|
|
return c.GetUserID()
|
|
case constant.OperationID:
|
|
return c.GetOperationID()
|
|
case constant.ConnID:
|
|
return c.GetConnID()
|
|
case constant.OpUserPlatform:
|
|
return c.GetPlatformID()
|
|
case constant.RemoteAddr:
|
|
return c.RemoteAddr
|
|
case SDKVersion:
|
|
return c.info.SDKVersion
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func newContext(respWriter http.ResponseWriter, req *http.Request) *UserConnContext {
|
|
remoteAddr := req.RemoteAddr
|
|
if forwarded := req.Header.Get("X-Forwarded-For"); forwarded != "" {
|
|
remoteAddr += "_" + forwarded
|
|
}
|
|
return &UserConnContext{
|
|
RespWriter: respWriter,
|
|
Req: req,
|
|
Path: req.URL.Path,
|
|
Method: req.Method,
|
|
RemoteAddr: remoteAddr,
|
|
ConnID: encrypt.Md5(req.RemoteAddr + "_" + strconv.Itoa(int(timeutil.GetCurrentTimestampByMill()))),
|
|
}
|
|
}
|
|
|
|
func newTempContext() *UserConnContext {
|
|
return &UserConnContext{
|
|
Req: &http.Request{URL: &url.URL{}},
|
|
info: &UserConnContextInfo{},
|
|
}
|
|
}
|
|
|
|
func (c *UserConnContext) ParseEssentialArgs() error {
|
|
query := c.Req.URL.Query()
|
|
if data := query.Get("v"); data != "" {
|
|
return c.parseByJson(data)
|
|
} else {
|
|
return c.parseByQuery(query, c.Req.Header)
|
|
}
|
|
}
|
|
|
|
func (c *UserConnContext) parseByQuery(query url.Values, header http.Header) error {
|
|
info := UserConnContextInfo{
|
|
Token: query.Get(Token),
|
|
UserID: query.Get(WsUserID),
|
|
OperationID: query.Get(OperationID),
|
|
Compression: query.Get(Compression),
|
|
SDKType: query.Get(SDKType),
|
|
SDKVersion: query.Get(SDKVersion),
|
|
}
|
|
platformID, err := strconv.Atoi(query.Get(PlatformID))
|
|
if err != nil {
|
|
return servererrs.ErrConnArgsErr.WrapMsg("platformID is not int")
|
|
}
|
|
info.PlatformID = platformID
|
|
if val := query.Get(SendResponse); val != "" {
|
|
ok, err := strconv.ParseBool(val)
|
|
if err != nil {
|
|
return servererrs.ErrConnArgsErr.WrapMsg("isMsgResp is not bool")
|
|
}
|
|
info.SendResponse = ok
|
|
}
|
|
if info.Compression == "" {
|
|
info.Compression = header.Get(Compression)
|
|
}
|
|
background, err := strconv.ParseBool(query.Get(BackgroundStatus))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
info.Background = background
|
|
return c.checkInfo(&info)
|
|
}
|
|
|
|
func (c *UserConnContext) parseByJson(data string) error {
|
|
reqInfo, err := base64.RawURLEncoding.DecodeString(data)
|
|
if err != nil {
|
|
return servererrs.ErrConnArgsErr.WrapMsg("data is not base64")
|
|
}
|
|
var info UserConnContextInfo
|
|
if err := json.Unmarshal(reqInfo, &info); err != nil {
|
|
return servererrs.ErrConnArgsErr.WrapMsg("data is not json", "info", err.Error())
|
|
}
|
|
return c.checkInfo(&info)
|
|
}
|
|
|
|
func (c *UserConnContext) checkInfo(info *UserConnContextInfo) error {
|
|
if info.OperationID == "" {
|
|
return servererrs.ErrConnArgsErr.WrapMsg("operationID is empty")
|
|
}
|
|
if info.Token == "" {
|
|
return servererrs.ErrConnArgsErr.WrapMsg("token is empty")
|
|
}
|
|
if info.UserID == "" {
|
|
return servererrs.ErrConnArgsErr.WrapMsg("sendID is empty")
|
|
}
|
|
if _, ok := constant.PlatformID2Name[info.PlatformID]; !ok {
|
|
return servererrs.ErrConnArgsErr.WrapMsg("platformID is invalid")
|
|
}
|
|
switch info.SDKType {
|
|
case "":
|
|
info.SDKType = GoSDK
|
|
case GoSDK, JsSDK:
|
|
default:
|
|
return servererrs.ErrConnArgsErr.WrapMsg("sdkType is invalid")
|
|
}
|
|
c.info = info
|
|
return nil
|
|
}
|
|
|
|
func (c *UserConnContext) GetRemoteAddr() string {
|
|
return c.RemoteAddr
|
|
}
|
|
|
|
func (c *UserConnContext) SetHeader(key, value string) {
|
|
c.RespWriter.Header().Set(key, value)
|
|
}
|
|
|
|
func (c *UserConnContext) ErrReturn(error string, code int) {
|
|
http.Error(c.RespWriter, error, code)
|
|
}
|
|
|
|
func (c *UserConnContext) GetConnID() string {
|
|
return c.ConnID
|
|
}
|
|
|
|
func (c *UserConnContext) GetUserID() string {
|
|
if c == nil || c.info == nil {
|
|
return ""
|
|
}
|
|
return c.info.UserID
|
|
}
|
|
|
|
func (c *UserConnContext) GetPlatformID() int {
|
|
if c == nil || c.info == nil {
|
|
return 0
|
|
}
|
|
return c.info.PlatformID
|
|
}
|
|
|
|
func (c *UserConnContext) GetOperationID() string {
|
|
if c == nil || c.info == nil {
|
|
return ""
|
|
}
|
|
return c.info.OperationID
|
|
}
|
|
|
|
func (c *UserConnContext) SetOperationID(operationID string) {
|
|
if c.info == nil {
|
|
c.info = &UserConnContextInfo{}
|
|
}
|
|
c.info.OperationID = operationID
|
|
}
|
|
|
|
func (c *UserConnContext) GetToken() string {
|
|
if c == nil || c.info == nil {
|
|
return ""
|
|
}
|
|
return c.info.Token
|
|
}
|
|
|
|
func (c *UserConnContext) GetCompression() bool {
|
|
return c != nil && c.info != nil && c.info.Compression == GzipCompressionProtocol
|
|
}
|
|
|
|
func (c *UserConnContext) GetSDKType() string {
|
|
if c == nil || c.info == nil {
|
|
return GoSDK
|
|
}
|
|
switch c.info.SDKType {
|
|
case "", GoSDK:
|
|
return GoSDK
|
|
case JsSDK:
|
|
return JsSDK
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func (c *UserConnContext) GetSDKVersion() string {
|
|
if c == nil || c.info == nil {
|
|
return ""
|
|
}
|
|
return c.info.SDKVersion
|
|
}
|
|
|
|
func (c *UserConnContext) ShouldSendResp() bool {
|
|
return c != nil && c.info != nil && c.info.SendResponse
|
|
}
|
|
|
|
func (c *UserConnContext) SetToken(token string) {
|
|
if c.info == nil {
|
|
c.info = &UserConnContextInfo{}
|
|
}
|
|
c.info.Token = token
|
|
}
|
|
|
|
func (c *UserConnContext) GetBackground() bool {
|
|
return c != nil && c.info != nil && c.info.Background
|
|
}
|