mirror of
https://github.com/anyproto/anytype-ts.git
synced 2025-06-08 05:57:02 +09:00
more reliable way to differentiate mw port
This commit is contained in:
parent
9f7bba1853
commit
b78783dc94
3 changed files with 104 additions and 17 deletions
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
- This is the native messaging host for the AnyType browser extension.
|
||||
- It enables the web extension to find the open ports of the AnyType application and to start it if it is not running.
|
||||
- It is installed by the Electron script found in electron/js/lib/installNativeMessagingHost.js
|
||||
|
@ -10,20 +10,23 @@ package main
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
|
||||
// UTILITY FUNCTIONS
|
||||
|
||||
// splits stdout into an array of lines, removing empty lines
|
||||
|
@ -106,6 +109,62 @@ func getOpenPortsWindows() (map[string][]string, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func isFileGateway(port string) bool {
|
||||
client := &http.Client{}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "http://192.168.184.136:"+port+"/file", nil)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// disable follow redirect
|
||||
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
bu := bytes.NewBuffer(nil)
|
||||
resp.Request.Write(bu)
|
||||
ioutil.ReadAll(bu)
|
||||
|
||||
defer resp.Body.Close()
|
||||
// should return 301 redirect Location: /file/
|
||||
if resp.StatusCode == 301 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isGrpcWebServer(port string) bool {
|
||||
client := &http.Client{}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
var data = strings.NewReader(`AAAAAAIQFA==`)
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", "http://192.168.184.136:"+port+"/anytype.ClientCommands/AppGetVersion", data)
|
||||
if err != nil {
|
||||
return false
|
||||
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/grpc-web-text")
|
||||
req.Header.Set("X-Grpc-Web", "1")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// should has Content-Type: application/grpc-web-text
|
||||
if resp.Header.Get("Content-Type") == "application/grpc-web-text" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// MacOS and Linux: returns a list of all open ports for all instances of anytype found using cli utilities lsof and grep
|
||||
func getOpenPortsUnix() (map[string][]string, error) {
|
||||
// execute the command
|
||||
|
@ -148,19 +207,47 @@ func getOpenPortsUnix() (map[string][]string, error) {
|
|||
func getOpenPorts() (map[string][]string, error) {
|
||||
// Get Platform
|
||||
platform := runtime.GOOS
|
||||
|
||||
Trace.Print("Getting Open Ports on Platform: " + platform)
|
||||
|
||||
var (
|
||||
ports map[string][]string
|
||||
err error
|
||||
)
|
||||
// Platform specific functions
|
||||
if platform == "windows" {
|
||||
return getOpenPortsWindows()
|
||||
ports, err = getOpenPortsWindows()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if platform == "darwin" {
|
||||
return getOpenPortsUnix()
|
||||
ports, err = getOpenPortsUnix()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if platform == "linux" {
|
||||
return getOpenPortsUnix()
|
||||
ports, err = getOpenPortsUnix()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, errors.New("unsupported platform")
|
||||
}
|
||||
for pid, pidports := range ports {
|
||||
var gatewayPort, grpcWebPort string
|
||||
for _, port := range pidports {
|
||||
if isFileGateway(port) {
|
||||
gatewayPort = port
|
||||
} else if isGrpcWebServer(port) {
|
||||
grpcWebPort = port
|
||||
}
|
||||
}
|
||||
if gatewayPort != "" && grpcWebPort != "" {
|
||||
ports[pid] = []string{grpcWebPort, gatewayPort}
|
||||
} else {
|
||||
delete(ports, pid)
|
||||
}
|
||||
}
|
||||
Trace.Printf("found ports: %v", ports)
|
||||
|
||||
return ports, nil
|
||||
}
|
||||
|
||||
// Windows, MacOS and Linux: Starts AnyType as a detached process and returns the PID
|
||||
|
@ -237,7 +324,9 @@ func Init(traceHandle io.Writer, errorHandle io.Writer) {
|
|||
}
|
||||
|
||||
func main() {
|
||||
file, err := os.OpenFile("nmh.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
// create temp file for logging
|
||||
tmpFileName := filepath.Join(os.TempDir(), "anytype-nmh.log")
|
||||
file, err := os.OpenFile(tmpFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
Init(os.Stdout, os.Stderr)
|
||||
Error.Printf("Unable to create and/or open log file. Will log to Stdout and Stderr. Error: %v", err)
|
||||
|
@ -247,7 +336,7 @@ func main() {
|
|||
defer file.Close()
|
||||
}
|
||||
|
||||
Trace.Printf("Chrome native messaging host started. Native byte order: %v.", nativeEndian)
|
||||
Trace.Printf("Chrome native messaging host started")
|
||||
read()
|
||||
Trace.Print("Chrome native messaging host exited.")
|
||||
}
|
||||
|
@ -257,7 +346,6 @@ func read() {
|
|||
v := bufio.NewReader(os.Stdin)
|
||||
// adjust buffer size to accommodate your json payload size limits; default is 4096
|
||||
s := bufio.NewReaderSize(v, bufferSize)
|
||||
Trace.Printf("IO buffer reader created with buffer size of %v.", s.Size())
|
||||
|
||||
lengthBytes := make([]byte, 4)
|
||||
lengthNum := int(0)
|
||||
|
@ -267,7 +355,6 @@ func read() {
|
|||
for b, err := s.Read(lengthBytes); b > 0 && err == nil; b, err = s.Read(lengthBytes) {
|
||||
// convert message length bytes to integer value
|
||||
lengthNum = readMessageLength(lengthBytes)
|
||||
Trace.Printf("Message size in bytes: %v", lengthNum)
|
||||
|
||||
// If message length exceeds size of buffer, the message will be truncated.
|
||||
// This will likely cause an error when we attempt to unmarshal message to JSON.
|
||||
|
@ -303,7 +390,7 @@ func readMessageLength(msg []byte) int {
|
|||
// parseMessage parses incoming message
|
||||
func parseMessage(msg []byte) {
|
||||
iMsg := decodeMessage(msg)
|
||||
Trace.Printf("Message received: %s", msg)
|
||||
Trace.Printf("Message received: %s: %s", iMsg.Type, msg)
|
||||
|
||||
// start building outgoing json message
|
||||
oMsg := OutgoingMessage{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue