简体   繁体   中英

Jetty doesn't close connection

I've created a simple server Java application using Gradle. As an embedded server , I am using Jetty . I am also using a Gretty plugin as it supports the latest Jetty version.

The project runs just fine . And I have tried to stress test it. As a part of my test I need to check the response time and therefore I am sending "Connection:Close" header via curl .

My response is a long JSON string , and I see only part of it , after which the connection hangs . I would like to know Why is it happening , and how can I work around it.

NOTE :

  1. When sending Connection:Keep-alive header , everything is fine
  2. When response from the server is not a long string , but smaller . It works just fine (doesn't hang)
  3. Tried the standard Jetty plugin from gradle , the result was the same.

HOW TO TEST :

  1. Build and run my project from console ./gradlew appRun
  2. From bash console run curl -H "Connection:Close" -i "http://localhost:8080/Environment/example"
  3. See the partial response and the connection still alive...

Seems like you are confusing the persistent connection modes between HTTP/1.0 and HTTP/1.1 .

Either that, or you are using a really old version of curl that still defaults to HTTP/1.0 .

HTTP/1.0 has no persistent connections by default, so to use persistent connections we send Connection: keep-alive .

HTTP/1.1 uses persistent connections by default, so to disable it we can send Connection: close

Using HTTP/1.0 , with Connection: close is like sending this ...

GET /Environment/example HTTP/1.0
Host: localhost:8080
Connection: close

... which produces an invalid header value for Connection per the HTTP/1.0 spec

Lets use the verbose features of curl to see what's really going on Connection wise...

Example: HTTP/1.1 with normal operation:

$ curl --verbose --http1.1 http://apache.org/ -so /dev/null
*   Trying 88.198.26.2...
* Connected to apache.org (88.198.26.2) port 80 (#0)
> GET / HTTP/1.1
> Host: apache.org
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Fri, 06 May 2016 12:05:39 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Fri, 06 May 2016 11:10:20 GMT
< ETag: "cf64-5322a812896a8"
< Accept-Ranges: bytes
< Content-Length: 53092
< Vary: Accept-Encoding
< Cache-Control: max-age=3600
< Expires: Fri, 06 May 2016 13:05:39 GMT
< Content-Type: text/html
< 
{ [1125 bytes data]
* Connection #0 to host apache.org left intact

Notice that it says it kept the connection intact?

Example: HTTP/1.1 with manual Connection: close operation:

$ curl --verbose --http1.1 --header "Connection: close" http://apache.org/ -so /dev/null
*   Trying 140.211.11.105...
* Connected to apache.org (140.211.11.105) port 80 (#0)
> GET / HTTP/1.1
> Host: apache.org
> User-Agent: curl/7.43.0
> Accept: */*
> Connection: close
> 
< HTTP/1.1 200 OK
< Date: Fri, 06 May 2016 12:06:35 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Fri, 06 May 2016 11:10:20 GMT
< ETag: "cf64-5322a812896a8"
< Accept-Ranges: bytes
< Content-Length: 53092
< Vary: Accept-Encoding
< Cache-Control: max-age=3600
< Expires: Fri, 06 May 2016 13:06:35 GMT
< Connection: close
< Content-Type: text/html
< 
{ [1106 bytes data]
* Closing connection 0

Ah, the HTTP response headers say that the server will close, and curl saw the connection being closed. What we wanted.

Example: HTTP/1.0 with normal operation:

$ curl --verbose --http1.0 http://apache.org/ -so /dev/null
*   Trying 140.211.11.105...
* Connected to apache.org (140.211.11.105) port 80 (#0)
> GET / HTTP/1.0
> Host: apache.org
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Fri, 06 May 2016 12:08:27 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Fri, 06 May 2016 11:10:20 GMT
< ETag: "cf64-5322a812896a8"
< Accept-Ranges: bytes
< Content-Length: 53092
< Vary: Accept-Encoding
< Cache-Control: max-age=3600
< Expires: Fri, 06 May 2016 13:08:27 GMT
< Connection: close
< Content-Type: text/html
< 
{ [4002 bytes data]
* Closing connection 0

See how the HTTP response headers say that the server will close?

Curl also saw the connection being closed.

That's what we expect with normal HTTP/1.0 operation.

Example: HTTP/1.0 with persistent connection:

$ curl --verbose --http1.0 --header "Connection: keep-alive" http://apache.org/ -so /dev/null
*   Trying 88.198.26.2...
* Connected to apache.org (88.198.26.2) port 80 (#0)
> GET / HTTP/1.0
> Host: apache.org
> User-Agent: curl/7.43.0
> Accept: */*
> Connection: keep-alive
> 
< HTTP/1.1 200 OK
< Date: Fri, 06 May 2016 12:08:37 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Fri, 06 May 2016 11:10:20 GMT
< ETag: "cf64-5322a812896a8"
< Accept-Ranges: bytes
< Content-Length: 53092
< Vary: Accept-Encoding
< Cache-Control: max-age=3600
< Expires: Fri, 06 May 2016 13:08:37 GMT
< Keep-Alive: timeout=30, max=100
< Connection: Keep-Alive
< Content-Type: text/html
< 
{ [3964 bytes data]
* Connection #0 to host apache.org left intact

Yup, the server indicates that it will use Keep-Alive too (per HTTP/1.0 spec), and curl even concurs and says the connection is left intact.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM