HTTP Client Post Call

Hi All,

I am pretty new to using the Post Call method to post data. While I tried to use the httpClient function to post a request on the Boomi server, I got the following error saying the existing connection is forcibly closed by the remote host. Can anyone point me in the direction of why this error occurred? Here is my script:

    user = "user" 
	password = "password"
	info = {"ProductPartNumber" : " **** ", "FacilityPrefix" : "***", "SqlWhere": "*****"}
	url = "https://****.com/ws/rest/Ignition?messageType=GET_PRODUCT_SPEC"
	# Create the JythonHttpClient.
	client = system.net.httpClient(username=user, password=password, bypass_cert_validation = True)
	response = client.post(url, info)

Error:

	... 38 common frames omitted
Caused by: com.inductiveautomation.ignition.common.GenericTransferrableException: Unable to POST https://bil-boomi01dv.entegris.com/ws/rest/Ignition?messageType=GET_PRODUCT_SPEC?ProductPartNumber=+AEC010M1G3000T+&FacilityPrefix=LSP&SqlWhere=and+PRODUCT_SPEC.SPEC_TYPE+in+%28%27IC%27%2C%27TOC%27%2C%27LPC%27%29
	at com.inductiveautomation.ignition.common.script.builtin.http.JythonHttpClient.send(JythonHttpClient.java:103)
	at com.inductiveautomation.ignition.common.script.builtin.http.InsecureJythonHttpClient.send(InsecureJythonHttpClient.java:37)
	at com.inductiveautomation.ignition.common.script.builtin.http.JythonHttpClient.post(JythonHttpClient.java:318)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
	... 35 common frames omitted
Caused by: com.inductiveautomation.ignition.common.GenericTransferrableException: An existing connection was forcibly closed by the remote host
	at java.net.http/jdk.internal.net.http.HttpClientImpl.send(Unknown Source)
	at java.net.http/jdk.internal.net.http.HttpClientFacade.send(Unknown Source)
	at com.inductiveautomation.ignition.common.script.builtin.http.JythonHttpClient.send(JythonHttpClient.java:101)
	... 42 common frames omitted
Caused by: com.inductiveautomation.ignition.common.GenericTransferrableException: An existing connection was forcibly closed by the remote host
	at java.base/sun.nio.ch.SocketDispatcher.read0(Native Method)
	at java.base/sun.nio.ch.SocketDispatcher.read(Unknown Source)
	at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
	at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
	at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
	at java.base/sun.nio.ch.SocketChannelImpl.read(Unknown Source)
	at java.net.http/jdk.internal.net.http.SocketTube.readAvailable(Unknown Source)
	at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.read(Unknown Source)
	at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowTask.run(Unknown Source)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(Unknown Source)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(Unknown Source)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler.runOrSchedule(Unknown Source)
	at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.signalReadable(Unknown Source)
	at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$ReadEvent.signalEvent(Unknown Source)
	at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowEvent.handle(Unknown Source)
	at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.handleEvent(Unknown Source)
	at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.lambda$run$3(Unknown Source)
	at java.base/java.util.ArrayList.forEach(Unknown Source)
	at java.net.http/jdk.internal.net.http.HttpClientImpl$SelectorManager.run(Unknown Source)

Please make sure you format code correctly when posting using the </> button.
Try this

user = "user" 
password = "password" 
data = {"ProductPartNumber" : " **** ", "FacilityPrefix" : "***", "SqlWhere": "*****"} 
url = "https://****.com/ws/rest/Ignition?messageType=GET_PRODUCT_SPEC" 
# Create the JythonHttpClient. 
client = system.net.httpClient(username=user, password=password, bypass_cert_validation = True) 
response = client.post(url, data=data)

got the same error.

The exact same error? The first error you posted looks like this:
https://xxx/ws/rest/Ignition?messageType=GET_PRODUCT_SPEC?ProductPartNumber=+AEC010M1G3000T+&FacilityPrefix=LSP&SqlWhere=and+PRODUCT_SPEC.SPEC_TYPE+in+%28%27IC%27%2C%27TOC%27%2C%27LPC%27%29

Which means you're sending your data dictionary as URL parameters, which is probably not what your server is expecting; typically POST routes expect data in the request body.

Can you post the actual error message (you may want to sanitize it, if you consider your URL sensitive) you get if you execute something like this:

user = "user" 
password = "password" 
client = system.net.httpClient(username=user, password=password, bypass_cert_validation = True) 

url = "https://****.com/ws/rest/Ignition" 
params = { "messageType": "GET_PRODUCT_SPEC" }
data = { "ProductPartNumber" : " **** ", "FacilityPrefix" : "***", "SqlWhere": "*****"} 
# Create the JythonHttpClient. 
response = client.post(url, params=params, data=data)

Note that the only error here is this: An existing connection was forcibly closed by the remote host, which is pretty clearly indicating the server isn't accepting your request; instead of returning an error code it's forcibly closing the socket.

As an aside:

:grimacing:
Accepting arbitrary strings as SQL input is super dangerous - I hope you know what you're doing.

3 Likes

This is the error after implementing what you recommended. It seems to me that they are the exact same error.

com.inductiveautomation.ignition.common.script.JythonExecException
Traceback (most recent call last):
  File "<function:runAction>", line 2, in runAction
  File "<custom-method specRuleTest>", line 13, in specRuleTest
java.io.IOException: java.io.IOException: Unable to POST https://****.com/ws/rest/Ignition?messageType=GET_PRODUCT_SPEC

	caused by org.python.core.PyException
Traceback (most recent call last):
  File "<function:runAction>", line 2, in runAction
  File "<custom-method specRuleTest>", line 13, in specRuleTest
java.io.IOException: java.io.IOException: Unable to POST https://****.com/ws/rest/Ignition?messageType=GET_PRODUCT_SPEC

	caused by IOException: Unable to POST https://****.com/ws/rest/Ignition?messageType=GET_PRODUCT_SPEC
	caused by IOException: An existing connection was forcibly closed by the remote host
	caused by IOException: An existing connection was forcibly closed by the remote host


Thanks for pointing out the arbitrary strings as SQL input is dangerous, but the arbitrary strings as SQL input are developed by another team that manages the database. I was just asked to provide the data shown above to get the product info.

If I had to guess, since I do because there’s not enough information available to us, I’d say this means either:

  • the server doesn’t like the data you’re providing
  • network or firewall issue

Usually you’d get an HTTP error code when a server doesn’t like something about the data, but who knows.

1 Like