Ejemplo n.º 1
0
// Connect opens a connection to the backend and upgrades it to a websocket. Calls to
// 'MakeRequest' can be made after calling this, but responss will not be
// receivable until 'Serve' is also called.
func (cs *ClientServerImpl) Connect() error {
	parsedURL, err := url.Parse(cs.URL)
	if err != nil {
		return err
	}

	signer := authv4.NewHttpSigner(cs.Region, ServiceName, cs.CredentialProvider, nil)

	// NewRequest never returns an error if the url parses and we just verified
	// it did above
	request, _ := http.NewRequest("GET", cs.URL, nil)
	signer.SignHttpRequest(request)

	// url.Host might not have the port, but tls.Dial needs it
	dialHost := parsedURL.Host
	if !strings.Contains(dialHost, ":") {
		dialHost += ":443"
	}

	timeoutDialer := &net.Dialer{Timeout: wsConnectTimeout}
	log.Info("Creating poll dialer", "host", parsedURL.Host)
	wsConn, err := tls.DialWithDialer(timeoutDialer, "tcp", dialHost, &tls.Config{InsecureSkipVerify: cs.AcceptInvalidCert})
	if err != nil {
		return err
	}

	websocketConn, httpResponse, err := websocket.NewClient(wsConn, parsedURL, request.Header, readBufSize, writeBufSize)
	if httpResponse != nil {
		defer httpResponse.Body.Close()
	}
	if err != nil {
		var resp []byte
		if httpResponse != nil {
			var readErr error
			resp, readErr = ioutil.ReadAll(httpResponse.Body)
			if readErr != nil {
				return errors.New("Unable to read websocket connection: " + readErr.Error() + ", " + err.Error())
			}
			// If there's a response, we can try to unmarshal it into one of the
			// modeled error types
			possibleError, _, decodeErr := DecodeData(resp, cs.TypeDecoder)
			if decodeErr == nil {
				return cs.NewError(possibleError)
			}
		}
		log.Warn("Error creating a websocket client", "err", err)
		return errors.New(string(resp) + ", " + err.Error())
	}
	cs.Conn = websocketConn
	return nil
}
Ejemplo n.º 2
0
// New returns a client/server to bidirectionally communicate with the backend.
// The returned struct should have both 'Connect' and 'Serve' called upon it
// before being used.
func New(url string, region string, credentialProvider credentials.AWSCredentialProvider, acceptInvalidCert bool, statsEngine stats.Engine, publishMetricsInterval time.Duration) wsclient.ClientServer {
	cs := &clientServer{
		statsEngine:            statsEngine,
		publishTicker:          nil,
		publishMetricsInterval: publishMetricsInterval,
		signer:                 authv4.NewHttpSigner(region, wsclient.ServiceName, credentialProvider, nil),
	}
	cs.URL = url
	cs.Region = region
	cs.CredentialProvider = credentialProvider
	cs.AcceptInvalidCert = acceptInvalidCert
	cs.ServiceError = &tcsError{}
	cs.RequestHandlers = make(map[string]wsclient.RequestHandler)
	cs.TypeDecoder = &TcsDecoder{}
	return cs
}
Ejemplo n.º 3
0
func (cs *clientServer) signRequest(payload []byte) []byte {
	signer := authv4.NewHttpSigner(cs.Region, "ecs", cs.CredentialProvider, nil)
	reqBody := bytes.NewBuffer(payload)
	// NewRequest never returns an error if the url parses and we just verified
	// it did above
	request, _ := http.NewRequest("GET", cs.URL, reqBody)
	signer.SignHttpRequest(request)

	var data []byte
	for k, vs := range request.Header {
		for _, v := range vs {
			data = append(data, k...)
			data = append(data, ": "...)
			data = append(data, v...)
			data = append(data, "\r\n"...)
		}
	}
	data = append(data, "\r\n"...)
	data = append(data, payload...)

	return data
}