使用golang终止来自IP层的http请求

时间:2018-06-05 07:34:29

标签: http go tcp

我正在使用golang向服务器发出http post请求。假设服务器当前已关闭(表示服务器运行的机器已关闭),则请求将停留在IP层。所以我的程序执行无法继续进行。它无法进入应用程序层。那么golang有什么方法可以阻止它。 我使用以下代码。

req, err := http.NewRequest("POST", url, bytes.NewReader(b))
       if err != nil {
               return errors.Wrap(err, "new request error")
       }
resp, err := http.DefaultClient.Do(req)
       if err != nil {
               return errors.Wrap(err, "http request error")
       }
       defer resp.Body.Close()

是否可以添加任何内容,以便在请求无法从IP层找到任何内容时终止请求。

3 个答案:

答案 0 :(得分:2)

默认的http客户端没有超时。您可以自己创建一个显式的http.Client并设置超时:

var cl = &http.Client{
    Timeout: time.Second * 10,
}

resp, err := cl.Do(req)

if err != nil {
    // err will be set on timeout
    return errors.Wrap(err, "http request error")
}
defer resp.Body.Close()

如果服务器在请求中间不再应答,则可以处理超时。

答案 1 :(得分:1)

在这种情况下,运输@kostix指的是你正在寻找的。运输和客户也可以安全地同时使用。但请read about the Transport(我也建议阅读有关客户端的内容),因为有许多不同的方法可以影响您处理空闲连接的方式,而不仅仅是前面提到的DialContext。

您可能想要设置ResponseHeaderTimeout

  

ResponseHeaderTimeout,如果非零,则指定数量     完全等待服务器响应头的时间     写请求(包括其正文,如果有的话)。这个     时间不包括阅读回应正文的时间。

或者,如果您使用的是安全连接,则可能需要设置TLSHandshakeTimeout

  

TLSHandshakeTimeout指定等待的最长时间     等待TLS握手。零意味着没有超时。

为了便于阅读和维护,我建议也可以创建一个构建客户端的功能,类似于:

func buildClient(timeout time.Duration) *http.Client {
    tr := &http.Transport{
        IdleConnTimeout:       timeout,
        ResponseHeaderTimeout: timeout,
        TLSHandshakeTimeout:   timeout,
    }
    client := &http.Client{
        Transport: tr,
        Timeout:   timeout,
    }
    return client
}

答案 2 :(得分:0)

使用非http.Transport的{​​{1}}字段设置为一个函数,该函数使用具有正确配置的超时/截止时间的自定义上下文。另一种选择是使用自定义DialContext

这样的事情:

net.Dialer

请注意,根据cli := http.Client{ Transport: &http.Transport{ DialContext: func (ctx context.Context, network, address string) (net.Conn, error) { dialer := net.Dialer{ Timeout: 3 * time.Second, } return dialer.DialContext(ctx, network, address) }, }, } req, err := http.NewRequest(...) resp, err := cli.Do(req) 的文档,传递给其net.Dialer的上下文可能胜过拨号器本身设置的超时 - 这是 正是我们需要的:拨号器的DialContext字段完全控制 “拨号”(TCP连接建立),你也可以武装你的 带有上下文(使用Timeout)控制的HTTP请求 整个请求的超时,也可以随时取消(包括拨号步骤)。

Playground example