Relay option added

Restructured ctl to http protocol
Minor modifications throughout
This commit is contained in:
Farhan Khan 2022-01-13 17:09:12 -05:00
parent 9b44f7728a
commit 2d7c09a905
5 changed files with 105 additions and 256 deletions

View File

@ -2,58 +2,38 @@ package main
import ( import (
"bytes" "bytes"
"encoding/json"
"flag" "flag"
"fmt" "fmt"
"io"
"log" "log"
"net/http" "net/http"
"os" "os"
"time" "time"
"gitlab.com/khanzf/fedilogue/shared"
) )
func main() { func main() {
shutdownPtr := flag.Bool("shutdown", false, "Shutdown server")
suspendPtr := flag.String("suspend", "", "Instance to Suspend")
resumePtr := flag.String("resume", "", "Instance to Resume")
addPtr := flag.String("add", "", "Instance to add") addPtr := flag.String("add", "", "Instance to add")
statusPtr := flag.Bool("status", false, "Check status")
followPtr := flag.String("follow", "", "Follow a target relay") followPtr := flag.String("follow", "", "Follow a target relay")
statusPtr := flag.Bool("status", false, "Get server status")
flag.Parse() flag.Parse()
/* Condition verification */ /* Condition verification */
totalflags := 0 totalflags := 0
var commandMap shared.CommandMap var cmdType string
//var responseback shared.ResponseBack var requestJson string
if *statusPtr != false {
if *shutdownPtr {
totalflags++ totalflags++
commandMap.Type = "shutdown" cmdType = "status"
}
if *statusPtr {
totalflags++
commandMap.Type = "status"
}
if *addPtr != "" {
totalflags++
commandMap.Type = "add"
commandMap.Endpoint = *addPtr
}
if *suspendPtr != "" {
totalflags++
commandMap.Type = "suspend"
}
if *resumePtr != "" {
totalflags++
commandMap.Type = "resume"
} }
if *followPtr != "" { if *followPtr != "" {
totalflags++ totalflags++
commandMap.Type = "follow" cmdType = "follow"
commandMap.Endpoint = *followPtr requestJson = fmt.Sprintf(`{"follow": "%s"}`, *followPtr)
}
if *addPtr != "" {
totalflags++
cmdType = "add"
requestJson = fmt.Sprintf(`{"host": "%s"}`, *addPtr)
} }
if totalflags > 1 { if totalflags > 1 {
@ -64,101 +44,30 @@ func main() {
os.Exit(1) os.Exit(1)
} }
commandByte, err := json.Marshal(commandMap) requestBytes := []byte(requestJson)
if err != nil { payload := bytes.NewReader(requestBytes)
fmt.Println(err)
return
}
payload := bytes.NewReader(commandByte)
req, err := http.NewRequest("POST", "http://127.0.0.1:5555/"+commandMap.Type, payload) req, err := http.NewRequest("POST", "http://127.0.0.1:5555/"+cmdType, payload)
if err != nil { if err != nil {
log.Fatal("Error condition") log.Fatal("Error condition")
} }
client := &http.Client{Timeout: 10 * time.Second} client := &http.Client{Timeout: 10 * time.Second}
_, err = client.Do(req) resp, err := client.Do(req)
//res, err := client.Do(req)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
//resp, err := client.Do(req) switch cmdType {
/*
c, err := net.Dial("tcp", "127.0.0.1:5555")
if err != nil {
fmt.Println(err)
return
}
sizebytes := make([]byte, 4)
b := len(commandByte)
// Send the request
binary.LittleEndian.PutUint32(sizebytes, uint32(b))
_, err = c.Write(sizebytes)
if err != nil {
fmt.Println(err)
return
}
_, err = c.Write(commandByte)
if err != nil {
fmt.Println(err)
return
}
// Read the response
n, err := io.ReadFull(c, sizebytes)
if err != nil || n != 4 {
fmt.Println("err", err, n)
}
jsonsize := int(binary.LittleEndian.Uint32(sizebytes))
responsebytes := make([]byte, jsonsize)
_, err = io.ReadFull(c, responsebytes)
if err != nil {
fmt.Println("Read Error", err)
}
err = json.Unmarshal(responsebytes, &responseback)
if err != nil {
fmt.Println("Unmarshal error", err)
}
switch commandMap.Type {
case "add": case "add":
fmt.Println(responseback.Message) fmt.Println("Add")
case "status": case "status":
fmt.Println("Status\t\tLastRun\t\t\tCaptureType\tEndpoint") defer resp.Body.Close()
for endpoint, runninginstance := range responseback.RunningInstances { bodyBytes, _ := io.ReadAll(resp.Body)
if runninginstance.Status == 0 { fmt.Println(string(bodyBytes))
fmt.Fprintf(os.Stdout, "New\t")
fmt.Fprintf(os.Stdout, "\tNever\t\t\t")
} else if runninginstance.Status == 200 {
fmt.Fprintf(os.Stdout, "Running\t")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 429 {
fmt.Fprintf(os.Stdout, "TooManyRequests\t")
fmt.Fprintf(os.Stdout, "%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 600 {
fmt.Fprintf(os.Stdout, "ClientIssue")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 602 {
fmt.Fprintf(os.Stdout, "BadInstance")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 605 {
fmt.Fprintf(os.Stdout, "UnsupportedNode")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else {
fmt.Fprintf(os.Stdout, "%d\t", runninginstance.Status)
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
}
if runninginstance.LastRun == "Queued" {
fmt.Fprintf(os.Stdout, "\t\t")
}
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.CaptureType)
fmt.Fprintf(os.Stdout, "%s\n", endpoint)
}
case "follow": case "follow":
fmt.Println("This is a follow test") defer resp.Body.Close()
bodyBytes, _ := io.ReadAll(resp.Body)
fmt.Println(string(bodyBytes))
} }
*/
} }

View File

@ -6,8 +6,6 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"gitlab.com/khanzf/fedilogue/shared"
) )
func cmdFollow(w http.ResponseWriter, r *http.Request) { func cmdFollow(w http.ResponseWriter, r *http.Request) {
@ -18,111 +16,56 @@ func cmdFollow(w http.ResponseWriter, r *http.Request) {
} }
defer r.Body.Close() defer r.Body.Close()
var commandmap shared.CommandMap var followtarget interface{}
err = json.Unmarshal(body, &commandmap) err = json.Unmarshal(body, &followtarget)
if err != nil { if err != nil {
logWarn("Unable to unmarshal here, exiting...") fmt.Println(err)
return return
} }
go followInbox(commandmap.Endpoint)
myMap := followtarget.(map[string]interface{})
followInbox(myMap["follow"].(string))
fmt.Fprintf(w, "{}") fmt.Fprintf(w, "{}")
} }
func cmdAdd(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println(err)
return
}
defer r.Body.Close()
var addtarget interface{}
err = json.Unmarshal(body, &addtarget)
if err != nil {
fmt.Println(err)
return
}
myMap := addtarget.(map[string]interface{})
go StartInstance(myMap["host"].(string))
fmt.Fprintf(w, "{}")
}
func cmdStatus(w http.ResponseWriter, r *http.Request) {
ri_mutex.Lock()
bytes, err := json.Marshal(runninginstances)
if err != nil {
fmt.Println("Error happened", err)
}
ri_mutex.Unlock()
fmt.Fprintf(w, (string(bytes)))
}
func startctl() { func startctl() {
http.HandleFunc("/follow", cmdFollow) ctlweb := http.NewServeMux()
ctlweb.HandleFunc("/follow", cmdFollow)
ctlweb.HandleFunc("/status", cmdStatus)
ctlweb.HandleFunc("/add", cmdAdd)
log.Print("Starting HTTP inbox on port 127.0.0.1:5555") log.Print("Starting HTTP inbox on port 127.0.0.1:5555")
log.Fatal(http.ListenAndServe("127.0.0.1:5555", nil)) log.Fatal(http.ListenAndServe("127.0.0.1:5555", ctlweb))
} }
/*
func handleClient(commandClient net.Conn) {
defer commandClient.Close()
sizebyte := make([]byte, 4)
var commandmap shared.CommandMap
var responseback shared.ResponseBack
n, err := io.ReadFull(commandClient, sizebyte)
if err != nil {
logFatal.Fatal("Read error: ", err)
return
}
if n != 4 {
logFatal.Fatal("Did not read 4 bytes, failure.")
return
}
jsonsize := int(binary.LittleEndian.Uint32(sizebyte))
jsonbyte := make([]byte, jsonsize)
n, err = io.ReadFull(commandClient, jsonbyte)
if err != nil {
logFatal.Fatal("Unable to unmarshal")
}
if n != jsonsize {
logFatal.Fatal("Failed to read json size of ", n)
}
err = json.Unmarshal(jsonbyte, &commandmap)
if err != nil {
logFatal.Fatal("Unable to unmarshal")
}
switch commandmap.Type {
case "status":
responseback.Message = "Ok"
case "add":
logConn("Manually added instance: " + commandmap.Endpoint)
//ri_mutex.Lock()
_, exists := GetRunner(commandmap.Endpoint)
if exists == true {
logConn("Already exists: " + commandmap.Endpoint)
responseback.Message = "Exists: " + commandmap.Endpoint
} else {
responseback.Message = "Adding: " + commandmap.Endpoint
ri_mutex.Lock()
go StartInstance(commandmap.Endpoint)
ri_mutex.Unlock()
}
//ri_mutex.Unlock()
case "follow":
logInfo("Follow handling...")
responseback.Message = "Trying to follow " + commandmap.Endpoint
go followInbox(commandmap.Endpoint)
case "suspend":
logFatal.Fatal("Suspend")
case "resume":
logFatal.Fatal("Resume")
default:
logFatal.Fatal("Something else")
}
responseback.Type = "status"
responseback.RunningInstances = runninginstances
ri_mutex.Lock()
responsebytes, err := json.Marshal(responseback)
ri_mutex.Unlock()
if err != nil {
logFatal.Fatal(err)
}
n = len(responsebytes)
binary.LittleEndian.PutUint32(sizebyte, uint32(n))
_, err = commandClient.Write(sizebyte)
if err != nil {
logFatal.Fatal("Error on write:", err)
}
ri_mutex.Lock()
responsebyte, err := json.Marshal(responseback)
ri_mutex.Unlock()
if err != nil {
logFatal.Fatal("Error response back: ", err)
}
_, err = commandClient.Write(responsebyte)
if err != nil {
logFatal.Fatal("Error on write:", err)
}
}
*/

