@@ -114,16 +114,95 @@ public HttpEntity getEntity() {
114
114
"GMT" + // GMT
115
115
"\" )?" ); // closing quote (optional, since an older version can still send a warn-date)
116
116
117
+ /**
118
+ * Optimized regular expression to test if a string matches the RFC 1123 date
119
+ * format (with quotes and leading space). Start/end of line characters and
120
+ * atomic groups are used to prevent backtracking.
121
+ */
122
+ private static final Pattern WARNING_HEADER_DATE_PATTERN = Pattern .compile (
123
+ "^ " + // start of line, leading space
124
+ // quoted RFC 1123 date format
125
+ "\" " + // opening quote
126
+ "(?>Mon|Tue|Wed|Thu|Fri|Sat|Sun), " + // day of week, atomic group to prevent backtracking
127
+ "\\ d{2} " + // 2-digit day
128
+ "(?>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) " + // month, atomic group to prevent backtracking
129
+ "\\ d{4} " + // 4-digit year
130
+ "\\ d{2}:\\ d{2}:\\ d{2} " + // (two-digit hour):(two-digit minute):(two-digit second)
131
+ "GMT" + // GMT
132
+ "\" $" ); // closing quote (optional, since an older version can still send a warn-date), end of line
133
+
134
+ /**
135
+ * Length of RFC 1123 format (with quotes and leading space), used in
136
+ * matchWarningHeaderPatternByPrefix(String).
137
+ */
138
+ private static final int WARNING_HEADER_DATE_LENGTH = 0
139
+ + 1
140
+ + 1
141
+ + 3 + 1 + 1
142
+ + 2 + 1
143
+ + 3 + 1
144
+ + 4 + 1
145
+ + 2 + 1 + 2 + 1 + 2 + 1
146
+ + 3
147
+ + 1 ;
148
+
149
+ /**
150
+ * Tests if a string matches the RFC 7234 specification for warning headers.
151
+ * This assumes that the warn code is always 299 and the warn agent is always
152
+ * Elasticsearch.
153
+ *
154
+ * @param s the value of a warning header formatted according to RFC 7234
155
+ * @return {@code true} if the input string matches the specification
156
+ */
157
+ private static boolean matchWarningHeaderPatternByPrefix (final String s ) {
158
+ return s .startsWith ("299 Elasticsearch-" );
159
+ }
160
+
161
+ /**
162
+ * Refer to org.elasticsearch.common.logging.DeprecationLogger
163
+ */
164
+ private static String extractWarningValueFromWarningHeader (final String s ) {
165
+ String warningHeader = s ;
166
+
167
+ /*
168
+ * The following block tests for the existence of a RFC 1123 date in the warning header. If the date exists, it is removed for
169
+ * extractWarningValueFromWarningHeader(String) to work properly (as it does not handle dates).
170
+ */
171
+ if (s .length () > WARNING_HEADER_DATE_LENGTH ) {
172
+ final String possibleDateString = s .substring (s .length () - WARNING_HEADER_DATE_LENGTH );
173
+ final Matcher matcher = WARNING_HEADER_DATE_PATTERN .matcher (possibleDateString );
174
+
175
+ if (matcher .matches ()) {
176
+ warningHeader = warningHeader .substring (0 , s .length () - WARNING_HEADER_DATE_LENGTH );
177
+ }
178
+ }
179
+
180
+ final int firstQuote = warningHeader .indexOf ('\"' );
181
+ final int lastQuote = warningHeader .length () - 1 ;
182
+ final String warningValue = warningHeader .substring (firstQuote + 1 , lastQuote );
183
+ assert assertWarningValue (s , warningValue );
184
+ return warningValue ;
185
+ }
186
+
187
+ /**
188
+ * Refer to org.elasticsearch.common.logging.DeprecationLogger
189
+ */
190
+ private static boolean assertWarningValue (final String s , final String warningValue ) {
191
+ final Matcher matcher = WARNING_HEADER_PATTERN .matcher (s );
192
+ final boolean matches = matcher .matches ();
193
+ assert matches ;
194
+ return matcher .group (1 ).equals (warningValue );
195
+ }
196
+
117
197
/**
118
198
* Returns a list of all warning headers returned in the response.
119
199
*/
120
200
public List <String > getWarnings () {
121
201
List <String > warnings = new ArrayList <>();
122
202
for (Header header : response .getHeaders ("Warning" )) {
123
203
String warning = header .getValue ();
124
- final Matcher matcher = WARNING_HEADER_PATTERN .matcher (warning );
125
- if (matcher .matches ()) {
126
- warnings .add (matcher .group (1 ));
204
+ if (matchWarningHeaderPatternByPrefix (warning )) {
205
+ warnings .add (extractWarningValueFromWarningHeader (warning ));
127
206
} else {
128
207
warnings .add (warning );
129
208
}
0 commit comments