package main import ( "encoding/base64" "flag" "fmt" "net/http" "strconv" "time" "yumc.pw/cloud/clipboard-sync/lib/clipboard" ) func main() { t := flag.String("t", "c", "Type c(client) or s(server)") a := flag.String("a", "http://127.0.0.1:8080", "Server Address") b := flag.String("b", ":8080", "Server Listen Port") flag.Parse() if *t == "c" { if clipboard.Unsupported { panic("Unsupported On This Machine") } syncClipboard(*a) } else { startServer(*b) } } const ( textHeader = "Go-Clipboard-Text" timeHeader = "Go-Clipboard-Time" ) func startServer(b string) { text := "" time := time.Now().Unix() http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) { switch req.Method { case "GET": resp.Header().Add(textHeader, text) resp.Header().Add(timeHeader, strconv.FormatInt(time, 10)) break case "POST": text = req.Header.Get(textHeader) time, _ = strconv.ParseInt(req.Header.Get(timeHeader), 10, 64) fmt.Printf("Client %s Update Clipboard...\n", req.RemoteAddr) break } }) fmt.Println("Start Server Listen On: " + b) http.ListenAndServe(b, nil) } func syncClipboard(a string) { old, _ := clipboard.ReadAll() updateTime := time.Now().Unix() client := &http.Client{} address := a fmt.Printf("Start Client Connect to Server %s\n", address) for { time.Sleep(100 * time.Millisecond) text, _ := clipboard.ReadAll() if old != text { old = text updateTime = time.Now().Unix() request, _ := http.NewRequest("POST", address, nil) request.Header.Add(textHeader, encode(text)) request.Header.Add(timeHeader, strconv.FormatInt(updateTime, 10)) client.Do(request) } else { response, err := http.Get(a) if err != nil { time.Sleep(1000 * time.Millisecond) fmt.Printf("Http Request Error: %s\n", err.Error()) continue } texts, ok := response.Header[textHeader] if ok { sText := decode(texts[0]) sTime, _ := strconv.ParseInt(response.Header[timeHeader][0], 10, 64) if sTime > updateTime && sText != old { old = sText updateTime = sTime clipboard.WriteAll(sText) fmt.Printf("Update Clipboard: %s\n", sText) } } } } } func encode(text string) string { return base64.URLEncoding.EncodeToString([]byte(text)) } func decode(text string) string { origin, _ := base64.URLEncoding.DecodeString(text) return string(origin) }