1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00
FrankerFaceZ/socketserver/internal/server/backend.go

173 lines
3.7 KiB
Go
Raw Normal View History

package server
import (
2015-10-25 12:40:07 -07:00
"golang.org/x/crypto/nacl/box"
"net/http"
"time"
"fmt"
"net/url"
"github.com/pmylund/go-cache"
"strconv"
"io/ioutil"
2015-10-25 03:21:50 -07:00
"encoding/json"
2015-10-25 12:40:07 -07:00
"sync"
2015-10-25 03:21:50 -07:00
"log"
2015-10-25 12:40:07 -07:00
"os"
"crypto/rand"
"encoding/base64"
"strings"
)
2015-10-25 03:21:50 -07:00
var backendHttpClient http.Client
var backendUrl string
var responseCache *cache.Cache
2015-10-25 03:21:50 -07:00
var getBacklogUrl string
2015-10-25 12:40:07 -07:00
var backendSharedKey [32]byte
2015-10-25 14:06:56 -07:00
var serverId int
2015-10-25 12:40:07 -07:00
var messageBufferPool sync.Pool
2015-10-25 03:21:50 -07:00
func SetupBackend(config *Config) {
backendHttpClient.Timeout = 60 * time.Second
backendUrl = config.BackendUrl
if responseCache != nil {
responseCache.Flush()
}
responseCache = cache.New(60 * time.Second, 120 * time.Second)
2015-10-25 03:21:50 -07:00
getBacklogUrl = fmt.Sprintf("%s/backlog", backendUrl)
2015-10-25 14:06:56 -07:00
messageBufferPool.New = New4KByteBuffer
2015-10-25 12:40:07 -07:00
var keys CryptoKeysBuf
file, err := os.Open(config.NaclKeysFile)
2015-10-25 03:21:50 -07:00
if err != nil {
log.Fatal(err)
}
2015-10-25 12:40:07 -07:00
dec := json.NewDecoder(file)
err = dec.Decode(&keys)
if err != nil {
log.Fatal(err)
2015-10-25 03:21:50 -07:00
}
2015-10-25 12:40:07 -07:00
2015-10-25 14:06:56 -07:00
var theirPublic, ourPrivate [32]byte
copy(theirPublic[:], keys.TheirPublicKey)
copy(ourPrivate[:], keys.OurPrivateKey)
serverId = keys.ServerId
box.Precompute(&backendSharedKey, &theirPublic, &ourPrivate)
}
func getCacheKey(remoteCommand, data string) string {
return fmt.Sprintf("%s/%s", remoteCommand, data)
}
func RequestRemoteDataCached(remoteCommand, data string, auth AuthInfo) (string, error) {
cached, ok := responseCache.Get(getCacheKey(remoteCommand, data))
if ok {
return cached.(string), nil
}
return RequestRemoteData(remoteCommand, data, auth)
}
2015-10-25 12:40:07 -07:00
func RequestRemoteData(remoteCommand, data string, auth AuthInfo) (responseStr string, err error) {
2015-10-25 03:21:50 -07:00
destUrl := fmt.Sprintf("%s/cmd/%s", backendUrl, remoteCommand)
var authKey string
if auth.UsernameValidated {
authKey = "usernameClaimed"
} else {
authKey = "username"
}
formData := url.Values{
"clientData": []string{data},
authKey: []string{auth.TwitchUsername},
}
2015-10-25 03:21:50 -07:00
resp, err := backendHttpClient.PostForm(destUrl, formData)
if err != nil {
return "", err
}
respBytes, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return "", err
}
2015-10-25 12:40:07 -07:00
responseStr = string(respBytes)
if resp.Header.Get("FFZ-Cache") != "" {
durSecs, err := strconv.ParseInt(resp.Header.Get("FFZ-Cache"), 10, 64)
if err != nil {
return "", fmt.Errorf("The RPC server returned a non-integer cache duration: %v", err)
}
duration := time.Duration(durSecs) * time.Second
2015-10-25 12:40:07 -07:00
responseCache.Set(getCacheKey(remoteCommand, data), responseStr, duration)
}
2015-10-25 12:40:07 -07:00
return
2015-10-25 03:21:50 -07:00
}
func FetchBacklogData(chatSubs, channelSubs []string) ([]ClientMessage, error) {
formData := url.Values{
"chatSubs": chatSubs,
"channelSubs": channelSubs,
}
resp, err := backendHttpClient.PostForm(getBacklogUrl, formData)
if err != nil {
return nil, err
}
dec := json.NewDecoder(resp.Body)
var messages []ClientMessage
err = dec.Decode(messages)
if err != nil {
return nil, err
}
return messages, nil
2015-10-25 12:40:07 -07:00
}
func GenerateKeys(outputFile, serverId, theirPublicStr string) {
var err error
output := CryptoKeysBuf{}
output.ServerId, err = strconv.Atoi(serverId)
if err != nil {
log.Fatal(err)
}
ourPublic, ourPrivate, err := box.GenerateKey(rand.Reader)
if err != nil {
log.Fatal(err)
}
2015-10-25 14:06:56 -07:00
output.OurPublicKey, output.OurPrivateKey = ourPublic[:], ourPrivate[:]
2015-10-25 12:40:07 -07:00
if theirPublicStr != "" {
2015-10-25 14:06:56 -07:00
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(theirPublicStr))
2015-10-25 12:40:07 -07:00
theirPublic, err := ioutil.ReadAll(reader)
if err != nil {
log.Fatal(err)
}
2015-10-25 14:06:56 -07:00
log.Print(theirPublic)
output.TheirPublicKey = theirPublic
2015-10-25 12:40:07 -07:00
}
file, err := os.Create(outputFile)
if err != nil {
log.Fatal(err)
}
enc := json.NewEncoder(file)
err = enc.Encode(output)
if err != nil {
log.Fatal(err)
}
err = file.Close()
if err != nil {
log.Fatal(err)
}
}