Skip to content

Commit fba0393

Browse files
committed
Add "Override local binding" to HTTP Sender
1 parent 86dec16 commit fba0393

5 files changed

Lines changed: 169 additions & 39 deletions

File tree

client/src/com/mirth/connect/connectors/http/HttpSender.java

Lines changed: 94 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/*
22
* Copyright (c) Mirth Corporation. All rights reserved.
3-
*
3+
*
44
* http://www.mirthcorp.com
5-
*
5+
*
66
* The software in this package is published under the terms of the MPL license a copy of which has
77
* been included with this distribution in the LICENSE.txt file.
88
*/
@@ -130,7 +130,7 @@ public void changedUpdate(DocumentEvent e) {
130130
checkContentEnabled();
131131
}
132132
});
133-
133+
134134
initToolTips();
135135
initLayout();
136136
}
@@ -148,6 +148,8 @@ public ConnectorProperties getProperties() {
148148
properties.setUseProxyServer(useProxyServerYesRadio.isSelected());
149149
properties.setProxyAddress(proxyAddressField.getText());
150150
properties.setProxyPort(proxyPortField.getText());
151+
properties.setOverrideLocalBinding(overrideLocalBindingYesRadio.isSelected());
152+
properties.setLocalAddress(localAddressField.getText());
151153

152154
if (postButton.isSelected()) {
153155
properties.setMethod("post");
@@ -190,7 +192,7 @@ public ConnectorProperties getProperties() {
190192
properties.setParametersMap(getProperties(queryParametersTable));
191193
properties.setUseParametersVariable(useQueryParamsVariableRadio.isSelected());
192194
properties.setParametersVariable(queryParamsVariableField.getText());
193-
195+
194196
properties.setHeadersMap(getProperties(headersTable));
195197
properties.setUseHeadersVariable(useHeadersVariableRadio.isSelected());
196198
properties.setHeadersVariable(headersVariableField.getText());
@@ -219,6 +221,15 @@ public void setProperties(ConnectorProperties properties) {
219221
proxyAddressField.setText(props.getProxyAddress());
220222
proxyPortField.setText(props.getProxyPort());
221223

224+
if (props.isOverrideLocalBinding()) {
225+
overrideLocalBindingYesRadio.setSelected(true);
226+
overrideLocalBindingYesRadioActionPerformed(null);
227+
} else {
228+
overrideLocalBindingNoRadio.setSelected(true);
229+
overrideLocalBindingNoRadioActionPerformed(null);
230+
}
231+
localAddressField.setText(props.getLocalAddress());
232+
222233
if (props.getMethod().equalsIgnoreCase("post")) {
223234
postButton.setSelected(true);
224235
postButtonActionPerformed(null);
@@ -656,6 +667,15 @@ public boolean checkProperties(ConnectorProperties properties, boolean highlight
656667
}
657668
}
658669

670+
if (props.isOverrideLocalBinding()) {
671+
if (props.getLocalAddress().length() <= 3) {
672+
valid = false;
673+
if (highlight) {
674+
localAddressField.setBackground(UIConstants.INVALID_COLOR);
675+
}
676+
}
677+
}
678+
659679
return valid;
660680
}
661681

@@ -670,6 +690,7 @@ public void resetInvalidProperties() {
670690
headersVariableField.setBackground(null);
671691
contentTypeField.setBackground(null);
672692
contentTextArea.setBackground(null);
693+
localAddressField.setBackground(null);
673694
}
674695

675696
@Override
@@ -889,6 +910,12 @@ private void initComponents() {
889910
responseBinaryMimeTypesField = new MirthTextField();
890911
responseBinaryMimeTypesRegexCheckBox = new MirthCheckBox();
891912
patchButton = new MirthRadioButton();
913+
overrideLocalBindingLabel = new JLabel();
914+
overrideLocalBindingButtonGroup = new ButtonGroup();
915+
overrideLocalBindingYesRadio = new MirthRadioButton();
916+
overrideLocalBindingNoRadio = new MirthRadioButton();
917+
localAddressLabel = new JLabel();
918+
localAddressField = new MirthIconTextField();
892919

893920
setBackground(new Color(255, 255, 255));
894921
setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
@@ -926,13 +953,13 @@ public void actionPerformed(ActionEvent evt) {
926953
useQueryParamsTableRadio.addActionListener(event -> {
927954
useQueryParamsVariableFieldsEnabled(false);
928955
});
929-
956+
930957
useQueryParamsVariableRadio.setText("Use Map:");
931958
useQueryParamsVariableRadio.setBackground(new Color(255, 255, 255));
932959
useQueryParamsVariableRadio.addActionListener(event -> {
933960
useQueryParamsVariableFieldsEnabled(true);
934961
});
935-
962+
936963
ButtonGroup queryParamsButtonGroup = new ButtonGroup();
937964
queryParamsButtonGroup.add(useQueryParamsTableRadio);
938965
queryParamsButtonGroup.add(useQueryParamsVariableRadio);
@@ -989,17 +1016,17 @@ public void actionPerformed(ActionEvent evt) {
9891016
useHeadersTableRadio.addActionListener(event -> {
9901017
useHeadersVariableFieldsEnabled(false);
9911018
});
992-
1019+
9931020
useHeadersVariableRadio.setText("Use Map:");
9941021
useHeadersVariableRadio.setBackground(new Color(255, 255, 255));
9951022
useHeadersVariableRadio.addActionListener(event -> {
9961023
useHeadersVariableFieldsEnabled(true);
9971024
});
998-
1025+
9991026
ButtonGroup headersButtonGroup = new ButtonGroup();
10001027
headersButtonGroup.add(useHeadersTableRadio);
10011028
headersButtonGroup.add(useHeadersVariableRadio);
1002-
1029+
10031030
responseContentLabel.setText("Response Content:");
10041031

10051032
responseContentXmlBodyRadio.setBackground(new Color(255, 255, 255));
@@ -1203,8 +1230,38 @@ public void actionPerformed(ActionEvent evt) {
12031230
patchButtonActionPerformed(evt);
12041231
}
12051232
});
1233+
1234+
localAddressLabel.setText("Local Address:");
1235+
1236+
localAddressField.setToolTipText("<html>The local address that the client socket will be bound to, if Override Local Binding is set to Yes.<br/></html>");
1237+
1238+
overrideLocalBindingLabel.setText("Override Local Binding:");
1239+
1240+
overrideLocalBindingYesRadio.setBackground(new Color(255, 255, 255));
1241+
overrideLocalBindingYesRadio.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
1242+
overrideLocalBindingButtonGroup.add(overrideLocalBindingYesRadio);
1243+
overrideLocalBindingYesRadio.setText("Yes");
1244+
overrideLocalBindingYesRadio.setToolTipText("<html>Select Yes to override the local address that the client socket will be bound to.<br/>Select No to use the default values of 0.0.0.0:0.<br/></html>");
1245+
overrideLocalBindingYesRadio.setMargin(new Insets(0, 0, 0, 0));
1246+
overrideLocalBindingYesRadio.addActionListener(new ActionListener() {
1247+
public void actionPerformed(ActionEvent evt) {
1248+
overrideLocalBindingYesRadioActionPerformed(evt);
1249+
}
1250+
});
1251+
1252+
overrideLocalBindingNoRadio.setBackground(new Color(255, 255, 255));
1253+
overrideLocalBindingNoRadio.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
1254+
overrideLocalBindingButtonGroup.add(overrideLocalBindingNoRadio);
1255+
overrideLocalBindingNoRadio.setText("No");
1256+
overrideLocalBindingNoRadio.setToolTipText("<html>Select Yes to override the local address that the client socket will be bound to.<br/>Select No to use the default values of 0.0.0.0:0.<br/></html>");
1257+
overrideLocalBindingNoRadio.setMargin(new Insets(0, 0, 0, 0));
1258+
overrideLocalBindingNoRadio.addActionListener(new ActionListener() {
1259+
public void actionPerformed(ActionEvent evt) {
1260+
overrideLocalBindingNoRadioActionPerformed(evt);
1261+
}
1262+
});
12061263
}
1207-
1264+
12081265
private void initToolTips() {
12091266
urlField.setToolTipText("Enter the URL of the HTTP server to send each message to.");
12101267
queryParametersTable.setToolTipText("Query parameters are encoded as x=y pairs as part of the request URL, separated from it by a '?' and from each other by an '&'.");
@@ -1243,15 +1300,15 @@ private void initToolTips() {
12431300
patchButton.setToolTipText("Selects the HTTP operation used to send each message.");
12441301
useQueryParamsTableRadio.setToolTipText("<html>The table below will be used to populate query parameters.</html>");
12451302
useQueryParamsVariableRadio.setToolTipText("<html>The Java map specified by the following variable will be used to populate query parameters.<br/>The map must have String keys and either String or List&lt;String&gt; values.</html>");
1246-
queryParamsVariableField.setToolTipText("<html>The variable of a Java map to use to populate query parameters.<br/>The map must have String keys and either String or List&lt;String&gt; values.</html>");
1303+
queryParamsVariableField.setToolTipText("<html>The variable of a Java map to use to populate query parameters.<br/>The map must have String keys and either String or List&lt;String&gt; values.</html>");
12471304
useHeadersTableRadio.setToolTipText("<html>The table below will be used to populate headers.</html>");
12481305
useHeadersVariableRadio.setToolTipText("<html>The Java map specified by the following variable will be used to populate headers.<br/>The map must have String keys and either String or List&lt;String&gt; values.</html>");
12491306
headersVariableField.setToolTipText("<html>The variable of a Java map to use to populate headers.<br/>The map must have String keys and either String or List&lt;String&gt; values.</html>");
12501307
}
1251-
1308+
12521309
private void initLayout() {
12531310
setLayout(new MigLayout("insets 0 8 0 8, novisualpadding, hidemode 3, gap 12 6", "[][]6[]", "[][][][][][][][][][][][][][][][][grow][][grow][][][][grow]"));
1254-
1311+
12551312
add(urlLabel, "right");
12561313
add(urlField, "w 312!, sx, split 2");
12571314
add(testConnection, "gapbefore 6");
@@ -1262,6 +1319,11 @@ private void initLayout() {
12621319
add(proxyAddressField, "w 202!, sx");
12631320
add(proxyPortLabel, "newline, right");
12641321
add(proxyPortField, "w 56!, sx");
1322+
add(overrideLocalBindingLabel, "newline, right");
1323+
add(overrideLocalBindingYesRadio, "split 2");
1324+
add(overrideLocalBindingNoRadio);
1325+
add(localAddressLabel, "newline, right");
1326+
add(localAddressField, "w 200!, sx");
12651327
add(methodLabel, "newline, right");
12661328
add(postButton, "split 5");
12671329
add(getButton);
@@ -1476,21 +1538,31 @@ private void dataTypeTextRadioActionPerformed(ActionEvent evt) {
14761538
charsetEncodingCombobox.setEnabled(true);
14771539
}
14781540
}
1479-
1541+
14801542
private void useHeadersVariableFieldsEnabled(boolean useVariable) {
14811543
headersVariableField.setEnabled(useVariable);
14821544
headersTable.setEnabled(!useVariable);
14831545
headersNewButton.setEnabled(!useVariable);
14841546
headersDeleteButton.setEnabled(!useVariable && headersTable.getSelectedRow() > -1);
14851547
}
1486-
1548+
14871549
private void useQueryParamsVariableFieldsEnabled(boolean useVariable) {
14881550
queryParamsVariableField.setEnabled(useVariable);
14891551
queryParametersTable.setEnabled(!useVariable);
14901552
queryParametersNewButton.setEnabled(!useVariable);
14911553
queryParametersDeleteButton.setEnabled(!useVariable && queryParametersTable.getSelectedRow() > -1);
14921554
}
1493-
1555+
1556+
private void overrideLocalBindingYesRadioActionPerformed(ActionEvent evt) {
1557+
localAddressField.setEnabled(true);
1558+
localAddressLabel.setEnabled(true);
1559+
}
1560+
1561+
private void overrideLocalBindingNoRadioActionPerformed(ActionEvent evt) {
1562+
localAddressField.setEnabled(false);
1563+
localAddressLabel.setEnabled(false);
1564+
}
1565+
14941566
private ButtonGroup authenticationButtonGroup;
14951567
private JLabel authenticationLabel;
14961568
private MirthRadioButton authenticationNoRadio;
@@ -1570,4 +1642,10 @@ private void useQueryParamsVariableFieldsEnabled(boolean useVariable) {
15701642
private MirthRadioButton useProxyServerYesRadio;
15711643
private MirthTextField usernameField;
15721644
private JLabel usernameLabel;
1645+
private JLabel overrideLocalBindingLabel;
1646+
private ButtonGroup overrideLocalBindingButtonGroup;
1647+
private MirthRadioButton overrideLocalBindingNoRadio;
1648+
private MirthRadioButton overrideLocalBindingYesRadio;
1649+
private JLabel localAddressLabel;
1650+
private MirthIconTextField localAddressField;
15731651
}

server/src/com/mirth/connect/connectors/http/HttpConnectorServlet.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/*
22
* Copyright (c) Mirth Corporation. All rights reserved.
3-
*
3+
*
44
* http://www.mirthcorp.com
5-
*
5+
*
66
* The software in this package is published under the terms of the MPL license a copy of which has
77
* been included with this distribution in the LICENSE.txt file.
88
*/
@@ -15,13 +15,12 @@
1515
import javax.ws.rs.core.Context;
1616
import javax.ws.rs.core.SecurityContext;
1717

18-
import org.apache.commons.lang3.StringUtils;
19-
2018
import com.mirth.connect.client.core.api.MirthApiException;
2119
import com.mirth.connect.server.api.MirthServlet;
2220
import com.mirth.connect.server.util.ConnectorUtil;
2321
import com.mirth.connect.server.util.TemplateValueReplacer;
2422
import com.mirth.connect.util.ConnectionTestResponse;
23+
import org.apache.commons.lang3.Strings;
2524

2625
public class HttpConnectorServlet extends MirthServlet implements HttpConnectorServletInterface {
2726

@@ -36,9 +35,22 @@ public HttpConnectorServlet(@Context HttpServletRequest request, @Context Securi
3635
public ConnectionTestResponse testConnection(String channelId, String channelName, HttpDispatcherProperties properties) {
3736
try {
3837
URL url = new URL(replacer.replaceValues(properties.getHost(), channelId, channelName));
39-
int port = url.getPort();
4038
// If no port was provided, default to port 80 or 443.
41-
return ConnectorUtil.testConnection(url.getHost(), (port == -1) ? (StringUtils.equalsIgnoreCase(url.getProtocol(), "https") ? 443 : 80) : port, TIMEOUT);
39+
final int port;
40+
if (url.getPort() != -1) {
41+
port = url.getPort();
42+
} else if (Strings.CI.equals(url.getProtocol(), "https")) {
43+
port = 443;
44+
} else {
45+
port = 80;
46+
}
47+
48+
if (!properties.isOverrideLocalBinding()) {
49+
return ConnectorUtil.testConnection(url.getHost(), port, TIMEOUT);
50+
} else {
51+
String localAddr = replacer.replaceValues(properties.getLocalAddress(), channelId, channelName);
52+
return ConnectorUtil.testConnection(url.getHost(), port, TIMEOUT, localAddr);
53+
}
4254
} catch (Exception e) {
4355
throw new MirthApiException(e);
4456
}

server/src/com/mirth/connect/connectors/http/HttpDispatcher.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
/*
22
* Copyright (c) Mirth Corporation. All rights reserved.
3-
*
3+
*
44
* http://www.mirthcorp.com
5-
*
5+
*
66
* The software in this package is published under the terms of the MPL license a copy of which has
77
* been included with this distribution in the LICENSE.txt file.
88
*/
99

1010
package com.mirth.connect.connectors.http;
1111

1212
import java.io.File;
13+
import java.net.InetAddress;
1314
import java.net.URI;
1415
import java.nio.charset.Charset;
1516
import java.util.ArrayList;
@@ -27,6 +28,8 @@
2728
import javax.mail.util.ByteArrayDataSource;
2829

2930
import com.mirth.connect.client.core.BrandingConstants;
31+
import com.mirth.connect.connectors.tcp.TcpDispatcherProperties;
32+
import com.mirth.connect.util.TcpUtil;
3033
import org.apache.commons.collections4.CollectionUtils;
3134
import org.apache.commons.collections4.map.CaseInsensitiveMap;
3235
import org.apache.commons.fileupload.FileUploadBase;
@@ -192,6 +195,7 @@ public void replaceConnectorProperties(ConnectorProperties connectorProperties,
192195
httpDispatcherProperties.setHost(replacer.replaceValues(httpDispatcherProperties.getHost(), connectorMessage));
193196
httpDispatcherProperties.setProxyAddress(replacer.replaceValues(httpDispatcherProperties.getProxyAddress(), connectorMessage));
194197
httpDispatcherProperties.setProxyPort(replacer.replaceValues(httpDispatcherProperties.getProxyPort(), connectorMessage));
198+
httpDispatcherProperties.setLocalAddress(replacer.replaceValues(httpDispatcherProperties.getLocalAddress(), connectorMessage));
195199
httpDispatcherProperties.setResponseBinaryMimeTypes(replacer.replaceValues(httpDispatcherProperties.getResponseBinaryMimeTypes(), connectorMessage));
196200
httpDispatcherProperties.setHeadersMap(replacer.replaceKeysAndValuesInMap(httpDispatcherProperties.getHeadersMap(), connectorMessage));
197201
httpDispatcherProperties.setHeadersVariable(replacer.replaceValues(httpDispatcherProperties.getHeadersVariable(), connectorMessage));
@@ -258,9 +262,9 @@ public Response send(ConnectorProperties connectorProperties, ConnectorMessage c
258262

259263
/*
260264
* If a charset is set in the Content Type field, use that.
261-
*
265+
*
262266
* If the charset is NONE, keep it as null.
263-
*
267+
*
264268
* Otherwise, use the charset from the Character Encoding drop-down menu.
265269
*/
266270
Charset charset = null;
@@ -312,8 +316,15 @@ public Response send(ConnectorProperties connectorProperties, ConnectorMessage c
312316
logger.debug("using authentication with credentials: " + credentials);
313317
}
314318

315-
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(socketTimeout).setSocketTimeout(socketTimeout).setStaleConnectionCheckEnabled(true).build();
316-
context.setRequestConfig(requestConfig);
319+
final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom()
320+
.setConnectTimeout(socketTimeout)
321+
.setSocketTimeout(socketTimeout)
322+
.setStaleConnectionCheckEnabled(true);
323+
if (httpDispatcherProperties.isOverrideLocalBinding()) {
324+
final InetAddress localAddress = InetAddress.getByName(getLocalAddress());
325+
requestConfigBuilder.setLocalAddress(localAddress);
326+
}
327+
context.setRequestConfig(requestConfigBuilder.build());
317328

318329
// Set proxy information
319330
if (httpDispatcherProperties.isUseProxyServer()) {
@@ -444,7 +455,7 @@ public boolean isBinaryContentType(ContentType contentType) {
444455

445456
return new Response(responseStatus, responseData, responseStatusMessage, responseError, validateResponse);
446457
}
447-
458+
448459
protected boolean shouldParseMultipart(HttpDispatcherProperties httpDispatcherProperties, String mimeType) {
449460
// Only parse multipart if XML Body is selected and Parse Multipart is enabled
450461
return httpDispatcherProperties.isResponseXmlBody() && httpDispatcherProperties.isResponseParseMultipart() && mimeType.startsWith(FileUploadBase.MULTIPART);
@@ -709,6 +720,9 @@ private boolean isBinaryContentType(String binaryMimeTypes, ContentType contentT
709720
}
710721
}
711722

723+
private String getLocalAddress() {
724+
return TcpUtil.getFixedHost(replacer.replaceValues(getConnectorProperties().getLocalAddress(), getChannelId(), getChannel().getName()));
725+
}
712726
@Override
713727
public HttpDispatcherProperties getConnectorProperties() {
714728
return (HttpDispatcherProperties) super.getConnectorProperties();

0 commit comments

Comments
 (0)