jenkinsci / java-client-api

A Jenkins API client for Java
MIT License
896 stars 468 forks source link

inputstream and ByteArrayOutputStream should be close when we finished request in getFileFromWorkspace #487

Closed XWTiger closed 2 years ago

XWTiger commented 2 years ago

Version report

Jenkins and plugins versions report:

0.3.9 snapshot, i just forked code in my project and compile it with master branch
when i request getFileFromWorkspace the third time, i found the request are locked

Reproduction steps

Results

Expected result: if found the code stream was not be closed

public String getFileFromWorkspace(String fileName) throws IOException {
        InputStream is = client.getFile(URI.create(url + "/ws/" + fileName));
        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = is.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }
        return result.toString("UTF-8");
    }

Actual result: i think it should be like this

public String getFileFromWorkspace(String fileName) throws IOException {
        InputStream is = client.getFile(URI.create(url + "/ws/" + fileName));
        ByteArrayOutputStream result = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = is.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            is.close();

            return result.toString("UTF-8");
        } finally {
            result.close();
        }
    }
XWTiger commented 2 years ago

i found the response should close too

@Override public InputStream getFile(URI path) throws IOException { CloseableHttpResponse response = null; try { HttpGet getMethod = new HttpGet(path); response = client.execute(getMethod, localContext); jenkinsVersion = ResponseUtils.getJenkinsVersion(response); httpResponseValidator.validateResponse(response); return new RequestReleasingInputStream(response.getEntity().getContent(), getMethod); } finally { response.close(); }

}
XWTiger commented 2 years ago

i think it is better add timeout configuration to jenkins client

public JenkinsHttpClient(URI uri, HttpClientBuilder builder) { this(uri, initTimeOut(builder)); }

protected static CloseableHttpClient initTimeOut(HttpClientBuilder builder) {
    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectionRequestTimeout(6000)
            .setConnectTimeout(6000)
            .setSocketTimeout(6000)
            .build();
    CloseableHttpClient httpClient = builder.setMaxConnTotal(50).setMaxConnPerRoute(1000).setDefaultRequestConfig(requestConfig).build();
    return httpClient;
}