// HandleWebsocketConnection handles the online viewers per example(gist source)
4966
func HandleWebsocketConnection(c websocket.Connection) {

	c.On("watch", func(pageSource string) {
		v.Add(pageSource)
		// join the socket to a room linked with the page source
		c.Join(pageSource)

		viewsCount := v.Get(pageSource).getCount()
		if viewsCount == 0 {
			viewsCount++ // count should be always > 0 here
		}
		c.To(pageSource).Emit("watch", viewsCount)
	})

	c.OnLeave(func(roomName string) {
		if roomName != c.ID() { // if the roomName  it's not the connection iself
			// the roomName here is the source, this is the only room(except the connection's ID room) which we join the users to.
			pageV := v.Get(roomName)
			if pageV == nil {
				return // for any case that this room is not a pageView source
			}
			// decrement -1 the specific counter for this page source.
			pageV.decrement()
			// 1. open 30 tabs.
			// 2. close the browser.
			// 3. re-open the browser
			// 4. should be  v.getCount() = 1
			// in order to achieve the previous flow we should decrement exactly when the user disconnects
			// but emit the result a little after, on a goroutine
			// getting all connections within this room and emit the online views one by one.
			// note:
			// we can also add a time.Sleep(2-3 seconds) inside the goroutine at the future if we don't need 'real-time' updates.
			go func(currentConnID string) {
				for _, conn := range c.Server().GetConnectionsByRoom(roomName) {
					if conn.ID() != currentConnID {
						conn.Emit("watch", pageV.getCount())
					}

				}
			}(c.ID())
		}

	})
}
278748
func IsWebSocketRequest(r *http.Request) bool {
	var _ interface{}
	_, hasUpgrade := r.Header["Upgrade"]
	_, hasSec := r.Header["Sec-Websocket-Version"]
	_, hasExt := r.Header["Sec-Websocket-Extensions"]
	_, hasKey := r.Header["Sec-Websocket-Key"]
	return hasUpgrade && hasSec && hasExt && hasKey
}
343232
func (exp *explorerUI) RootWebsocket(w http.ResponseWriter, r *http.Request) {
	wsHandler := websocket.Handler(func(ws *websocket.Conn) {
		// Create channel to signal updated data availability
		updateSig := make(hubSpoke, 3)
		// Create a channel for exchange updates
		xcChan := make(exchangeChannel, 3)
		// register websocket client with our signal channel
		clientData := exp.wsHub.RegisterClient(&updateSig, xcChan)
		// unregister (and close signal channel) before return
		defer exp.wsHub.UnregisterClient(&updateSig)

		// close the websocket
		closeWS := func() {
			err := ws.Close()
			// Do not log error if connection is just closed.
			if err != nil && !pstypes.IsWSClosedErr(err) &&
				!pstypes.IsIOTimeoutErr(err) {
				log.Errorf("Failed to close websocket: %v", err)
			}
		}
		defer closeWS()

		send := func(webData WebSocketMessage) error {
			err := ws.SetWriteDeadline(time.Now().Add(wsWriteTimeout))
			if err != nil && !pstypes.IsWSClosedErr(err) {
				log.Warnf("SetWriteDeadline failed: %v", err)
			}
			if err := websocket.JSON.Send(ws, webData); err != nil {
				// Do not log error if connection is just closed
				if !pstypes.IsWSClosedErr(err) {
					log.Debugf("Failed to send web socket message %s: %v", webData.EventId, err)
				}
				// If the send failed, the client is probably gone, so close
				// the connection and quit.
				return fmt.Errorf("Send fail")
			}
			return nil
		}

		requestLimit := 1 << 20
		// set the max payload size to 1 MB
		ws.MaxPayloadBytes = requestLimit

		// Start listening for websocket messages from client with raw
		// transaction bytes (hex encoded) to decode or broadcast.
		go func() {
			defer closeWS()
			for {
				// Wait to receive a message on the websocket
				msg := &WebSocketMessage{}
				err := ws.SetReadDeadline(time.Now().Add(wsReadTimeout))
				if err != nil && !pstypes.IsWSClosedErr(err) {
					log.Warnf("SetReadDeadline failed: %v", err)
				}
				if err = websocket.JSON.Receive(ws, &msg); err != nil {
					if err.Error() != "EOF" {
						log.Warnf("websocket client receive error: %v", err)
					}
					return
				}

				// handle received message according to event ID
				var webData WebSocketMessage
				//  If the request sent is past the limit continue to the next iteration.
				if len(msg.Message) > requestLimit {
					log.Debug("Request size over limit")
					webData.Message = "Request too large"
					continue
				}

				switch msg.EventId {
				case "decodetx":
					log.Debugf("Received decodetx signal for hex: %.40s...", msg.Message)
					tx, err := exp.blockData.DecodeRawTransaction(msg.Message)
					if err == nil {
						message, err := json.MarshalIndent(tx, "", "    ")
						if err != nil {
							log.Warn("Invalid JSON message: ", err)
							webData.Message = "Error: Could not encode JSON message"
							break
						}
						webData.Message = string(message)
					} else {
						log.Debugf("Could not decode raw tx")
						webData.Message = fmt.Sprintf("Error: %v", err)
					}

				case "sendtx":
					log.Debugf("Received sendtx signal for hex: %.40s...", msg.Message)
					txid, err := exp.blockData.SendRawTransaction(msg.Message)
					if err != nil {
						webData.Message = fmt.Sprintf("Error: %v", err)
					} else {
						webData.Message = fmt.Sprintf("Transaction sent: %s", txid)
					}

				case "getmempooltxs":
					// MempoolInfo. Used on mempool and home page.
					inv := exp.MempoolInventory()

					// Check if client supplied a mempool ID. If so, check that an update
					// is needed before sending.
					if msg.Message != "" {
						clientID, err := strconv.ParseUint(msg.Message, 10, 64)
						if err != nil {
							// For now, just log a warning and return the mempool anyway.
							log.Warn("Unable to parse supplied mempool ID %s", msg.Message)
						} else if inv.ID() == clientID {
							// Client is up-to-date. No need to send anything.
							continue
						}
					}

					inv.RLock()
					msg, err := json.Marshal(inv)
					inv.RUnlock()

					if err != nil {
						log.Warn("Invalid JSON message: ", err)
						webData.Message = "Error: Could not encode JSON message"
						break
					}
					webData.Message = string(msg)

				case "getmempooltrimmed":
					// TrimmedMempoolInfo. Used in nexthome.
					// construct mempool object with properties required in template
					inv := exp.MempoolInventory()
					mempoolInfo := inv.Trim() // Trim internally locks the MempoolInfo.

					exp.pageData.RLock()
					mempoolInfo.Subsidy = exp.pageData.HomeInfo.NBlockSubsidy
					exp.pageData.RUnlock()

					msg, err := json.Marshal(mempoolInfo)

					if err != nil {
						log.Warn("Invalid JSON message: ", err)
						webData.Message = "Error: Could not encode JSON message"
						break
					}
					webData.Message = string(msg)

				case "getticketpooldata":
					// Retrieve chart data on the given interval.
					interval := dbtypes.TimeGroupingFromStr(msg.Message)
					// Chart height is returned since the cache may be stale,
					// although it is automatically updated by the first caller
					// who requests data from a stale cache.
					timeChart, priceChart, donutChart, chartHeight, err :=
						exp.explorerSource.TicketPoolVisualization(interval)
					if dbtypes.IsTimeoutErr(err) {
						log.Warnf("TicketPoolVisualization DB timeout: %v", err)
						webData.Message = "Error: DB timeout"
						break
					}
					if err != nil {
						if strings.HasPrefix(err.Error(), "unknown interval") {
							log.Debugf("invalid ticket pool interval provided "+
								"via TicketPoolVisualization: %s", msg.Message)
							webData.Message = "Error: " + err.Error()
							break
						}
						log.Errorf("TicketPoolVisualization error: %v", err)
						webData.Message = "Error: failed to fetch ticketpool data"
						break
					}

					mp := new(apitypes.PriceCountTime)

					inv := exp.MempoolInventory()
					inv.RLock()
					if len(inv.Tickets) > 0 {
						mp.Price = inv.Tickets[0].TotalOut
						mp.Count = len(inv.Tickets)
						mp.Time = dbtypes.NewTimeDefFromUNIX(inv.Tickets[0].Time)
					} else {
						log.Debug("No tickets exists in the mempool")
					}
					inv.RUnlock()

					data := &apitypes.TicketPoolChartsData{
						ChartHeight: uint64(chartHeight),
						TimeChart:   timeChart,
						PriceChart:  priceChart,
						DonutChart:  donutChart,
						Mempool:     mp,
					}

					msg, err := json.Marshal(data)
					if err != nil {
						log.Warn("Invalid JSON message: ", err)
						webData.Message = "Error: Could not encode JSON message"
						break
					}
					webData.Message = string(msg)

				case "ping":
					log.Tracef("We've been pinged: %.40s...", msg.Message)
					continue
				default:
					log.Warnf("Unrecognized event ID: %v", msg.EventId)
					continue
				}

				webData.EventId = msg.EventId + "Resp"

				err = send(webData)
				if err != nil {
					return
				}
			}
		}()

		// Send loop (ping, new tx, block, etc. update loop)
	loop:
		for {
			// Wait for signal from the hub to update
			select {
			case sig, ok := <-updateSig:
				// Check if the update channel was closed. Either the websocket
				// hub will do it after unregistering the client, or forcibly in
				// response to (http.CloseNotifier).CloseNotify() and only then
				// if the hub has somehow lost track of the client.
				if !ok {
					break loop
				}

				if !sig.IsValid() {
					log.Errorf("invalid signal to send: %s / %d", sig.Signal.String(), int(sig.Signal))
					continue
				}

				log.Tracef("signaling client: %p", &updateSig)

				// Write block data to websocket client

				webData := WebSocketMessage{
					// Use HubSignal's string, not HubMessage's string, which is decorated.
					EventId: sig.Signal.String(),
					Message: "error",
				}
				buff := new(bytes.Buffer)
				enc := json.NewEncoder(buff)
				switch sig.Signal {
				case sigNewBlock:
					exp.pageData.RLock()
					err := enc.Encode(types.WebsocketBlock{
						Block: exp.pageData.BlockInfo,
						Extra: exp.pageData.HomeInfo,
					})
					exp.pageData.RUnlock()
					if err == nil {
						webData.Message = buff.String()
					} else {
						log.Errorf("json.Encode(WebsocketBlock) failed: %v", err)
					}

				case sigMempoolUpdate:
					inv := exp.MempoolInventory()
					inv.RLock()
					err := enc.Encode(inv.MempoolShort)
					inv.RUnlock()
					if err == nil {
						webData.Message = buff.String()
					} else {
						log.Errorf("json.Encode(MempoolShort) failed: %v", err)
					}

				case sigPingAndUserCount:
					// ping and send user count
					webData.Message = strconv.Itoa(exp.wsHub.NumClients())
				case sigNewTxs:
					// Do not use any tx slice in sig.Msg. Instead use client's
					// new transactions slice, newTxs.
					clientData.RLock()
					err := enc.Encode(clientData.newTxs)
					clientData.RUnlock()
					if err == nil {
						webData.Message = buff.String()
					} else {
						log.Errorf("json.Encode([]*MempoolTx) failed: %v", err)
					}

				case sigSyncStatus:
					err := enc.Encode(SyncStatus())
					if err == nil {
						webData.Message = buff.String()
					} else {
						log.Errorf("json.Encode([]SyncStatusInfo) failed: %v", err)
					}

				default:
					log.Errorf("RootWebsocket: Unhandled signal: %v", sig)
				}

				err := send(webData)
				if err != nil {
					return
				}

			case update := <-xcChan:
				buff := new(bytes.Buffer)
				enc := json.NewEncoder(buff)
				webData := WebSocketMessage{
					EventId: exchangeUpdateID,
					Message: "error",
				}
				err := enc.Encode(update)
				if err == nil {
					webData.Message = buff.String()
				} else {
					log.Errorf("json.Encode(*WebsocketExchangeUpdate) failed: %v", err)
				}
				err = send(webData)
				if err != nil {
					return
				}

			case <-exp.wsHub.quitWSHandler:
				break loop
			} // select
		} // for a.k.a. loop:
	}) // wsHandler := websocket.Handler(func(ws *websocket.Conn) {

	wsHandler.ServeHTTP(w, r)
}
57814
func NewWebsocketDialer(handler http.Handler) *websocket.Dialer {
	return &websocket.Dialer{
		NetDial: func(network, addr string) (net.Conn, error) {
			hc := newHandlerConn()
			hc.runHandler(handler)
			return hc, nil
		},
	}
}
125501
func (h *Harness) proxyWebsocket(w http.ResponseWriter, r *http.Request, host string) {
	var (
		d   net.Conn
		err error
	)
	if h.paths.HTTPSsl {
		// since this proxy isn't used in production,
		// it's OK to set InsecureSkipVerify to true
		// no need to add another configuration option.
		d, err = tls.Dial("tcp", host, &tls.Config{InsecureSkipVerify: true})
	} else {
		d, err = net.Dial("tcp", host)
	}
	if err != nil {
		http.Error(w, "Error contacting backend server.", 500)
		utils.Logger.Error("Error dialing websocket backend ", "host", host, "error", err)
		return
	}
	hj, ok := w.(http.Hijacker)
	if !ok {
		http.Error(w, "Not a hijacker?", 500)
		return
	}
	nc, _, err := hj.Hijack()
	if err != nil {
		utils.Logger.Error("Hijack error", "error", err)
		return
	}
	defer func() {
		if err = nc.Close(); err != nil {
			utils.Logger.Error("Connection close error", "error", err)
		}
		if err = d.Close(); err != nil {
			utils.Logger.Error("Dial close error", "error", err)
		}
	}()

	err = r.Write(d)
	if err != nil {
		utils.Logger.Error("Error copying request to target", "error", err)
		return
	}

	errc := make(chan error, 2)
	cp := func(dst io.Writer, src io.Reader) {
		_, err := io.Copy(dst, src)
		errc <- err
	}
	go cp(d, nc)
	go cp(nc, d)
	<-errc
}
810756
func (s *Server) handleConn(conn net.Conn, isTLS bool) {
	// Read a single byte
	buf := make([]byte, 1)
	if _, err := conn.Read(buf); err != nil {
		if err != io.EOF {
			s.logger.Printf("[ERR] consul.rpc: failed to read byte: %v %s", err, logConn(conn))
		}
		conn.Close()
		return
	}
	typ := pool.RPCType(buf[0])

	// Enforce TLS if VerifyIncoming is set
	if s.config.VerifyIncoming && !isTLS && typ != pool.RPCTLS {
		s.logger.Printf("[WARN] consul.rpc: Non-TLS connection attempted with VerifyIncoming set %s", logConn(conn))
		conn.Close()
		return
	}

	// Switch on the byte
	switch typ {
	case pool.RPCConsul:
		s.handleConsulConn(conn)

	case pool.RPCRaft:
		metrics.IncrCounter([]string{"rpc", "raft_handoff"}, 1)
		s.raftLayer.Handoff(conn)

	case pool.RPCTLS:
		if s.rpcTLS == nil {
			s.logger.Printf("[WARN] consul.rpc: TLS connection attempted, server not configured for TLS %s", logConn(conn))
			conn.Close()
			return
		}
		conn = tls.Server(conn, s.rpcTLS)
		s.handleConn(conn, true)

	case pool.RPCMultiplexV2:
		s.handleMultiplexV2(conn)

	case pool.RPCSnapshot:
		s.handleSnapshotConn(conn)

	default:
		if !s.handleEnterpriseRPCConn(typ, conn, isTLS) {
			s.logger.Printf("[ERR] consul.rpc: unrecognized RPC byte: %v %s", typ, logConn(conn))
			conn.Close()
		}
	}
}
931753
func IsWebSocketUpgrade(r *http.Request) bool {
	return tokenListContainsValue(r.Header, "Connection", "upgrade") &&
		tokenListContainsValue(r.Header, "Upgrade", "websocket")
}
379697
func (xc *CommonExchange) startWebsocket() {
	ws, processor := xc.websocket()
	go func() {
		for {
			message, err := ws.Read()
			if err != nil {
				xc.setWsFail(err)
				return
			}
			processor(message)
		}
	}()
}
104173
func (s *Server) OnConnection(ws *websocket.Conn) {
	defer func() {
		ws.Close()
	}()

	client := NewClient(ws, s.hub)
	s.hub.Register(client)
	client.Listen()
}
81158
func (p *Provider) handleConnection(conn net.Conn) {
	// Create an RPC server to handle inbound
	pe := &providerEndpoint{p: p}
	rpcServer := rpc.NewServer()
	rpcServer.RegisterName("Client", pe)
	rpcCodec := msgpackrpc.NewCodec(false, false, conn)

	defer func() {
		if !pe.hijacked() {
			conn.Close()
		}
	}()

	for !p.IsShutdown() {
		if err := rpcServer.ServeRequest(rpcCodec); err != nil {
			if err != io.EOF && !strings.Contains(err.Error(), "closed") {
				p.logger.Printf("[ERR] scada-client: RPC error: %v", err)
			}
			return
		}

		// Handle potential hijack in Client.Connect
		if pe.hijacked() {
			cb := pe.getHijack()
			cb(conn)
			return
		}
	}
}
532899
func isWebsocket(req *http.Request) bool {
	if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" ||
		!strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") {
		return false
	}
	return true
}
848722
func newWebsocketChannel(conn *Conn, num byte, read, write bool) *websocketChannel {
	r, w := io.Pipe()
	return &websocketChannel{conn, num, r, w, read, write}
}
741511
func (p *Proxy) ServeTCP(conn net.Conn) {
	log.Debugf("Handling connection from %s", conn.RemoteAddr())
	defer conn.Close()
	connBackend, err := net.DialTCP("tcp", nil, p.target)
	if err != nil {
		log.Errorf("Error while connection to backend: %v", err)
		return
	}
	defer connBackend.Close()

	errChan := make(chan error, 1)
	go connCopy(conn, connBackend, errChan)
	go connCopy(connBackend, conn, errChan)

	err = <-errChan
	if err != nil {
		log.Errorf("Error during connection: %v", err)
	}
}
483124
func (ed *Dispatcher) HandleConnectEvent(e esdispatcher.Event) {
	evt := e.(*ConnectEvent)

	if ed.connection != nil {
		// Already connected. No error.
		evt.ErrCh <- nil
		return
	}

	eventch, err := ed.EventCh()
	if err != nil {
		evt.ErrCh <- err
		return
	}

	peers, err := ed.discoveryService.GetPeers()
	if err != nil {
		evt.ErrCh <- err
		return
	}

	if len(peers) == 0 {
		evt.ErrCh <- errors.New("no peers to connect to")
		return
	}

	peer, err := ed.peerResolver.Resolve(peers)
	if err != nil {
		evt.ErrCh <- err
		return
	}

	conn, err := ed.connectionProvider(ed.context, ed.chConfig, peer)
	if err != nil {
		logger.Warnf("error creating connection: %s", err)
		evt.ErrCh <- errors.WithMessagef(err, "could not create client conn")
		return
	}

	ed.connection = conn
	ed.setConnectedPeer(peer)

	go ed.connection.Receive(eventch)

	evt.ErrCh <- nil
}
915865
func NewAtomicWebSocketSet() AtomicWebSocketSet {
	return AtomicWebSocketSet{
		sockets: map[uint64]*websocket.Conn{},
		mutex:   &sync.Mutex{},
	}
}
489741
func (mr *MockNetworkAPIClientMockRecorder) NetworkConnect(ctx, networkID, container, config interface{}) *gomock.Call {
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkConnect", reflect.TypeOf((*MockNetworkAPIClient)(nil).NetworkConnect), ctx, networkID, container, config)
}
1078330
func handleRequest(conn net.Conn, rhost string) error {
	fmt.Println("TCP connection received")
	defer func() { fmt.Println("Connection closed") }()
	defer conn.Close()

	REQUEST_HEADERS := map[string][]string{
		"Sec-WebSocket-Protocol": []string{"binary", "base64"},
		"Sec-WebSocket-Version":  []string{"13"},
	}

	dialer := websocket.Dialer{Proxy: http.ProxyFromEnvironment}
	ws, response, err := dialer.Dial(rhost, REQUEST_HEADERS)
	if err != nil {
		return err
	}
	defer ws.Close()

	protocol_arr := response.Header["Sec-Websocket-Protocol"]
	var protocol string
	if len(protocol_arr) > 0 {
		protocol = protocol_arr[0]
	}

	var messageType int
	if protocol == "base64" {
		messageType = websocket.TextMessage
	} else if protocol == "binary" {
		messageType = websocket.BinaryMessage
	} else {
		return fmt.Errorf("Expected Sec-Websocket-Protocol header value of binary or base64, got:\n%s", response.Header)
	}

	fmt.Println("Websocket connection established, proxying...")
	var stopChan = make(chan int)
	go pipe_to_ws(conn, ws, messageType, stopChan)
	pipe_to_net(conn, ws, messageType, stopChan)
	return nil
}