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