mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
explicit http url decoding support
This commit is contained in:
@@ -8,12 +8,13 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class HttpFormatParser {
|
public class HttpFormatParser {
|
||||||
|
|
||||||
public static Map<String, String> parseUrl(String uri) {
|
public static Map<String, String> parseUrl(String uri) {
|
||||||
if (uri.matches("http.+")) {
|
if (uri.matches("http.+")) {
|
||||||
return Map.of("uri", rewriteUriWithStaticsEncoded(uri));
|
return Map.of("uri", rewriteExplicitSections(uri));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -54,14 +55,14 @@ public class HttpFormatParser {
|
|||||||
throw new BasicError("Request template must have at least a method and a uri: " + methodAndHeaders[0]);
|
throw new BasicError("Request template must have at least a method and a uri: " + methodAndHeaders[0]);
|
||||||
}
|
}
|
||||||
props.put("method", methodLine[0]);
|
props.put("method", methodLine[0]);
|
||||||
props.put("uri", rewriteUriWithStaticsEncoded(methodLine[1]));
|
props.put("uri", rewriteExplicitSections(methodLine[1]));
|
||||||
|
|
||||||
if (methodLine.length == 3) {
|
if (methodLine.length == 3) {
|
||||||
String actualVersion = methodLine[2];
|
String actualVersion = methodLine[2];
|
||||||
String symbolicVersion = actualVersion
|
String symbolicVersion = actualVersion
|
||||||
.replaceAll("/1.1", "_1_1")
|
.replaceAll("/1.1", "_1_1")
|
||||||
.replaceAll("/2.0", "_2")
|
.replaceAll("/2.0", "_2")
|
||||||
.replaceAll("/2", "_2");
|
.replaceAll("/2", "_2");
|
||||||
|
|
||||||
props.put("version", symbolicVersion);
|
props.put("version", symbolicVersion);
|
||||||
}
|
}
|
||||||
@@ -69,27 +70,37 @@ public class HttpFormatParser {
|
|||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String rewriteUriWithStaticsEncoded(String template) {
|
private final static Pattern DOENCODE = Pattern.compile("(URLENCODE|E)\\[\\[(?<data>.+?)\\]\\]");
|
||||||
String[] parts = template.split("\\?", 2);
|
|
||||||
|
|
||||||
if (parts.length == 2) {
|
private static String rewriteExplicitSections(String template) {
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
String input = parts[1];
|
StringBuilder sb = new StringBuilder();
|
||||||
Matcher matcher = ParsedTemplate.STANDARD_ANCHOR.matcher(input);
|
Matcher matcher = DOENCODE.matcher(template);
|
||||||
int idx = 0;
|
while (matcher.find()) {
|
||||||
while (matcher.find()) {
|
String rewrite = matcher.group("data");
|
||||||
String pre = input.substring(0, matcher.start());
|
String encoded = rewriteStaticsOnly(rewrite);
|
||||||
sb.append(URLEncoder.encode(pre, StandardCharsets.UTF_8));
|
matcher.appendReplacement(sb, encoded);
|
||||||
sb.append(matcher.group());
|
|
||||||
idx = matcher.end();
|
|
||||||
// matcher.appendReplacement(sb, "test-value" + idx);
|
|
||||||
}
|
|
||||||
sb.append(URLEncoder.encode(input.substring(idx), StandardCharsets.UTF_8));
|
|
||||||
return parts[0] + "?" + sb.toString();
|
|
||||||
} else {
|
|
||||||
return template;
|
|
||||||
}
|
}
|
||||||
|
matcher.appendTail(sb);
|
||||||
|
return sb.toString();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String rewriteStaticsOnly(String template) {
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String input = template;
|
||||||
|
Matcher matcher = ParsedTemplate.STANDARD_ANCHOR.matcher(input);
|
||||||
|
int idx = 0;
|
||||||
|
while (matcher.find()) {
|
||||||
|
String pre = input.substring(0, matcher.start());
|
||||||
|
sb.append(URLEncoder.encode(pre, StandardCharsets.UTF_8));
|
||||||
|
sb.append(matcher.group());
|
||||||
|
idx = matcher.end();
|
||||||
|
// matcher.appendReplacement(sb, "test-value" + idx);
|
||||||
|
}
|
||||||
|
sb.append(URLEncoder.encode(input.substring(idx), StandardCharsets.UTF_8));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,12 +120,19 @@ All other request fields are optional and have reasonable defaults:
|
|||||||
- **uri** - This is the URI that you might put into the URL bar of your
|
- **uri** - This is the URI that you might put into the URL bar of your
|
||||||
browser. There is no default.
|
browser. There is no default.
|
||||||
Example: `https://en.wikipedia.org/wiki/Leonhard_Euler`
|
Example: `https://en.wikipedia.org/wiki/Leonhard_Euler`
|
||||||
|
|
||||||
If the uri contains a question mark '?' as a query delimiter, then all
|
If the uri contains a question mark '?' as a query delimiter, then all
|
||||||
characters after this are automatically URL encoded. This is done for
|
embedded sections which are contained within `URLENCODE[[` ... `]]`
|
||||||
any literal part of the uri. If you use bindings in the uri as
|
sections are preprocessed by the HTTP driver. This allows you to keep
|
||||||
in `https://en.wikipedia.org/wiki/{topic}`, then it is up to you to
|
your test data in a recognizable form. This is done at startup, so there
|
||||||
ensure that the values are produced in a valid form for a URI. You can
|
is no cost during the test run. As an added convenience, binding points
|
||||||
use the `URLEncode()` binding function where needed to achieve this.
|
which are within the encoded block will be preserved, so
|
||||||
|
both `https://en.wikipedia.org/URLENCODE[[wiki/]]{topic}` and
|
||||||
|
`https://en.wikipedia.org/URLENCODE[[wiki/{topic}]]` will yield the same
|
||||||
|
configuration. For a terser form, you can use `E[[...]]`. You must also
|
||||||
|
ensure that the values that are inserted at binding points are produced
|
||||||
|
in a valid form for a URI. You can use the `URLEncode()`
|
||||||
|
binding function where needed to achieve this.
|
||||||
- **method** - An optional request method. If not provided, "GET" is assumed. Any method name will
|
- **method** - An optional request method. If not provided, "GET" is assumed. Any method name will
|
||||||
work here, even custom ones that are specific to a given target system. No validation is done for
|
work here, even custom ones that are specific to a given target system. No validation is done for
|
||||||
standard method names, as there is no way to know what method names may be valid.
|
standard method names, as there is no way to know what method names may be valid.
|
||||||
@@ -179,40 +186,40 @@ results. Support may be added for long-lived connections in a future release.
|
|||||||
are those which do not redirect from HTTPS to HTTP.
|
are those which do not redirect from HTTPS to HTTP.
|
||||||
|
|
||||||
- **diagnostics** - default: none - synonym: **diag**
|
- **diagnostics** - default: none - synonym: **diag**
|
||||||
example: `diag=brief,1000` - print diagnostics for every 1000th
|
example: `diag=brief,1000` - print diagnostics for every 1000th cycle,
|
||||||
cycle, including only brief details as explained below.
|
including only brief details as explained below.
|
||||||
|
|
||||||
This setting is a selector for what level of verbosity you will get
|
This setting is a selector for what level of verbosity you will get on
|
||||||
on the console. If you set this to true, you'll get every request
|
the console. If you set this to true, you'll get every request and
|
||||||
and response logged to console. This is only for verifying that a test
|
response logged to console. This is only for verifying that a test is
|
||||||
is configured and to spot check services before running higher scale
|
configured and to spot check services before running higher scale tests.
|
||||||
tests.
|
|
||||||
|
|
||||||
All of the data shown in diagnostics is post-hoc, directly from
|
All of the data shown in diagnostics is post-hoc, directly from the
|
||||||
the response provided by the internal HTTP client in the Java runtime.
|
response provided by the internal HTTP client in the Java runtime.
|
||||||
|
|
||||||
If you want finer control over how much information diagnostics
|
If you want finer control over how much information diagnostics
|
||||||
provides, you can specify a comma separated list of the below.
|
provides, you can specify a comma separated list of the below.
|
||||||
|
|
||||||
- headers - show headers
|
- headers - show headers
|
||||||
- stats - show basic stats of each request
|
- stats - show basic stats of each request
|
||||||
- data10 - show only the first 10 characters of each response body
|
- data10 - show only the first 10 characters of each response body
|
||||||
- data100 - show only the first 100 characters of each response body
|
- data100 - show only the first 100 characters of each response body
|
||||||
this setting supersedes `data10`
|
this setting supersedes `data10`
|
||||||
- data1000 - show only the first 1000 characters of each response body
|
- data1000 - show only the first 1000 characters of each response body
|
||||||
this setting supersedes `data100`
|
this setting supersedes `data100`
|
||||||
- data - show all of each response body
|
- data - show all of each response body this setting
|
||||||
this setting supersedes `data1000`
|
supersedes `data1000`
|
||||||
- redirects - show details for interstitial request which are made
|
- redirects - show details for interstitial request which are made
|
||||||
when the client follows a redirect directive like a `location` header.
|
when the client follows a redirect directive like a `location`
|
||||||
- requests - show details for requests
|
header.
|
||||||
- responses - show details for responses
|
- requests - show details for requests
|
||||||
- brief - Show headers, stats, requests, responses, and 10 characters
|
- responses - show details for responses
|
||||||
- all - Show everything, including full payloads and redirects
|
- brief - Show headers, stats, requests, responses, and 10 characters
|
||||||
- a modulo - any number, like 3000 - causes the diagnostics to be
|
- all - Show everything, including full payloads and redirects
|
||||||
reported only on this cycle modulo. If you set `diag=300,brief`
|
- a modulo - any number, like 3000 - causes the diagnostics to be
|
||||||
then you will get the brief diagnostic output for every 300th
|
reported only on this cycle modulo. If you set `diag=300,brief`
|
||||||
response.
|
then you will get the brief diagnostic output for every 300th
|
||||||
|
response.
|
||||||
|
|
||||||
The requests, responses, and redirects setting work intersectionally.
|
The requests, responses, and redirects setting work intersectionally.
|
||||||
For example, if you specify responses, and redirect, but not requests,
|
For example, if you specify responses, and redirect, but not requests,
|
||||||
@@ -221,5 +228,5 @@ results. Support may be added for long-lived connections in a future release.
|
|||||||
|
|
||||||
All of the diagnostic filters are incrementally added.
|
All of the diagnostic filters are incrementally added.
|
||||||
|
|
||||||
- **timeout** - default: forever -
|
- **timeout** - default: forever - Sets the timeout of each request in
|
||||||
Sets the timeout of each request in milliseconds.
|
milliseconds.
|
||||||
|
|||||||
Reference in New Issue
Block a user