312 lines
9.2 KiB
Go
312 lines
9.2 KiB
Go
package localserver
|
|
|
|
// import (
|
|
// "bufio"
|
|
// "encoding/json"
|
|
// "fmt"
|
|
// "io"
|
|
// "log"
|
|
// "os"
|
|
// "path/filepath"
|
|
// "sync/atomic"
|
|
|
|
// "github.com/pion/webrtc/v3"
|
|
// )
|
|
|
|
// const (
|
|
// UPLOAD_INIT = "upload_init"
|
|
// UPLOAD = "upload"
|
|
// UPLOAD_DONE = "upload_done"
|
|
// DOWNLOAD_INIT = "download_init"
|
|
// DOWNLOAD = "download"
|
|
// DOWNLOAD_DONE = "download_done"
|
|
// HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE_INIT = "hosted_squad_download_file_response_init"
|
|
// HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE = "hosted_squad_download_file_response"
|
|
// HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE_END = "hosted_squad_download_file_response_end"
|
|
// )
|
|
|
|
// const (
|
|
// bufferedAmountLowThreshold uint64 = 512 * 1024
|
|
// //maxBufferedAmount uint64 = 1024 * 1024
|
|
// )
|
|
|
|
// type WebrtcCallFileManager struct {
|
|
// files map[string]*os.File
|
|
// l *uint32
|
|
// }
|
|
|
|
// func NewWebrtcCallFileManager() *WebrtcCallFileManager {
|
|
// l := uint32(0)
|
|
// return &WebrtcCallFileManager{
|
|
// files: make(map[string]*os.File),
|
|
// l: &l,
|
|
// }
|
|
// }
|
|
|
|
// func (w *WebrtcCallFileManager) HandleCallEvent(from string, squadId string, eventId string, payload map[string]interface{}, data []byte, manager *WebRTCCallManager) (err error) {
|
|
// done, errCh := make(chan struct{}), make(chan error)
|
|
// go func() {
|
|
// // logger.Println("got an event in call file manager", from, eventId, payload)
|
|
// switch eventId {
|
|
// case UPLOAD_INIT:
|
|
// if _, ok := payload["filename"]; !ok {
|
|
// errCh <- fmt.Errorf("no field filename in payload")
|
|
// return
|
|
// }
|
|
// if _, ok := payload["filename"].(string); !ok {
|
|
// errCh <- fmt.Errorf("field filename in payload is not a string")
|
|
// return
|
|
// }
|
|
// if err = w.initUpload(squadId, from, payload["filename"].(string)); err != nil {
|
|
// errCh <- err
|
|
// return
|
|
// }
|
|
// case UPLOAD:
|
|
// if _, ok := payload["filename"]; !ok {
|
|
// errCh <- fmt.Errorf("no field filename in payload")
|
|
// return
|
|
// }
|
|
// if _, ok := payload["filename"].(string); !ok {
|
|
// errCh <- fmt.Errorf("field filename in payload is not a string")
|
|
// return
|
|
// }
|
|
// if err = w.upload(squadId, from, payload["filename"].(string), data); err != nil {
|
|
// errCh <- err
|
|
// return
|
|
// }
|
|
// case UPLOAD_DONE:
|
|
// if _, ok := payload["filename"]; !ok {
|
|
// errCh <- fmt.Errorf("no field filename in payload")
|
|
// return
|
|
// }
|
|
// if _, ok := payload["filename"].(string); !ok {
|
|
// errCh <- fmt.Errorf("field filename in payload is not a string")
|
|
// return
|
|
// }
|
|
// if _, ok := payload["targets"]; !ok {
|
|
// errCh <- fmt.Errorf("no field targets in payload")
|
|
// return
|
|
// }
|
|
// if _, ok := payload["targets"].([]interface{}); !ok {
|
|
// errCh <- fmt.Errorf("field targets in payload is not a string")
|
|
// return
|
|
// }
|
|
// channels := []*DataChannel{}
|
|
// manager.DataChannelMapMux.RLock()
|
|
// for _, target := range payload["targets"].([]interface{}) {
|
|
// if _, ok := manager.DataChannels[target.(string)]; !ok {
|
|
// manager.DataChannelMapMux.RUnlock()
|
|
// errCh <- fmt.Errorf("no corresponding datachannel : %s", target.(string))
|
|
// return
|
|
// }
|
|
// channel := manager.DataChannels[target.(string)]
|
|
// for {
|
|
// if atomic.CompareAndSwapUint32(channel.l, 0, 1) {
|
|
// defer atomic.SwapUint32(channel.l, 0)
|
|
// break
|
|
// }
|
|
// }
|
|
// channels = append(channels, channel)
|
|
// }
|
|
// manager.DataChannelMapMux.RUnlock()
|
|
// if err = w.uploadDone(squadId, from, payload["filename"].(string), channels); err != nil {
|
|
// errCh <- err
|
|
// return
|
|
// }
|
|
// case DOWNLOAD:
|
|
// if _, ok := payload["filename"]; !ok {
|
|
// errCh <- fmt.Errorf("no field filename in payload")
|
|
// return
|
|
// }
|
|
// if _, ok := payload["filename"].(string); !ok {
|
|
// errCh <- fmt.Errorf("field filename in payload is not a string")
|
|
// return
|
|
// }
|
|
// if _, ok := payload["peerId"]; !ok {
|
|
// errCh <- fmt.Errorf("no field peerId in payload")
|
|
// return
|
|
// }
|
|
// if _, ok := payload["peerId"].(string); !ok {
|
|
// errCh <- fmt.Errorf("field peerId in payload is not a string")
|
|
// return
|
|
// }
|
|
// manager.DataChannelMapMux.RLock()
|
|
// if _, ok := manager.DataChannels[payload["peerId"].(string)]; !ok {
|
|
// manager.DataChannelMapMux.RUnlock()
|
|
// errCh <- fmt.Errorf("no corresponding datachannel")
|
|
// return
|
|
// }
|
|
// channel := manager.DataChannels[payload["peerId"].(string)]
|
|
// for {
|
|
// if atomic.CompareAndSwapUint32(channel.l, 0, 1) {
|
|
// // logger.Println("atomic lock unlocked")
|
|
// defer atomic.SwapUint32(channel.l, 0)
|
|
// break
|
|
// }
|
|
// }
|
|
// manager.DataChannelMapMux.RUnlock()
|
|
// if err = w.download(squadId, from, payload["filename"].(string), channel.DataChannel); err != nil {
|
|
// errCh <- err
|
|
// return
|
|
// }
|
|
// }
|
|
// done <- struct{}{}
|
|
// }()
|
|
// select {
|
|
// case <-done:
|
|
// return nil
|
|
// case err = <-errCh:
|
|
// return
|
|
// }
|
|
// }
|
|
|
|
// func (w *WebrtcCallFileManager) initUpload(squadId string, from string, fileName string) (err error) {
|
|
// for {
|
|
// if atomic.CompareAndSwapUint32(w.l, 0, 1) {
|
|
// defer atomic.SwapUint32(w.l, 0)
|
|
// if _, dirErr := os.Stat(filepath.Join(dataPath, dataPath, "data", "squads", squadId)); os.IsNotExist(dirErr) {
|
|
// if err = os.MkdirAll(filepath.Join(dataPath, dataPath, "data", "squads", squadId), 0700); err != nil {
|
|
// return
|
|
// }
|
|
// }
|
|
// f, fErr := os.Create(filepath.Join(dataPath, dataPath, "data", "squads", squadId, fileName))
|
|
// if err != nil {
|
|
// return fErr
|
|
// }
|
|
// f.Close()
|
|
// f, fErr = os.OpenFile(filepath.Join(dataPath, dataPath, "data", "squads", squadId, fileName), os.O_APPEND|os.O_WRONLY, 0644)
|
|
// if err != nil {
|
|
// return fErr
|
|
// }
|
|
// w.files[fileName] = f
|
|
// break
|
|
// } else {
|
|
// continue
|
|
// }
|
|
// }
|
|
// return
|
|
// }
|
|
|
|
// func (w *WebrtcCallFileManager) upload(squadId string, from string, fileName string, data []byte) (err error) {
|
|
// for {
|
|
// if atomic.CompareAndSwapUint32(w.l, 0, 1) {
|
|
// defer atomic.SwapUint32(w.l, 0)
|
|
// if _, ok := w.files[fileName]; !ok {
|
|
// err = fmt.Errorf("no open file with name %s", fileName)
|
|
// return
|
|
// }
|
|
// _, err = w.files[fileName].Write(data)
|
|
// break
|
|
// } else {
|
|
// continue
|
|
// }
|
|
// }
|
|
// return
|
|
// }
|
|
|
|
// func (w *WebrtcCallFileManager) uploadDone(squadId string, from string, fileName string, channels []*DataChannel) (err error) {
|
|
// for {
|
|
// if atomic.CompareAndSwapUint32(w.l, 0, 1) {
|
|
// defer atomic.SwapUint32(w.l, 0)
|
|
// if _, ok := w.files[fileName]; !ok {
|
|
// err = fmt.Errorf("no open file with name %s", fileName)
|
|
// return
|
|
// }
|
|
// err = w.files[fileName].Close()
|
|
// delete(w.files, fileName)
|
|
// bsInit, jsonErr := json.Marshal(map[string]interface{}{
|
|
// "type": UPLOAD_DONE,
|
|
// "from": "server",
|
|
// "payload": map[string]string{
|
|
// "path": fileName,
|
|
// },
|
|
// })
|
|
// if jsonErr != nil {
|
|
// return jsonErr
|
|
// }
|
|
// for _, channel := range channels {
|
|
// if err = channel.DataChannel.SendText(string(bsInit)); err != nil {
|
|
// return
|
|
// }
|
|
// }
|
|
// break
|
|
// } else {
|
|
// continue
|
|
// }
|
|
// }
|
|
// return
|
|
// }
|
|
|
|
// func (w *WebrtcCallFileManager) download(squadId string, dst string, fileName string, channel *webrtc.DataChannel) (err error) {
|
|
// // logger.Println("got called")
|
|
// if _, dirErr := os.Stat(filepath.Join(dataPath, dataPath, "data", "squads", squadId, fileName)); os.IsNotExist(dirErr) {
|
|
// // logger.Println("file does not exist :", filepath.Join(dataPath, "data", "squads", squadId, fileName))
|
|
// return
|
|
// }
|
|
// f, err := os.Open(filepath.Join(dataPath, dataPath, "data", "squads", squadId, fileName))
|
|
// if err != nil {
|
|
// return
|
|
// }
|
|
// defer f.Close()
|
|
// bsInit, err := json.Marshal(map[string]interface{}{
|
|
// "type": HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE_INIT,
|
|
// "from": "server",
|
|
// "payload": map[string]string{
|
|
// "path": fileName,
|
|
// },
|
|
// })
|
|
// if err != nil {
|
|
// return
|
|
// }
|
|
// if err = channel.SendText(string(bsInit)); err != nil {
|
|
// return
|
|
// }
|
|
// r := bufio.NewReader(f)
|
|
// buf := make([]byte, 0, 30000)
|
|
// // logger.Println("start reading")
|
|
// for {
|
|
// n, readErr := r.Read(buf[:cap(buf)])
|
|
// buf = buf[:n]
|
|
// if n == 0 {
|
|
// if err == nil {
|
|
// // logger.Println("n is 0 weird")
|
|
// break
|
|
// }
|
|
// if err == io.EOF {
|
|
// break
|
|
// }
|
|
// log.Fatal(readErr)
|
|
// }
|
|
// bs, jsonErr := json.Marshal(map[string]interface{}{
|
|
// "type": HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE,
|
|
// "from": "server",
|
|
// "payload": map[string]interface{}{
|
|
// "path": fileName,
|
|
// "content": buf,
|
|
// },
|
|
// })
|
|
// if jsonErr != nil {
|
|
// return jsonErr
|
|
// }
|
|
// if err = channel.SendText(string(bs)); err != nil {
|
|
// return
|
|
// }
|
|
// }
|
|
// // logger.Println("stop reading")
|
|
// bs, err := json.Marshal(map[string]interface{}{
|
|
// "type": HOSTED_SQUAD_DOWNLOAD_FILE_RESPONSE_END,
|
|
// "from": "server",
|
|
// "payload": map[string]string{
|
|
// "path": fileName,
|
|
// },
|
|
// })
|
|
// if err != nil {
|
|
// return
|
|
// }
|
|
// if err = channel.SendText(string(bs)); err != nil {
|
|
// return
|
|
// }
|
|
// // logger.Println("done")
|
|
// return
|
|
// }
|