foundeo / bolthttp Goto Github PK
View Code? Open in Web Editor NEWA HTTP Client for CFML
License: Apache License 2.0
A HTTP Client for CFML
License: Apache License 2.0
Hey, Pete. Great work with this project. Thanks so much. But I was recommending it again to someone today, and they happened to have the CF Admin feature checked for "disable access to internal coldfusion java components", and this failed. Well, it gets this error:
The error occurred in D:/ColdFusion2018/cfusion/wwwroot/test/bolthttp/javaloader/JavaProxy.cfc: line 34Called from D:/ColdFusion2018/cfusion/wwwroot/test/bolthttp/javaloader/JavaLoader.cfc: line 449Called from D:/ColdFusion2018/cfusion/wwwroot/test/bolthttp/javaloader/JavaLoader.cfc: line 252Called from D:/ColdFusion2018/cfusion/wwwroot/test/bolthttp/javaloader/JavaLoader.cfc: line 50Called from D:/ColdFusion2018/cfusion/wwwroot/test/bolthttp/bolthttp.cfc: line 207Called from D:/ColdFusion2018/cfusion/wwwroot/test/bolthttp/bolthttp.cfc: line 7Called from D:/ColdFusion2018/cfusion/wwwroot/test/test-bolthttp.cfm: line 10
32 : 33 : var classLoader = createObject("java", "java.lang.ClassLoader").getSystemClassLoader(); 34 : var objectClass = classLoader.loadClass("java.lang.Object");
`
And clearly it's a havaloader issue. In fact the problem was raised there also in 2017, but there's been no movement on it.
Someone might helpfully want to point to a 2019 blog post from Ben N where he also observed the problem with Java loader (and that Admin setting). And a commenter there (Mark) proposed that a jvm arg helped him:
--add-exports=java.base/jdk.internal.loader=ALL-UNNAMED
But sadly that did NOT help for me, with bolthttp, on CF2018 or 2021 (both running Java 11). (And the --add-exports is not supported by Java 8, so downgrading to that was not the way to get that arg to "work".
Of course, turning off the admin setting (which is enabled by default with the "secure profile" in CF) may be an option for some.
But for those who cannot, I wanted to raise this issue here in case you, Pete, or anyone else may have another suggestion to allow it to work. I realize it's a rather dormant project, and it does at least work great otherwise. Again, thanks so much for it.
There seems to be a change in the underlying httpclient, causing an error.
When I ran the tool passing in an arrayelement of connectrequesttimeout (as indicated in the readme and the code), it failed saying it was invalid. I looked and found that the method for the underlying requestbuilder is instead connect_ion_requesttimeout. I gather perhaps the httpclient api has changed over time.
I could have proposed a PR, but it would seem you may want to handle things any of several ways, from adding a new arg, to letting the old arg work (for backward compat) but have the code pass it as the value to the new arg, or perhaps determine what to do via a try/catch based on what the underlying httpclient class supports, or creating a different version of the CFC that might be version-specific and called dynamically based on detection of a new httpclient class. I just didn't want to presume any particular implementation that may appeal to you or not. :-)
So I'll leave it here for consideration by you or others.
We've noticed a problem with bolthttp when a request is made to a server running mod_cfml to create dynamic Tomcat contexts.
The issue is that mod_cfml will issue a redirect (hopefully a 307) to force the client to retry to request.
You can work around this by enabling redirects on a request, but in our case we explicitly are not following redirects because a 301 or 302 is a sign of a problem.
It would appear this issue can be solved in Apache HttpClient by implementing a redirect strategy. I'm wondering if it would make sense to add support for configuring BoltHTTP to only follow specific redirect commands or at least potentially always honor a 307 redirect, since this seems to be specifically for these kinds of operations (where an HTTP request must be retried).
While implementing this library to work around some timeout issues calling HTTP in a thread, I ran into some exceptions being thrown because the parameters where not being interpreted as strings.
I've submitted a pull request to address this by adding javaCast('string', xxx)
around values being sent to the Apache methods that expect a string.
I am running test/run.cfm installed on ColdFusion Enterprise Edition 9,0,2,282541 Java: 1.7.0_80 .
The TLS 1.2 test is failing.
TLS 1.2 / Mozilla Modern Configuration
GET https://mozilla-modern.badssl.com/
FAIL: Expected 200 got exception: Received fatal alert: handshake_failure
While working on replacing CFHTTP with BoltHTTP, I needed to replicate the throwOnError
option of CFHTTP, so I wanted to share this service layer function I wrote in case it helps anyone else. All it does is capture exceptions and if the throwOnError
is false, remaps the exceptions to match what CFHTTP returns on similar errors.
I thought it worth sharing since it took a little trial and error to figure out the various exceptions and remap them.
/**
* @hint Generates an HTTP request using the BoltHttp client.
*
* @url The URL for the HTTP request.
* @method The method for the HTTP request.
* @params An array of CFHTTP-like parameters to supply to the BoltHttp client.
* @options An struct of options to pass to the BoltHttp client.
* @config Overrides the default configuration for the BoltHttp client.
* @throwOnError Determines if we should try to ignore errors an HTTP issue occurs. This is to mimic the CFHTTP throwOnError feature.
*/
public struct function http(string url, string method="GET", array params=[], struct options={}, struct config={}, boolean throwOnError=true) output="false" {
var boltClient = new rootcom.thirdparty.bolthttp.bolthttp(arguments.config);
try {
return boltClient.request(
url=arguments.url
, method=arguments.method
, params=arguments.params
, options=arguments.options
);
} catch( Any e ){
/*
We want to mimic CFHTTP's throwOnError flag, which will not throw hard errors when a
HTTP issue occurs, but instead returns a standard response.
*/
if( !arguments.throwOnError ){
switch( e.type ){
/*
These errors happen when the "connectTimeout" has been reached and the
host could not be reached.
*/
case "org.apache.http.conn.ConnectTimeoutException":
case "java.net.NoRouteToHostException":
return {
"ErrorDetail"="I/O Exception: No route to host (Host unreachable)"
, "Mimetype"="Unable to determine MIME type of file."
, "Statuscode"="Connection Failure. Status code unavailable."
, "Filecontent"="Connection Failure"
, "Responseheader"={}
, "Text"=true
, "Charset"=""
, "Header"=""
};
/*
These errors happen when the "socketTimeout" has been reached and a connection
to the host occurred, but the server did not respond within a timely manor.
*/
case "java.net.SocketTimeoutException":
return {
"ErrorDetail"=""
, "Mimetype"="Unable to determine MIME type of file."
, "Statuscode"="408 Request Time-out"
, "Filecontent"="Connection Timeout"
, "Responseheader"={}
, "Text"=true
, "Charset"=""
, "Header"=""
};
/*
These errors happen when the host name is invalid.
*/
case "java.net.UnknownHostException":
var requestedUrl = createObject("java", "java.net.URL").init(javaCast("string", arguments.url));
return {
"ErrorDetail"="Unknown host: #requestedUrl.getHost()#: Name or service not known"
, "Mimetype"="Unable to determine MIME type of file."
, "Statuscode"="Connection Failure. Status code unavailable."
, "Filecontent"="Connection Failure"
, "Responseheader"={}
, "Text"=true
, "Charset"=""
, "Header"=""
};
}
}
rethrow;
}
}
I'm not sure if this is worth refactoring into the code or just documented in. It could be easily refactored into a requestNoError()
or safeRequest()
helper, or even adding as an attribute to the request method.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.