-
Notifications
You must be signed in to change notification settings - Fork 68
Fix: websocket url parser #326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,8 +11,6 @@ | |
| import eu.luminis.jmeter.wssampler.SingleWriteWebSocketSampler; | ||
| import eu.luminis.jmeter.wssampler.SingleWriteWebSocketSamplerGui; | ||
| import java.lang.reflect.Method; | ||
| import java.net.URI; | ||
| import java.net.URISyntaxException; | ||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import org.apache.jmeter.testelement.TestElement; | ||
|
|
@@ -25,6 +23,7 @@ | |
| import us.abstracta.jmeter.javadsl.codegeneration.params.EnumParam; | ||
| import us.abstracta.jmeter.javadsl.codegeneration.params.StringParam; | ||
| import us.abstracta.jmeter.javadsl.core.samplers.BaseSampler; | ||
| import us.abstracta.jmeter.javadsl.http.JmeterUrl; | ||
|
|
||
| /** | ||
| * Provides factory methods to create WebSocket samplers for performance | ||
|
|
@@ -119,8 +118,8 @@ public static DslDisconnectSampler websocketDisconnect() { | |
| * @return the write sampler for further configuration or usage | ||
| * @since 2.2 | ||
| */ | ||
| public static DslWriteSampler websocketWrite(String requestData) { | ||
| return new DslWriteSampler(requestData); | ||
| public static DslWriteSampler websocketWrite(String requestData, String dataType) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also add a default method without dataType param using text as default |
||
| return new DslWriteSampler(requestData, dataType); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -133,11 +132,12 @@ public static DslWriteSampler websocketWrite(String requestData) { | |
| * Requires an active WebSocket connection established via | ||
| * {@link #websocketConnect(String)}. | ||
| * | ||
| * @param type the data type to read from the server. Must be 'text' or 'binary' | ||
| * @return the read sampler for further configuration or usage | ||
| * @since 2.2 | ||
| */ | ||
| public static DslReadSampler websocketRead() { | ||
| return new DslReadSampler(); | ||
| public static DslReadSampler websocketRead(String type) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as before |
||
| return new DslReadSampler(type); | ||
| } | ||
|
|
||
| public static class DslConnectSampler extends BaseSampler<DslConnectSampler> { | ||
|
|
@@ -150,43 +150,40 @@ public static class DslConnectSampler extends BaseSampler<DslConnectSampler> { | |
|
|
||
| private DslConnectSampler(String url) { | ||
| super("WebSocket Open Connection", OpenWebSocketSamplerGui.class); | ||
| try { | ||
| URI uri = new URI(url); | ||
| parseUrl(url); | ||
| } | ||
|
|
||
| private static boolean containsJmeterExpression(String value) { | ||
| return value != null && value.contains("${"); | ||
| } | ||
|
|
||
| String scheme = uri.getScheme(); | ||
| if (scheme == null || (!"ws".equals(scheme) && !"wss".equals(scheme))) { | ||
| private void parseUrl(String url) { | ||
| JmeterUrl parsed = JmeterUrl.valueOf(url); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what happen if url string is full variable? |
||
| String scheme = parsed.protocol(); | ||
| if (scheme != null && !containsJmeterExpression(scheme)) { | ||
| if (!"ws".equals(scheme) && !"wss".equals(scheme)) { | ||
| throw new IllegalArgumentException( | ||
| "Invalid WebSocket URL. Must start with 'ws://' or 'wss://'"); | ||
| } | ||
|
|
||
| this.tls = "wss".equals(scheme); | ||
| this.server = uri.getHost(); | ||
| if (this.server == null) { | ||
| throw new IllegalArgumentException("Invalid WebSocket URL. Host is required"); | ||
| } | ||
|
|
||
| int port = uri.getPort(); | ||
| if (port == -1) { | ||
| this.port = this.tls ? "443" : "80"; | ||
| } else { | ||
| this.port = String.valueOf(port); | ||
| } | ||
|
|
||
| String path = uri.getPath(); | ||
| if (path == null || path.isEmpty()) { | ||
| this.path = "/"; | ||
| tls = "wss".equals(scheme); | ||
| } | ||
| server = parsed.host(); | ||
| if ((server == null || server.isEmpty()) && scheme != null | ||
| && !containsJmeterExpression(scheme)) { | ||
| throw new IllegalArgumentException("Invalid WebSocket URL. Host is required"); | ||
| } | ||
| String parsedPort = parsed.port(); | ||
| if (parsedPort == null || parsedPort.isEmpty()) { | ||
| if (scheme != null && !containsJmeterExpression(scheme)) { | ||
| port = tls ? "443" : "80"; | ||
| } else { | ||
| this.path = path; | ||
| } | ||
|
|
||
| String query = uri.getQuery(); | ||
| if (query != null && !query.isEmpty()) { | ||
| this.path = this.path + "?" + query; | ||
| port = ""; | ||
| } | ||
|
|
||
| } catch (URISyntaxException e) { | ||
| throw new IllegalArgumentException("Invalid WebSocket URL: " + url, e); | ||
| } else { | ||
| port = parsedPort; | ||
| } | ||
| String parsedPath = parsed.path(); | ||
| path = (parsedPath == null || parsedPath.isEmpty()) ? "/" : parsedPath; | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -199,9 +196,15 @@ protected TestElement buildTestElement() { | |
| ret.setReadTimeout(responseTimeoutMillis); | ||
| } | ||
| ret.setTLS(tls); | ||
| ret.setServer(server); | ||
| ret.setPort(port); | ||
| ret.setPath(path); | ||
| if (server != null) { | ||
| ret.setServer(server); | ||
| } | ||
| if (port != null) { | ||
| ret.setPort(port); | ||
| } | ||
| if (path != null) { | ||
| ret.setPath(path); | ||
| } | ||
| return ret; | ||
| } | ||
|
|
||
|
|
@@ -424,16 +427,21 @@ protected MethodCall buildMethodCall(CloseWebSocketSampler testElement, | |
|
|
||
| public static class DslWriteSampler extends BaseSampler<DslWriteSampler> { | ||
| private String requestData; | ||
| private String dataType; | ||
|
|
||
| private DslWriteSampler(String requestData) { | ||
| private DslWriteSampler(String requestData, String dataType) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment regarding to data type |
||
| super("WebSocket Single Write", SingleWriteWebSocketSamplerGui.class); | ||
| this.requestData = requestData; | ||
| this.dataType = dataType; | ||
| if (dataType != null && !"text".equals(dataType) && !"binary".equals(dataType)) { | ||
| throw new IllegalArgumentException("Invalid data type. Must be 'text' or 'binary'"); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| protected TestElement buildTestElement() { | ||
| SingleWriteWebSocketSampler write = new SingleWriteWebSocketSampler(); | ||
| write.setType(DataPayloadType.Text); | ||
| write.setType("text".equals(dataType) ? DataPayloadType.Text : DataPayloadType.Binary); | ||
| write.setRequestData(requestData); | ||
| write.setCreateNewConnection(false); | ||
| return write; | ||
|
|
@@ -460,9 +468,14 @@ protected MethodCall buildMethodCall(SingleWriteWebSocketSampler testElement, | |
| public static class DslReadSampler extends BaseSampler<DslReadSampler> { | ||
| private String responseTimeoutMillis; | ||
| private boolean waitForResponse = true; | ||
| private String type; | ||
|
|
||
| private DslReadSampler() { | ||
| private DslReadSampler(String type) { | ||
| super("WebSocket Single Read", SingleReadWebSocketSamplerGui.class); | ||
| this.type = type; | ||
| if (type != null && !"text".equals(type) && !"binary".equals(type)) { | ||
| throw new IllegalArgumentException("Invalid data type. Must be 'text' or 'binary'"); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -471,7 +484,7 @@ protected TestElement buildTestElement() { | |
| if (responseTimeoutMillis != null) { | ||
| read.setReadTimeout(responseTimeoutMillis); | ||
| } | ||
| read.setDataType(DataType.Text); | ||
| read.setDataType("text".equals(type) ? DataType.Text : DataType.Binary); | ||
| read.setOptional(!waitForResponse); | ||
| read.setCreateNewConnection(false); | ||
| return read; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider use an Enum for type, in caso it field could be a JMeter variable maybe you should expose both methods
public static DslWriteSampler websocketWrite(String requestData, String dataType)and
public static DslWriteSampler websocketWrite(String requestData, DataType dataType)