mirror of
https://github.com/go-gitea/gitea.git
synced 2025-05-17 13:00:28 +02:00
189 lines
4.8 KiB
Go
189 lines
4.8 KiB
Go
// Copyright 2022 The Gitea Authors. All rights reserved.
|
|
// Use of this source code is governed by a MIT-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package bots
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
bots_model "code.gitea.io/gitea/models/bots"
|
|
"code.gitea.io/gitea/modules/log"
|
|
"code.gitea.io/gitea/modules/web"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
func Routes() *web.Route {
|
|
r := web.NewRoute()
|
|
r.Get("/", Serve)
|
|
return r
|
|
}
|
|
|
|
var upgrader = websocket.Upgrader{
|
|
ReadBufferSize: 4096,
|
|
WriteBufferSize: 4096,
|
|
EnableCompression: true,
|
|
CheckOrigin: func(r *http.Request) bool {
|
|
return true
|
|
},
|
|
}
|
|
|
|
var pongWait = 60 * time.Second
|
|
|
|
type Message struct {
|
|
Version int //
|
|
Type int // message type, 1 register 2 error 3 task 4 no task
|
|
RunnerUUID string // runner uuid
|
|
ErrCode int // error code
|
|
ErrContent string // errors message
|
|
EventName string
|
|
EventPayload string
|
|
}
|
|
|
|
func Serve(w http.ResponseWriter, r *http.Request) {
|
|
log.Trace("websocket init request begin from %s", r.RemoteAddr)
|
|
c, err := upgrader.Upgrade(w, r, nil)
|
|
if err != nil {
|
|
log.Error("websocket upgrade failed: %v", err)
|
|
return
|
|
}
|
|
defer c.Close()
|
|
log.Trace("websocket upgrade from %s successfully", r.RemoteAddr)
|
|
|
|
c.SetReadDeadline(time.Now().Add(pongWait))
|
|
c.SetPongHandler(func(string) error { c.SetReadDeadline(time.Now().Add(pongWait)); return nil })
|
|
|
|
MESSAGE_BUMP:
|
|
for {
|
|
// read log from client
|
|
mt, message, err := c.ReadMessage()
|
|
if err != nil {
|
|
if websocket.IsCloseError(err, websocket.CloseAbnormalClosure) ||
|
|
websocket.IsCloseError(err, websocket.CloseNormalClosure) {
|
|
c.Close()
|
|
break
|
|
}
|
|
if !strings.Contains(err.Error(), "i/o timeout") {
|
|
log.Error("websocket[%s] read failed: %#v", r.RemoteAddr, err)
|
|
}
|
|
break
|
|
} else {
|
|
log.Trace("websocket[%s] received message: %s", r.RemoteAddr, message)
|
|
}
|
|
|
|
// read message first
|
|
var msg Message
|
|
if err = json.Unmarshal(message, &msg); err != nil {
|
|
log.Error("websocket[%s] unmarshal failed: %#v", r.RemoteAddr, err)
|
|
break
|
|
}
|
|
|
|
switch msg.Version {
|
|
case 1:
|
|
switch msg.Type {
|
|
case 1:
|
|
log.Info("websocket[%s] registered", r.RemoteAddr)
|
|
runner, err := bots_model.GetRunnerByUUID(msg.RunnerUUID)
|
|
if err != nil {
|
|
if !errors.Is(err, bots_model.ErrRunnerNotExist{}) {
|
|
log.Error("websocket[%s] get runner [%s] failed: %v", r.RemoteAddr, msg.RunnerUUID, err)
|
|
break
|
|
}
|
|
err = c.WriteMessage(mt, message)
|
|
if err != nil {
|
|
log.Error("websocket[%s] sent message failed: %v", r.RemoteAddr, err)
|
|
break
|
|
}
|
|
} else {
|
|
fmt.Printf("-----%v\n", runner)
|
|
// TODO: handle read message
|
|
err = c.WriteMessage(mt, message)
|
|
if err != nil {
|
|
log.Error("websocket[%s] sent message failed: %v", r.RemoteAddr, err)
|
|
break
|
|
}
|
|
}
|
|
default:
|
|
returnMsg := Message{
|
|
Version: 1,
|
|
Type: 2,
|
|
ErrCode: 1,
|
|
ErrContent: fmt.Sprintf("message type %d is not supported", msg.Type),
|
|
}
|
|
bs, err := json.Marshal(&returnMsg)
|
|
if err != nil {
|
|
log.Error("websocket[%s] marshal message failed: %v", r.RemoteAddr, err)
|
|
break MESSAGE_BUMP
|
|
}
|
|
err = c.WriteMessage(mt, bs)
|
|
if err != nil {
|
|
log.Error("websocket[%s] sent message failed: %v", r.RemoteAddr, err)
|
|
}
|
|
break MESSAGE_BUMP
|
|
}
|
|
default:
|
|
returnMsg := Message{
|
|
Version: 1,
|
|
Type: 2,
|
|
ErrCode: 1,
|
|
ErrContent: "version is not supported",
|
|
}
|
|
bs, err := json.Marshal(&returnMsg)
|
|
if err != nil {
|
|
log.Error("websocket[%s] marshal message failed: %v", r.RemoteAddr, err)
|
|
break MESSAGE_BUMP
|
|
}
|
|
err = c.WriteMessage(mt, bs)
|
|
if err != nil {
|
|
log.Error("websocket[%s] sent message failed: %v", r.RemoteAddr, err)
|
|
}
|
|
break MESSAGE_BUMP
|
|
}
|
|
|
|
// TODO: find new task and send to client
|
|
task, err := bots_model.GetCurBuildByUUID(msg.RunnerUUID)
|
|
if err != nil {
|
|
log.Error("websocket[%s] get task failed: %v", r.RemoteAddr, err)
|
|
break
|
|
}
|
|
if task == nil {
|
|
returnMsg := Message{
|
|
Version: 1,
|
|
Type: 4,
|
|
}
|
|
bs, err := json.Marshal(&returnMsg)
|
|
if err != nil {
|
|
log.Error("websocket[%s] marshal message failed: %v", r.RemoteAddr, err)
|
|
break MESSAGE_BUMP
|
|
}
|
|
err = c.WriteMessage(mt, bs)
|
|
if err != nil {
|
|
log.Error("websocket[%s] sent message failed: %v", r.RemoteAddr, err)
|
|
}
|
|
} else {
|
|
returnMsg := Message{
|
|
Version: 1,
|
|
Type: 3,
|
|
EventName: task.Event.Event(),
|
|
EventPayload: task.EventPayload,
|
|
}
|
|
bs, err := json.Marshal(&returnMsg)
|
|
if err != nil {
|
|
log.Error("websocket[%s] marshal message failed: %v", r.RemoteAddr, err)
|
|
break
|
|
}
|
|
err = c.WriteMessage(mt, bs)
|
|
if err != nil {
|
|
log.Error("websocket[%s] sent message failed: %v", r.RemoteAddr, err)
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|