You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: ob_http.go
    path of file: ./repos/hysteria/extras/outbounds
    
    the code of the file until where you have to start completion: package outbounds

import (
	"bufio"
	"bytes"
	"crypto/tls"
	"encoding/base64"
	"errors"
	"fmt"
	"io"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

const (
	httpRequestTimeout = 10 * time.Second
    
func (o *httpOutbound) TCP(reqAddr *AddrEx) (net.Conn, error) {
	req, err := o.addrExToRequest(reqAddr)
	if err != nil {
		return nil, err
	}
	conn, err := o.dial()
	if err != nil {
		return nil, err
	}
	if err := req.Write(conn); err != nil {
		_ = conn.Close()
		return nil, err
	}
	if err := conn.SetDeadline(time.Now().Add(httpRequestTimeout)); err != nil {
		_ = conn.Close()
		return nil, err
	}
	bufReader := bufio.NewReader(conn)
	resp, err := http.ReadResponse(bufReader, req)
	if resp != nil {
		// Don't need response body here.
		_ = resp.Body.Close()
	}
	if err != nil {
		_ = conn.Close()
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		_ = conn.Close()
		return nil, errHTTPRequestFailed{resp.StatusCode}
	}
	if err := conn.SetDeadline(time.Time{}); err != nil {
		_ = conn.Close()
		return nil, err
	}
	if bufReader.Buffered() > 0 {
		// There is still data in the buffered reader.
		// We need to get it out and put it into a cachedConn,
		// so that handleConnect can read it.
		data := make([]byte, bufReader.Buffered())
		_, err := io.ReadFull(bufReader, data)
		if err != nil {
			// Read from buffer failed, is this possible?
			_ = conn.Close()
			return nil, err
		}
		cachedConn := &cachedConn{
			Conn:   conn,
			Buffer: *bytes.NewBuffer(data),
		}
		return cachedConn, nil
	} else {
		return conn, nil
	}
}