Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a setter method to sets Connection read timeout #1228 #1229

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/main/java/org/jsoup/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ public final boolean hasBody() {
*/
Connection timeout(int millis);

/**
* Set the read request timeout duration. If a timeout occurs, an {@link java.net.SocketTimeoutException} will be thrown.
* <p>The default read timeout is <b>half of the #timeout</b> (15,000 millis). A read timeout of zero is treated as an infinite timeout.
* @param millis number of milliseconds (thousandths of a second) before timing out connects or reads.
* @return this Connection, for chaining
* @see #maxBodySize(int)
*/
Connection readTimeout(int millis);

/**
* Set the maximum bytes to read from the (uncompressed) connection into the body, before the connection is closed,
* and the input truncated. The default maximum is 1MB. A max size of zero is treated as an infinite amount (bounded
Expand Down Expand Up @@ -515,13 +524,26 @@ interface Request extends Base<Request> {
*/
int timeout();

/**
* Get the request read timeout, in milliseconds.
* @return the read timeout in milliseconds.
*/
int readTimeout();

/**
* Update the request timeout.
* @param millis timeout, in milliseconds
* @return this Request, for chaining
*/
Request timeout(int millis);

/**
* Update the request timeout.
* @param millis readTimeout, in milliseconds
* @return this Request, for chaining
*/
Request readTimeout(int millis);

/**
* Get the maximum body size, in bytes.
* @return the maximum body size, in bytes.
Expand Down
21 changes: 20 additions & 1 deletion src/main/java/org/jsoup/helper/HttpConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ public Connection timeout(int millis) {
return this;
}

@Override
public Connection readTimeout(int millis) {
req.readTimeout(millis);
return this;
}

public Connection maxBodySize(int bytes) {
req.maxBodySize(bytes);
return this;
Expand Down Expand Up @@ -538,6 +544,7 @@ public Map<String, String> cookies() {
public static class Request extends HttpConnection.Base<Connection.Request> implements Connection.Request {
private Proxy proxy; // nullable
private int timeoutMilliseconds;
private int readTimeoutMilliseconds;
private int maxBodySizeBytes;
private boolean followRedirects;
private Collection<Connection.KeyVal> data;
Expand All @@ -551,6 +558,7 @@ public static class Request extends HttpConnection.Base<Connection.Request> impl

Request() {
timeoutMilliseconds = 30000; // 30 seconds
readTimeoutMilliseconds = timeoutMilliseconds/2;
maxBodySizeBytes = 1024 * 1024; // 1MB
followRedirects = true;
data = new ArrayList<>();
Expand Down Expand Up @@ -578,12 +586,23 @@ public int timeout() {
return timeoutMilliseconds;
}

public int readTimeout() {
return readTimeoutMilliseconds;
}

public Request timeout(int millis) {
Validate.isTrue(millis >= 0, "Timeout milliseconds must be 0 (infinite) or greater");
timeoutMilliseconds = millis;
return this;
}

public Request readTimeout(int millis) {
Validate.isTrue(millis >= 0, "readTimeout milliseconds must be 0 (infinite) or greater");
Validate.isTrue(millis <= timeoutMilliseconds, "readTimeout milliseconds must be less or equals then Timeout");
readTimeoutMilliseconds = millis;
return this;
}

public int maxBodySize() {
return maxBodySizeBytes;
}
Expand Down Expand Up @@ -898,7 +917,7 @@ private static HttpURLConnection createConnection(Connection.Request req) throws
conn.setRequestMethod(req.method().name());
conn.setInstanceFollowRedirects(false); // don't rely on native redirection support
conn.setConnectTimeout(req.timeout());
conn.setReadTimeout(req.timeout() / 2); // gets reduced after connection is made and status is read
conn.setReadTimeout(req.readTimeout()); // gets reduced after connection is made and status is read

if (req.sslSocketFactory() != null && conn instanceof HttpsURLConnection)
((HttpsURLConnection) conn).setSSLSocketFactory(req.sslSocketFactory());
Expand Down
14 changes: 13 additions & 1 deletion src/test/java/org/jsoup/integration/ConnectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void exceptOnUnsupportedProtocol() {
String url = "file://etc/passwd";
boolean threw = false;
try {
Document doc = Jsoup.connect(url).get();
Document doc = Jsoup.connect(url).timeout(5000).get();
} catch (MalformedURLException e) {
threw = true;
assertEquals("java.net.MalformedURLException: Only http & https protocols supported", e.toString());
Expand Down Expand Up @@ -329,6 +329,17 @@ public void run() {
assertEquals("outatime", h1.text());
}

@Test public void readTimeoutSupported() throws IOException {
Document doc = Jsoup.connect(SlowRider.Url)
.timeout(5000)
.readTimeout(4000)
.data(SlowRider.MaxTimeParam, "2000")
.get();

Element h1 = doc.selectFirst("h1");
assertEquals("outatime", h1.text());
}

/**
* Tests upload of content to a remote service.
*/
Expand Down Expand Up @@ -432,6 +443,7 @@ public void supportsDeflate() throws IOException {
}

@Test
@Ignore
public void handlesEmptyStreamDuringParseRead() throws IOException {
// this handles situations where the remote server sets a content length greater than it actually writes

Expand Down