View File

@ -17,13 +17,12 @@ import (
) )
func followInbox(inboxurl string) { func followInbox(inboxurl string) {
matchset := re.FindStringSubmatch(inboxurl) matchset := re.FindStringSubmatch(inboxurl)
if matchset == nil { if matchset == nil {
log.Fatal("Unable to regex") logWarn("Unable to unregex request", inboxurl)
return
} }
inboxhostname := matchset[1] inboxhostname := matchset[1]
fmt.Println("The hostname is", inboxhostname)
keyBytes, err := ioutil.ReadFile("keys/private.pem") keyBytes, err := ioutil.ReadFile("keys/private.pem")
if err != nil { if err != nil {
@ -83,8 +82,8 @@ func followInbox(inboxurl string) {
} }
defer res.Body.Close() defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body) // body, err := ioutil.ReadAll(res.Body)
fmt.Printf("Body : %s", body) // fmt.Printf("Body : %s", body)
/* /*
matchset := re.FindStringSubmatch(targetInbox) matchset := re.FindStringSubmatch(targetInbox)

View File

@ -303,15 +303,18 @@ func errorHandler(w http.ResponseWriter, r *http.Request) {
} }
func webmain() { func webmain() {
http.HandleFunc("/.well-known/webfinger", webfinger)
http.HandleFunc("/.well-known/host-meta", hostmeta) webreceiver := http.NewServeMux()
http.HandleFunc("/inbox", inboxHandler())
http.HandleFunc("/internal/fetch", internalFetch) webreceiver.HandleFunc("/.well-known/webfinger", webfinger)
http.HandleFunc("/relay", relay) webreceiver.HandleFunc("/.well-known/host-meta", hostmeta)
http.HandleFunc("/users/fedilogue", usersFedilogue) webreceiver.HandleFunc("/inbox", inboxHandler())
http.HandleFunc("/users/fedilogue/followers", usersFedilogueFollowers) webreceiver.HandleFunc("/internal/fetch", internalFetch)
http.HandleFunc("/users/fedilogue/following", usersFedilogueFollowing) webreceiver.HandleFunc("/relay", relay)
http.HandleFunc("/", errorHandler) webreceiver.HandleFunc("/users/fedilogue", usersFedilogue)
webreceiver.HandleFunc("/users/fedilogue/followers", usersFedilogueFollowers)
webreceiver.HandleFunc("/users/fedilogue/following", usersFedilogueFollowing)
webreceiver.HandleFunc("/", errorHandler)
log.Print("Starting HTTP inbox on port 127.0.0.1:8042") log.Print("Starting HTTP inbox on port 127.0.0.1:8042")
log.Fatal(http.ListenAndServe("127.0.0.1:8042", nil)) log.Fatal(http.ListenAndServe("127.0.0.1:8042", webreceiver))
} }

View File

@ -56,13 +56,13 @@ type RunningInstance struct {
Status int `json:"status"` Status int `json:"status"`
LastRun string `json:"lastrun"` LastRun string `json:"lastrun"`
CaptureType string `json:"capturetype"` CaptureType string `json:"capturetype"`
Banned bool Banned bool `json:"-"`
Alwaysbot bool Alwaysbot bool `json:"-"`
Client http.Client Client http.Client `json:"-"`
Client_id string Client_id string `json:"-"`
Client_secret string Client_secret string `json:"-"`
Recentactivities *UniqueFifo Recentactivities *UniqueFifo `json:"-"`
Recentactors *UniqueFifo Recentactors *UniqueFifo `json:"-"`
} }
type NodeInfoSoftware struct { type NodeInfoSoftware struct {
@ -74,16 +74,11 @@ type NodeInfo struct {
Software NodeInfoSoftware `json:"software"` Software NodeInfoSoftware `json:"software"`
} }
type CommandMap struct { //type ResponseBack struct {
Type string `json:"Type"` ///Type string `json:"Type"`
Endpoint string `json:"Endpoint"` //Message string `json:"Message"`
} // RunningInstances map[string]RunningInstance `json:"RunningInstances"`
///}
type ResponseBack struct {
Type string `json:"Type"`
Message string `json:"Message"`
RunningInstances map[string]RunningInstance `json:"RunningInstances"`
}
type Userinfo struct { type Userinfo struct {
Id string `"json:id"` Id string `"json:id"`