Skip to content
This repository was archived by the owner on Aug 7, 2025. It is now read-only.

Commit a9f7c3f

Browse files
authored
Merge pull request #407 from pytorch/issue_202
Error handling - non ssl request
2 parents f0da8d2 + 5efea7f commit a9f7c3f

File tree

4 files changed

+80
-9
lines changed

4 files changed

+80
-9
lines changed

frontend/server/src/main/java/org/pytorch/serve/ServerInitializer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import io.netty.handler.codec.http.HttpServerCodec;
88
import io.netty.handler.ssl.SslContext;
99
import org.pytorch.serve.http.ApiDescriptionRequestHandler;
10+
import org.pytorch.serve.http.ExtendedSSLHandler;
1011
import org.pytorch.serve.http.HttpRequestHandler;
1112
import org.pytorch.serve.http.HttpRequestHandlerChain;
1213
import org.pytorch.serve.http.InferenceRequestHandler;
@@ -48,7 +49,7 @@ public void initChannel(Channel ch) {
4849

4950
int maxRequestSize = ConfigManager.getInstance().getMaxRequestSize();
5051
if (sslCtx != null) {
51-
pipeline.addLast("ssl", sslCtx.newHandler(ch.alloc()));
52+
pipeline.addLast("ssl", new ExtendedSSLHandler(sslCtx, connectorType));
5253
}
5354
pipeline.addLast("http", new HttpServerCodec());
5455
pipeline.addLast("aggregator", new HttpObjectAggregator(maxRequestSize));
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.pytorch.serve.http;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.channel.ChannelHandlerContext;
5+
import io.netty.handler.codec.http.HttpResponseStatus;
6+
import io.netty.handler.ssl.OptionalSslHandler;
7+
import io.netty.handler.ssl.SslContext;
8+
import io.netty.handler.ssl.SslHandler;
9+
import java.util.List;
10+
import org.pytorch.serve.util.ConfigManager;
11+
import org.pytorch.serve.util.ConnectorType;
12+
import org.pytorch.serve.util.NettyUtils;
13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
15+
16+
public class ExtendedSSLHandler extends OptionalSslHandler {
17+
private static final Logger logger = LoggerFactory.getLogger(ExtendedSSLHandler.class);
18+
/** the length of the ssl record header (in bytes) */
19+
private static final int SSL_RECORD_HEADER_LENGTH = 5;
20+
21+
private ConnectorType connectorType;
22+
23+
public ExtendedSSLHandler(SslContext sslContext, ConnectorType connectorType) {
24+
super(sslContext);
25+
this.connectorType = connectorType;
26+
}
27+
28+
@Override
29+
protected void decode(ChannelHandlerContext context, ByteBuf in, List<Object> out)
30+
throws Exception {
31+
if (in.readableBytes() < SSL_RECORD_HEADER_LENGTH) {
32+
return;
33+
}
34+
ConfigManager configMgr = ConfigManager.getInstance();
35+
if (SslHandler.isEncrypted(in) || !configMgr.isSSLEnabled(connectorType)) {
36+
super.decode(context, in, out);
37+
} else {
38+
logger.error("Recieved HTTP request!");
39+
NettyUtils.sendJsonResponse(
40+
context,
41+
new StatusResponse(
42+
"This TorchServe instance only accepts HTTPS requests",
43+
HttpResponseStatus.FORBIDDEN.code()));
44+
}
45+
}
46+
}

frontend/server/src/main/java/org/pytorch/serve/util/ConfigManager.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,15 @@ public final class ConfigManager {
105105

106106
public static final String PYTHON_EXECUTABLE = "python";
107107

108+
public static final Pattern ADDRESS_PATTERN =
109+
Pattern.compile(
110+
"((https|http)://([^:^/]+)(:([0-9]+))?)|(unix:(/.*))",
111+
Pattern.CASE_INSENSITIVE);
112+
private static Pattern pattern = Pattern.compile("\\$\\$([^$]+[^$])\\$\\$");
113+
108114
private Pattern blacklistPattern;
109115
private Properties prop;
110-
private static Pattern pattern = Pattern.compile("\\$\\$([^$]+[^$])\\$\\$");
116+
111117
private boolean snapshotDisabled;
112118

113119
private static ConfigManager instance;
@@ -718,6 +724,30 @@ public boolean isSnapshotDisabled() {
718724
return snapshotDisabled;
719725
}
720726

727+
public boolean isSSLEnabled(ConnectorType connectorType) {
728+
String address = prop.getProperty(TS_INFERENCE_ADDRESS, "http://127.0.0.1:8080");
729+
switch (connectorType) {
730+
case MANAGEMENT_CONNECTOR:
731+
address = prop.getProperty(TS_MANAGEMENT_ADDRESS, "http://127.0.0.1:8081");
732+
break;
733+
case METRICS_CONNECTOR:
734+
address = prop.getProperty(TS_METRICS_ADDRESS, "http://127.0.0.1:8082");
735+
break;
736+
default:
737+
break;
738+
}
739+
// String inferenceAddress = prop.getProperty(TS_INFERENCE_ADDRESS,
740+
// "http://127.0.0.1:8080");
741+
Matcher matcher = ConfigManager.ADDRESS_PATTERN.matcher(address);
742+
if (!matcher.matches()) {
743+
throw new IllegalArgumentException("Invalid binding address: " + address);
744+
}
745+
746+
String protocol = matcher.group(2);
747+
748+
return "https".equalsIgnoreCase(protocol);
749+
}
750+
721751
public int getIniitialWorkerPort() {
722752
return Integer.parseInt(prop.getProperty(TS_INITIAL_WORKER_PORT, "9000"));
723753
}

frontend/server/src/main/java/org/pytorch/serve/util/Connector.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,10 @@
2424
import java.net.SocketAddress;
2525
import java.util.Objects;
2626
import java.util.regex.Matcher;
27-
import java.util.regex.Pattern;
2827
import org.apache.commons.io.FileUtils;
2928

3029
public class Connector {
3130

32-
private static final Pattern ADDRESS_PATTERN =
33-
Pattern.compile(
34-
"((https|http)://([^:^/]+)(:([0-9]+))?)|(unix:(/.*))",
35-
Pattern.CASE_INSENSITIVE);
36-
3731
private static boolean useNativeIo = ConfigManager.getInstance().useNativeIo();
3832

3933
private boolean uds;
@@ -75,7 +69,7 @@ private Connector(
7569
}
7670

7771
public static Connector parse(String binding, ConnectorType connectorType) {
78-
Matcher matcher = ADDRESS_PATTERN.matcher(binding);
72+
Matcher matcher = ConfigManager.ADDRESS_PATTERN.matcher(binding);
7973
if (!matcher.matches()) {
8074
throw new IllegalArgumentException("Invalid binding address: " + binding);
8175
}

0 commit comments

Comments
 (0)