From ada1da1bac734271f53bc29a4ad21f9b4a89cfb2 Mon Sep 17 00:00:00 2001 From: shengxiang Date: Wed, 29 Nov 2017 19:18:02 +0800 Subject: [PATCH] use net.dns1 as dns server and fallback to 8.8.8.8, add screenrecord method --- initialize.go | 14 ++++++++--- main.go | 66 +++++++++++++++++++++++++++++++++++++++++++++++++- tunnelproxy.go | 3 ++- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/initialize.go b/initialize.go index bd8f80b..919969f 100644 --- a/initialize.go +++ b/initialize.go @@ -21,7 +21,7 @@ var ( httpServer *http.Server ) -func dnsLookupHost(hostname string) (ip net.IP, err error) { +func dnsLookupHost(hostname string, dnsServer string) (ip net.IP, err error) { if !strings.HasSuffix(hostname, ".") { hostname += "." } @@ -33,7 +33,8 @@ func dnsLookupHost(hostname string) (ip net.IP, err error) { } c := new(dns.Client) c.SingleInflight = true - in, _, err := c.Exchange(m1, "8.8.8.8:53") + + in, _, err := c.Exchange(m1, dnsServer+":53") if err != nil { return nil, err } @@ -45,7 +46,7 @@ func dnsLookupHost(hostname string) (ip net.IP, err error) { return t.A, nil } if t, ok := in.Answer[0].(*dns.CNAME); ok { - return dnsLookupHost(t.Target) + return dnsLookupHost(t.Target, dnsServer) } return nil, errors.New("dns resolve failed: " + hostname) } @@ -56,11 +57,16 @@ func init() { KeepAlive: 30 * time.Second, DualStack: true, } + // get default dns server + dnsServer := getProperty("net.dns1") + if dnsServer == "" { + dnsServer = "8.8.8.8" + } // manualy dns resolve newDialContext := func(ctx context.Context, network, addr string) (net.Conn, error) { host, port, _ := net.SplitHostPort(addr) if net.ParseIP(host) == nil { - ip, err := dnsLookupHost(host) + ip, err := dnsLookupHost(host, dnsServer) if err != nil { return nil, err } diff --git a/main.go b/main.go index 9cb62ca..fd61bb0 100644 --- a/main.go +++ b/main.go @@ -583,12 +583,76 @@ func ServeHTTP(lis net.Listener, tunnel *TunnelProxy) error { dp := downManager.Get(id) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(dp) - }) + }).Methods("GET") m.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, version) }) + // FIXME(ssx): screenrecord is not good enough, need to change later + var recordCmd *exec.Cmd + var recordDone = make(chan bool, 1) + var recordLock sync.Mutex + var recordFolder = "/sdcard/screenrecords/" + var recordRunning = false + + m.HandleFunc("/screenrecord", func(w http.ResponseWriter, r *http.Request) { + recordLock.Lock() + defer recordLock.Unlock() + + if recordCmd != nil { + http.Error(w, "screenrecord not closed", 400) + return + } + os.RemoveAll(recordFolder) + os.MkdirAll(recordFolder, 0755) + recordCmd = exec.Command("screenrecord", recordFolder+"0.mp4") + if err := recordCmd.Start(); err != nil { + http.Error(w, err.Error(), 500) + return + } + recordRunning = true + go func() { + for i := 1; recordCmd.Wait() == nil && i <= 20 && recordRunning; i++ { // set limit, to prevent too many videos. max 1 hour + recordCmd = exec.Command("screenrecord", recordFolder+strconv.Itoa(i)+".mp4") + if err := recordCmd.Start(); err != nil { + log.Println("screenrecord error:", err) + break + } + } + recordDone <- true + }() + io.WriteString(w, "screenrecord started") + }).Methods("POST") + + m.HandleFunc("/screenrecord", func(w http.ResponseWriter, r *http.Request) { + recordLock.Lock() + defer recordLock.Unlock() + + recordRunning = false + if recordCmd != nil { + if recordCmd.Process != nil { + recordCmd.Process.Signal(os.Interrupt) + } + select { + case <-recordDone: + case <-time.After(5 * time.Second): + // force kill + exec.Command("pkill", "screenrecord").Run() + } + recordCmd = nil + } + w.Header().Set("Content-Type", "application/json") + files, _ := ioutil.ReadDir(recordFolder) + videos := []string{} + for i := 0; i < len(files); i++ { + videos = append(videos, fmt.Sprintf(recordFolder+"%d.mp4", i)) + } + json.NewEncoder(w).Encode(map[string]interface{}{ + "videos": videos, + }) + }).Methods("PUT") + m.HandleFunc("/upgrade", func(w http.ResponseWriter, r *http.Request) { ver := r.FormValue("version") var err error diff --git a/tunnelproxy.go b/tunnelproxy.go index d803171..8eb5b9a 100644 --- a/tunnelproxy.go +++ b/tunnelproxy.go @@ -4,6 +4,7 @@ import ( "errors" "log" "os" + "strings" "time" "github.com/franela/goreq" @@ -28,7 +29,7 @@ func getDeviceInfo() *proto.DeviceInfo { devInfo.Battery = battery // Udid is ${Serial}-${MacAddress}-${model} - udid := getProperty("ro.serialno") + "-" + devInfo.HWAddr + "-" + getProperty("ro.product.model") + udid := getProperty("ro.serialno") + "-" + devInfo.HWAddr + "-" + strings.Replace(getProperty("ro.product.model"), " ", "_", -1) devInfo.Udid = udid currentDeviceInfo = devInfo }