Example #1
0
// getRoute is a utility function for making the web request to a route.
// Protocol is one of http, https, ws, or wss.  If the protocol is https or wss,
// then getRoute will make a secure transport client with InsecureSkipVerify:
// true.  If the protocol is http or ws, then getRoute does an unencrypted HTTP
// client request.  If the protocol is ws or wss, then getRoute will upgrade the
// connection to websockets and then send expectedResponse *to* the route, with
// the expectation that the route will echo back what it receives.  Note that
// getRoute returns only the first len(expectedResponse) bytes of the actual
// response.
func getRoute(routerUrl string, hostName string, protocol string, headers map[string]string, expectedResponse string) (response string, err error) {
	url := protocol + "://" + routerUrl
	var tlsConfig *tls.Config

	if protocol == "https" || protocol == "wss" {
		tlsConfig = &tls.Config{
			InsecureSkipVerify: true,
			ServerName:         hostName,
		}
	}

	switch protocol {
	case "http", "https":
		httpClient := &http.Client{Transport: &http.Transport{
			TLSClientConfig: tlsConfig,
		},
		}
		req, err := http.NewRequest("GET", url, nil)

		if err != nil {
			return "", err
		}

		for name, value := range headers {
			req.Header.Set(name, value)
		}

		req.Host = hostName
		resp, err := httpClient.Do(req)
		if err != nil {
			return "", err
		}
		defer resp.Body.Close()
		respBody, err := ioutil.ReadAll(resp.Body)
		return string(respBody), err

	case "ws", "wss":
		origin := fmt.Sprintf("http://%s/", tr.GetDefaultLocalAddress())
		wsConfig, err := websocket.NewConfig(url, origin)
		if err != nil {
			return "", err
		}

		port := 80
		if protocol == "wss" {
			port = 443
		}
		wsConfig.Location.Host = fmt.Sprintf("%s:%d", hostName, port)
		wsConfig.TlsConfig = tlsConfig

		ws, err := websocket.DialConfig(wsConfig)
		if err != nil {
			return "", err
		}

		_, err = ws.Write([]byte(expectedResponse))
		if err != nil {
			return "", err
		}

		var msg = make([]byte, len(expectedResponse))
		_, err = ws.Read(msg)
		if err != nil {
			return "", err
		}

		return string(msg), nil
	}

	return "", errors.New("Unrecognized protocol in getRoute")
}
Example #2
0
// getRoute is a utility function for making the web request to a route.
// Protocol is one of http, https, ws, or wss.  If the protocol is https or wss,
// then getRoute will make a secure transport client with InsecureSkipVerify:
// true.  If the protocol is http or ws, then getRoute does an unencrypted HTTP
// client request.  If the protocol is ws or wss, then getRoute will upgrade the
// connection to websockets and then send expectedResponse *to* the route, with
// the expectation that the route will echo back what it receives.  Note that
// getRoute returns only the first len(expectedResponse) bytes of the actual
// response.
func getRoute(routerUrl string, hostName string, protocol string, headers map[string]string, expectedResponse string) (response string, err error) {
	url := protocol + "://" + routerUrl
	var tlsConfig *tls.Config

	routerAddress := getRouteAddress()
	dialer := func(network, addr string) (net.Conn, error) {
		if _, port, err := net.SplitHostPort(addr); err == nil {
			return net.Dial(network, fmt.Sprintf("%s:%s", routerAddress, port))
		}
		return net.Dial(network, fmt.Sprintf("%s:%s", routerAddress, "80"))
	}
	tlsDialer := func(network, addr string, config *tls.Config) (*tls.Conn, error) {
		if _, port, err := net.SplitHostPort(addr); err == nil {
			return tls.Dial(network, fmt.Sprintf("%s:%s", routerAddress, port), config)
		}
		return tls.Dial(network, fmt.Sprintf("%s:%s", routerAddress, "443"), config)
	}

	if protocol == "https" || protocol == "wss" {
		tlsConfig = &tls.Config{
			InsecureSkipVerify: true,
			ServerName:         hostName,
		}
	}

	switch protocol {
	case "http", "https":
		httpClient := &http.Client{Transport: knet.SetTransportDefaults(&http.Transport{
			Dial:            dialer,
			TLSClientConfig: tlsConfig,
		}),
		}
		req, err := http.NewRequest("GET", url, nil)

		if err != nil {
			return "", err
		}

		for name, value := range headers {
			req.Header.Set(name, value)
		}

		req.Host = hostName
		resp, err := httpClient.Do(req)
		if err != nil {
			return "", err
		}
		defer resp.Body.Close()
		switch {
		case resp.StatusCode == 503:
			return "", ErrUnavailable
		case resp.StatusCode == 401:
			return "", ErrUnauthenticated
		case resp.StatusCode >= 400:
			return "", fmt.Errorf("GET of %s returned: %d", url, resp.StatusCode)
		}
		respBody, err := ioutil.ReadAll(resp.Body)
		cookies := resp.Cookies()
		for _, cookie := range cookies {
			if len(cookie.Name) != 32 || len(cookie.Value) != 32 {
				return "", fmt.Errorf("GET of %s returned bad cookie %s=%s", url, cookie.Name, cookie.Value)
			}
		}
		return string(respBody), err

	case "ws", "wss":
		origin := fmt.Sprintf("http://%s/", tr.GetDefaultLocalAddress())
		wsConfig, err := websocket.NewConfig(url, origin)
		if err != nil {
			return "", err
		}

		port := 80
		if protocol == "wss" {
			port = 443
		}
		if _, _, err := net.SplitHostPort(hostName); err == nil {
			wsConfig.Location.Host = hostName
		} else {
			wsConfig.Location.Host = fmt.Sprintf("%s:%d", hostName, port)
		}

		var conn net.Conn
		if tlsConfig == nil {
			conn, err = dialer("tcp", wsConfig.Location.Host)
		} else {
			conn, err = tlsDialer("tcp", wsConfig.Location.Host, tlsConfig)
		}
		if err != nil {
			return "", err
		}
		ws, err := websocket.NewClient(wsConfig, conn)
		if err != nil {
			if err == websocket.ErrBadStatus {
				return "", ErrUnavailable
			}
			return "", err
		}

		_, err = ws.Write([]byte(expectedResponse))
		if err != nil {
			return "", err
		}

		var msg = make([]byte, len(expectedResponse))
		_, err = ws.Read(msg)
		if err != nil {
			return "", err
		}

		return string(msg), nil
	}

	return "", errors.New("Unrecognized protocol in getRoute")
}
Example #3
0
// getRoute is a utility function for making the web request to a route.
// Protocol is one of http, https, ws, or wss.  If the protocol is https or wss,
// then getRoute will make a secure transport client with InsecureSkipVerify:
// true.  If the protocol is http or ws, then getRoute does an unencrypted HTTP
// client request.  If the protocol is ws or wss, then getRoute will upgrade the
// connection to websockets and then send expectedResponse *to* the route, with
// the expectation that the route will echo back what it receives.  Note that
// getRoute returns only the first len(expectedResponse) bytes of the actual
// response.
func getRoute(routerUrl string, hostName string, protocol string, headers map[string]string, expectedResponse string) (response string, err error) {
	url := protocol + "://" + routerUrl
	var tlsConfig *tls.Config

	if protocol == "https" || protocol == "wss" {
		tlsConfig = &tls.Config{
			InsecureSkipVerify: true,
			ServerName:         hostName,
		}
	}

	switch protocol {
	case "http", "https":
		httpClient := &http.Client{Transport: knet.SetTransportDefaults(&http.Transport{
			TLSClientConfig: tlsConfig,
		}),
		}
		req, err := http.NewRequest("GET", url, nil)

		if err != nil {
			return "", err
		}

		for name, value := range headers {
			req.Header.Set(name, value)
		}

		req.Host = hostName
		resp, err := httpClient.Do(req)
		if err != nil {
			return "", err
		}
		defer resp.Body.Close()
		switch {
		case resp.StatusCode == 503:
			return "", ErrUnavailable
		case resp.StatusCode == 401:
			return "", ErrUnauthenticated
		case resp.StatusCode >= 400:
			return "", fmt.Errorf("GET of %s returned: %d", url, resp.StatusCode)
		}
		respBody, err := ioutil.ReadAll(resp.Body)
		return string(respBody), err

	case "ws", "wss":
		origin := fmt.Sprintf("http://%s/", tr.GetDefaultLocalAddress())
		wsConfig, err := websocket.NewConfig(url, origin)
		if err != nil {
			return "", err
		}

		port := 80
		if protocol == "wss" {
			port = 443
		}
		wsConfig.Location.Host = fmt.Sprintf("%s:%d", hostName, port)
		wsConfig.TlsConfig = tlsConfig

		ws, err := websocket.DialConfig(wsConfig)
		if err != nil {
			if derr, ok := err.(*websocket.DialError); ok {
				if derr.Err == websocket.ErrBadStatus {
					// a better websocket library would know the difference here
					return "", ErrUnavailable
				}
			}
			return "", err
		}

		_, err = ws.Write([]byte(expectedResponse))
		if err != nil {
			return "", err
		}

		var msg = make([]byte, len(expectedResponse))
		_, err = ws.Read(msg)
		if err != nil {
			return "", err
		}

		return string(msg), nil
	}

	return "", errors.New("Unrecognized protocol in getRoute")
}