Following the recent merge of PR #3502 for LDEV-5387, Tom Chiverton commented on Jira:
“Does this PR cause a double GET ? I don’t see it saving the response from the fall back GET to be used later”
Looking at HTTPResource.java, Tom’s concern is valid — and depending on the operation, it can trigger up to 3 separate GET requests and 2 HEAD requests for a single tag/function call.
Where it happens
In core/.../HTTPResource.java:
if (rejectsHead(code)) {
HTTPResponse rsp = null;
try {
rsp = HTTPEngine4Impl.get(url, data.username, data.password, _getTimeout(), true, null, data.userAgent, pd, null);
code = rsp.getStatusCode();
}
finally {
HTTPEngine.closeEL(rsp); // <--- Closed and discarded immediately
}
}
headStatusCode = code;
return code;
The fallback GET in getStatusCode() reads the status, closes the connection in finally, and only records headStatusCode = code. Crucially, it does not assign rsp to this.http.
The request traces
-
fileRead(url):ResourceUtil.toResourceExisting()→res.exists()→getStatusCode():- Request 1 (HEAD): returns 403 / 405.
- Request 2 (GET #1): fallback GET in
getStatusCode()to confirm status, immediately closed.
res.getInputStream()→ callsgetHTTPResponse(true):- Request 3 (GET #2): brand-new GET over the wire to pull the stream.
- Total: 1 HEAD + 2 GETs
-
<cfcontent file="url">:toResourceExisting()→exists():- Request 1 (HEAD) (fails 403)
- Request 2 (GET #1) (fallback in
getStatusCode(), closed)
file.getContentType()(iftypeomitted):- Checks
if (http == null)→ Request 3 (HEAD #2) (still fails 403)
- Checks
file.length():- Calls
getHTTPResponse(false). Sincehttp == null, fires Request 4 (GET #2), reads length, and closes infinally.
- Calls
file.getInputStream():- Calls
getHTTPResponse(true), firing Request 5 (GET #3) to stream the response.
- Calls
- Total: 2 HEADs + 3 GETs
Why the test missed it
In test/tickets/LDEV5387.cfc, the mock server tracks requests via attributes.requests.add(method & " " & path), but the spec only asserts:
expect( trim( result.fileContent ) ).toBe( "LDEV-5387" );
There are no assertions checking arrayLen(attributes.requests) or verifying that only a single GET is issued.
Questions for the team / bot
- Can we update
HTTPResourceto preservethis.httpwhen the fallback GET succeeds, rather than closing it ingetStatusCode()? - How should
HTTPResource.getInputStream()handle reuse vs recreation (currently hardcoded asgetHTTPResponse(true)) when an open response stream already exists on the resource? - Could we add a request-count assertion to
test/tickets/LDEV5387.cfcto prevent multi-request regressions going forward? - is @GianTschingt configured to see replies on jira tickets? I also sent a PM on this forum but it wasn’t read, afaik.