Esempio n. 1
0
func vncWsHandler(w http.ResponseWriter, r *http.Request) {
	// we assume that if we got here, then the url must be sane and of
	// the format /ws/<host>/<port>
	path := r.URL.Path
	if !strings.HasSuffix(path, "/") {
		path += "/"
	}
	fields := strings.Split(path, "/")
	if len(fields) != 5 {
		http.NotFound(w, r)
		return
	}
	fields = fields[2:]

	rhost := fmt.Sprintf("%v:%v", fields[0], fields[1])

	// connect to the remote host
	remote, err := net.Dial("tcp", rhost)
	if err != nil {
		log.Errorln(err)
		http.StatusText(500)
		return
	}

	websocket.Handler(func(ws *websocket.Conn) {
		go func() {
			decoder := base64.NewDecoder(base64.StdEncoding, ws)
			tee := io.TeeReader(decoder, remote)

			for {
				// Read
				msg, err := vnc.ReadClientMessage(tee)
				if err != nil {
					if err == io.EOF || strings.Contains(err.Error(), "closed network") {
						break
					}

					log.Debugln(err)
					continue
				}

				if r, ok := vncKBRecording[rhost]; ok {
					r.RecordMessage(msg)
				}
			}

			remote.Close()
		}()
		func() {
			sbuf := make([]byte, VNC_WS_BUF)
			dbuf := make([]byte, 2*VNC_WS_BUF)
			for {
				n, err := remote.Read(sbuf)
				if err != nil {
					if !strings.Contains(err.Error(), "closed network connection") && err != io.EOF {
						log.Errorln(err)
					}
					break
				}
				base64.StdEncoding.Encode(dbuf, sbuf[0:n])
				n = base64.StdEncoding.EncodedLen(n)

				_, err = ws.Write(dbuf[0:n])
				if err != nil {
					log.Errorln(err)
					break
				}
			}
			ws.Close()
		}()
	}).ServeHTTP(w, r)
}