Skip to content
This repository has been archived by the owner on May 27, 2024. It is now read-only.

Commit

Permalink
/minicap support singlefight occupy old connection
Browse files Browse the repository at this point in the history
  • Loading branch information
codeskyblue committed Feb 7, 2018
1 parent 9c01489 commit 2efeb48
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 46 deletions.
80 changes: 34 additions & 46 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func init() {
// - minitouch
var muxMutex = sync.Mutex{}
var muxLocks = make(map[string]bool)
var muxConns = make(map[string]*websocket.Conn)

func singleFightWrap(handleFunc func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -83,6 +84,33 @@ func singleFightWrap(handleFunc func(http.ResponseWriter, *http.Request)) func(h
}
}

func singleFightNewerWebsocket(handleFunc func(http.ResponseWriter, *http.Request, *websocket.Conn)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
muxMutex.Lock()
if oldWs, ok := muxConns[r.RequestURI]; ok {
oldWs.Close()
delete(muxConns, r.RequestURI)
}

wsConn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
http.Error(w, "websocket upgrade error", 500)
muxMutex.Unlock()
return
}
muxConns[r.RequestURI] = wsConn
muxMutex.Unlock()

handleFunc(w, r, wsConn) // handle request

muxMutex.Lock()
if muxConns[r.RequestURI] == wsConn { // release connection
delete(muxConns, r.RequestURI)
}
muxMutex.Unlock()
}
}

// Get preferred outbound ip of this machine
func getOutboundIP() (ip net.IP, err error) {
conn, err := net.Dial("udp", "8.8.8.8:80")
Expand Down Expand Up @@ -119,35 +147,6 @@ type MinicapInfo struct {
Density float32 `json:"density"`
}

func httpDownload(path string, urlStr string, perms os.FileMode) (written int64, err error) {
resp, err := goreq.Request{
Uri: urlStr,
RedirectHeaders: true,
MaxRedirects: 10,
}.Do()
if err != nil {
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("http download <%s> status %v", urlStr, resp.Status)
return
}
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, perms)
if err != nil {
return
}
defer file.Close()
written, err = io.Copy(file, resp.Body)
log.Println("http download:", written)
return
}

func fileExists(path string) bool {
_, err := os.Stat(path)
return err == nil
}

var (
propOnce sync.Once
properties map[string]string
Expand Down Expand Up @@ -464,7 +463,7 @@ func ServeHTTP(lis net.Listener, tunnel *TunnelProxy) error {
packageName := mux.Vars(r)["pkgname"]
mainActivity, err := mainActivityOf(packageName)
if err != nil {
http.Error(w, err.Error(), 500)
http.Error(w, err.Error(), http.StatusGone) // 410
return
}
flags := r.FormValue("flags")
Expand Down Expand Up @@ -764,12 +763,7 @@ func ServeHTTP(lis net.Listener, tunnel *TunnelProxy) error {
io.WriteString(w, "Unable to canceled")
}).Methods("DELETE")

m.HandleFunc("/minitouch", singleFightWrap(func(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Print("upgrade:", err)
return
}
m.HandleFunc("/minitouch", singleFightNewerWebsocket(func(w http.ResponseWriter, r *http.Request, ws *websocket.Conn) {
defer ws.Close()
const wsWriteWait = 10 * time.Second
wsWrite := func(messageType int, data []byte) error {
Expand Down Expand Up @@ -837,26 +831,20 @@ func ServeHTTP(lis net.Listener, tunnel *TunnelProxy) error {
}
}))

m.HandleFunc("/minicap", singleFightWrap(func(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Print("upgrade:", err)
return
}
m.HandleFunc("/minicap", singleFightNewerWebsocket(func(w http.ResponseWriter, r *http.Request, ws *websocket.Conn) {
defer ws.Close()

const wsWriteWait = 10 * time.Second
wsWrite := func(messageType int, data []byte) error {
ws.SetWriteDeadline(time.Now().Add(wsWriteWait))
return ws.WriteMessage(messageType, data)
}
wsWrite(websocket.TextMessage, []byte("start @minicap service"))
if err := service.Start("minicap"); err != nil && err != cmdctrl.ErrAlreadyRunning {
wsWrite(websocket.TextMessage, []byte("restart @minicap service"))
if err := service.Restart("minicap"); err != nil && err != cmdctrl.ErrAlreadyRunning {
wsWrite(websocket.TextMessage, []byte("@minicap service start failed: "+err.Error()))
return
}
defer service.Stop("minicap")
// TODO

wsWrite(websocket.TextMessage, []byte("dial unix:@minicap"))
log.Printf("minicap connection: %v", r.RemoteAddr)
dataC := make(chan []byte, 10)
Expand Down
34 changes: 34 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ import (
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"time"

"github.com/codeskyblue/procfs"
"github.com/franela/goreq"
shellquote "github.com/kballard/go-shellquote"
"github.com/shogo82148/androidbinary/apk"
)
Expand All @@ -25,6 +29,11 @@ func TempFileName(dir, suffix string) string {
return filepath.Join(dir, hex.EncodeToString(randBytes)+suffix)
}

func fileExists(path string) bool {
_, err := os.Stat(path)
return err == nil
}

// Command add timeout support for os/exec
type Command struct {
Args []string
Expand Down Expand Up @@ -184,3 +193,28 @@ func mainActivityOf(packageName string) (activity string, err error) {
}
return "", errors.New("package not found")
}

// download minicap or minitouch apk, etc...
func httpDownload(path string, urlStr string, perms os.FileMode) (written int64, err error) {
resp, err := goreq.Request{
Uri: urlStr,
RedirectHeaders: true,
MaxRedirects: 10,
}.Do()
if err != nil {
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("http download <%s> status %v", urlStr, resp.Status)
return
}
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, perms)
if err != nil {
return
}
defer file.Close()
written, err = io.Copy(file, resp.Body)
log.Println("http download:", written)
return
}

0 comments on commit 2efeb48

Please sign in to comment.