Example #1
0
func (c *Client) hijack(method, path string, setRawTerminal bool, in io.Reader, stderr, stdout io.Writer) error {
	if path != "/version" && !c.SkipServerVersionCheck && c.expectedApiVersion == nil {
		err := c.checkApiVersion()
		if err != nil {
			return err
		}
	}
	req, err := http.NewRequest(method, c.getURL(path), nil)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "plain/text")
	protocol := c.endpointURL.Scheme
	address := c.endpointURL.Path
	if protocol != "unix" {
		protocol = "tcp"
		address = c.endpointURL.Host
	}
	dial, err := net.Dial(protocol, address)
	if err != nil {
		return err
	}
	defer dial.Close()
	clientconn := httputil.NewClientConn(dial, nil)
	clientconn.Do(req)
	rwc, br := clientconn.Hijack()
	var wg sync.WaitGroup
	wg.Add(2)
	errs := make(chan error, 2)
	go func() {
		var err error
		if setRawTerminal {
			_, err = io.Copy(stdout, br)
		} else {
			_, err = utils.StdCopy(stdout, stderr, br)
		}
		errs <- err
		wg.Done()
	}()
	go func() {
		var err error
		if in != nil {
			_, err = io.Copy(rwc, in)
		}
		rwc.(interface {
			CloseWrite() error
		}).CloseWrite()
		errs <- err
		wg.Done()
	}()
	wg.Wait()
	close(errs)
	if err := <-errs; err != nil {
		return err
	}
	return nil
}
Example #2
0
func (c *Client) hijack(method, path string, success chan struct{}, in io.Reader, errStream io.Writer, out io.Writer) error {
	req, err := http.NewRequest(method, c.getURL(path), nil)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "plain/text")
	protocol := c.endpointURL.Scheme
	address := c.endpointURL.Path
	if protocol != "unix" {
		protocol = "tcp"
		address = c.endpointURL.Host
	}
	dial, err := net.Dial(protocol, address)
	if err != nil {
		return err
	}
	defer dial.Close()
	clientconn := httputil.NewClientConn(dial, nil)
	clientconn.Do(req)
	if success != nil {
		success <- struct{}{}
		<-success
	}
	rwc, br := clientconn.Hijack()
	var wg sync.WaitGroup
	wg.Add(2)
	errs := make(chan error, 2)
	go func() {
		var err error
		if in != nil {
			_, err = io.Copy(out, br)
		} else {
			_, err = utils.StdCopy(out, errStream, br)
		}
		errs <- err
		wg.Done()
	}()
	go func() {
		var err error
		if in != nil {
			_, err = io.Copy(rwc, in)
		}
		rwc.(interface {
			CloseWrite() error
		}).CloseWrite()
		errs <- err
		wg.Done()
	}()
	wg.Wait()
	close(errs)
	if err := <-errs; err != nil {
		return err
	}
	return nil
}
Example #3
0
func (c *Client) hijack(method, path string, success chan struct{}, in io.Reader, errStream io.Writer, out io.Writer) error {
	req, err := http.NewRequest(method, c.getURL(path), nil)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "plain/text")
	protocol := c.endpointURL.Scheme
	address := c.endpointURL.Path
	if protocol != "unix" {
		protocol = "tcp"
		address = c.endpointURL.Host
	}
	dial, err := net.Dial(protocol, address)
	if err != nil {
		return err
	}
	defer dial.Close()
	clientconn := httputil.NewClientConn(dial, nil)
	clientconn.Do(req)
	if success != nil {
		success <- struct{}{}
		<-success
	}
	rwc, br := clientconn.Hijack()
	errStdout := make(chan error, 1)
	go func() {
		var err error
		if in != nil {
			_, err = io.Copy(out, br)
		} else {
			_, err = utils.StdCopy(out, errStream, br)
		}
		errStdout <- err
	}()
	go func() {
		if in != nil {
			io.Copy(rwc, in)
		}
		if err := rwc.(interface {
			CloseWrite() error
		}).CloseWrite(); err != nil && errStream != nil {
			fmt.Fprintf(errStream, "Couldn't send EOF: %s\n", err)
		}
	}()
	if err := <-errStdout; err != nil {
		return err
	}
	return nil
}
Example #4
0
func (c *Client) stream(method, path string, setRawTerminal bool, headers map[string]string, in io.Reader, stdout, stderr io.Writer) error {
	if (method == "POST" || method == "PUT") && in == nil {
		in = bytes.NewReader(nil)
	}
	if path != "/version" && !c.SkipServerVersionCheck && c.expectedApiVersion == nil {
		err := c.checkApiVersion()
		if err != nil {
			return err
		}
	}
	req, err := http.NewRequest(method, c.getURL(path), in)
	if err != nil {
		return err
	}
	req.Header.Set("User-Agent", userAgent)
	if method == "POST" {
		req.Header.Set("Content-Type", "plain/text")
	}
	for key, val := range headers {
		req.Header.Set(key, val)
	}
	var resp *http.Response
	protocol := c.endpointURL.Scheme
	address := c.endpointURL.Path
	if stdout == nil {
		stdout = ioutil.Discard
	}
	if stderr == nil {
		stderr = ioutil.Discard
	}
	if protocol == "unix" {
		dial, err := net.Dial(protocol, address)
		if err != nil {
			return err
		}
		clientconn := httputil.NewClientConn(dial, nil)
		resp, err = clientconn.Do(req)
		defer clientconn.Close()
	} else {
		resp, err = c.client.Do(req)
	}
	if err != nil {
		if strings.Contains(err.Error(), "connection refused") {
			return ErrConnectionRefused
		}
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode < 200 || resp.StatusCode >= 400 {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		return newError(resp.StatusCode, body)
	}
	if resp.Header.Get("Content-Type") == "application/json" {
		dec := json.NewDecoder(resp.Body)
		for {
			var m jsonMessage
			if err := dec.Decode(&m); err == io.EOF {
				break
			} else if err != nil {
				return err
			}
			if m.Stream != "" {
				fmt.Fprint(stdout, m.Stream)
			} else if m.Progress != "" {
				fmt.Fprintf(stdout, "%s %s\r", m.Status, m.Progress)
			} else if m.Error != "" {
				return errors.New(m.Error)
			}
			if m.Status != "" {
				fmt.Fprintln(stdout, m.Status)
			}
		}
	} else {
		if setRawTerminal {
			_, err = io.Copy(stdout, resp.Body)
		} else {
			_, err = utils.StdCopy(stdout, stderr, resp.Body)
		}
		return err
	}
	return nil
}
Example #5
0
func (c *Client) hijack(method, path string, success chan struct{}, setRawTerminal bool, in io.Reader, stderr, stdout io.Writer) error {
	if path != "/version" && !c.SkipServerVersionCheck && c.expectedApiVersion == nil {
		err := c.checkApiVersion()
		if err != nil {
			return err
		}
	}
	if stdout == nil {
		stdout = ioutil.Discard
	}
	if stderr == nil {
		stderr = ioutil.Discard
	}
	req, err := http.NewRequest(method, c.getURL(path), nil)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "plain/text")
	protocol := c.endpointURL.Scheme
	address := c.endpointURL.Path
	if protocol != "unix" {
		protocol = "tcp"
		address = c.endpointURL.Host
	}
	dial, err := net.Dial(protocol, address)
	if err != nil {
		return err
	}
	defer dial.Close()
	clientconn := httputil.NewClientConn(dial, nil)
	clientconn.Do(req)
	if success != nil {
		success <- struct{}{}
		<-success
	}
	rwc, br := clientconn.Hijack()
	errs := make(chan error, 2)
	exit := make(chan bool)
	go func() {
		defer close(exit)
		var err error
		if setRawTerminal {
			_, err = io.Copy(stdout, br)
		} else {
			_, err = utils.StdCopy(stdout, stderr, br)
		}
		errs <- err
	}()
	go func() {
		var err error
		if in != nil {
			_, err = io.Copy(rwc, in)
		}
		rwc.(interface {
			CloseWrite() error
		}).CloseWrite()
		errs <- err
	}()
	<-exit
	return <-errs
}