2929import java .nio .charset .Charset ;
3030import java .security .AccessController ;
3131import java .security .PrivilegedAction ;
32- import java .time .ZoneId ;
33- import java .time .ZonedDateTime ;
34- import java .time .format .DateTimeFormatter ;
35- import java .time .format .DateTimeFormatterBuilder ;
36- import java .time .format .SignStyle ;
3732import java .util .BitSet ;
3833import java .util .Collections ;
39- import java .util .HashMap ;
4034import java .util .Iterator ;
4135import java .util .LinkedHashMap ;
4236import java .util .Locale ;
4741import java .util .regex .Matcher ;
4842import java .util .regex .Pattern ;
4943
50- import static java .time .temporal .ChronoField .DAY_OF_MONTH ;
51- import static java .time .temporal .ChronoField .DAY_OF_WEEK ;
52- import static java .time .temporal .ChronoField .HOUR_OF_DAY ;
53- import static java .time .temporal .ChronoField .MINUTE_OF_HOUR ;
54- import static java .time .temporal .ChronoField .MONTH_OF_YEAR ;
55- import static java .time .temporal .ChronoField .SECOND_OF_MINUTE ;
56- import static java .time .temporal .ChronoField .YEAR ;
57-
5844/**
5945 * A logger that logs deprecation notices.
6046 */
@@ -165,73 +151,14 @@ public void deprecatedAndMaybeLog(final String key, final String msg, final Obje
165151 Build .CURRENT .isSnapshot () ? "-SNAPSHOT" : "" ,
166152 Build .CURRENT .shortHash ());
167153
168- /*
169- * RFC 7234 section 5.5 specifies that the warn-date is a quoted HTTP-date. HTTP-date is defined in RFC 7234 Appendix B as being from
170- * RFC 7231 section 7.1.1.1. RFC 7231 specifies an HTTP-date as an IMF-fixdate (or an obs-date referring to obsolete formats). The
171- * grammar for IMF-fixdate is specified as 'day-name "," SP date1 SP time-of-day SP GMT'. Here, day-name is
172- * (Mon|Tue|Wed|Thu|Fri|Sat|Sun). Then, date1 is 'day SP month SP year' where day is 2DIGIT, month is
173- * (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec), and year is 4DIGIT. Lastly, time-of-day is 'hour ":" minute ":" second' where
174- * hour is 2DIGIT, minute is 2DIGIT, and second is 2DIGIT. Finally, 2DIGIT and 4DIGIT have the obvious definitions.
175- */
176- private static final DateTimeFormatter RFC_7231_DATE_TIME ;
177-
178- static {
179- final Map <Long , String > dow = new HashMap <>();
180- dow .put (1L , "Mon" );
181- dow .put (2L , "Tue" );
182- dow .put (3L , "Wed" );
183- dow .put (4L , "Thu" );
184- dow .put (5L , "Fri" );
185- dow .put (6L , "Sat" );
186- dow .put (7L , "Sun" );
187- final Map <Long , String > moy = new HashMap <>();
188- moy .put (1L , "Jan" );
189- moy .put (2L , "Feb" );
190- moy .put (3L , "Mar" );
191- moy .put (4L , "Apr" );
192- moy .put (5L , "May" );
193- moy .put (6L , "Jun" );
194- moy .put (7L , "Jul" );
195- moy .put (8L , "Aug" );
196- moy .put (9L , "Sep" );
197- moy .put (10L , "Oct" );
198- moy .put (11L , "Nov" );
199- moy .put (12L , "Dec" );
200- RFC_7231_DATE_TIME = new DateTimeFormatterBuilder ()
201- .parseCaseInsensitive ()
202- .parseLenient ()
203- .optionalStart ()
204- .appendText (DAY_OF_WEEK , dow )
205- .appendLiteral (", " )
206- .optionalEnd ()
207- .appendValue (DAY_OF_MONTH , 2 , 2 , SignStyle .NOT_NEGATIVE )
208- .appendLiteral (' ' )
209- .appendText (MONTH_OF_YEAR , moy )
210- .appendLiteral (' ' )
211- .appendValue (YEAR , 4 )
212- .appendLiteral (' ' )
213- .appendValue (HOUR_OF_DAY , 2 )
214- .appendLiteral (':' )
215- .appendValue (MINUTE_OF_HOUR , 2 )
216- .optionalStart ()
217- .appendLiteral (':' )
218- .appendValue (SECOND_OF_MINUTE , 2 )
219- .optionalEnd ()
220- .appendLiteral (' ' )
221- .appendOffset ("+HHMM" , "GMT" )
222- .toFormatter (Locale .getDefault (Locale .Category .FORMAT ));
223- }
224-
225- private static final String STARTUP_TIME = RFC_7231_DATE_TIME .format (ZonedDateTime .now (ZoneId .of ("GMT" )));
226-
227154 /**
228155 * Regular expression to test if a string matches the RFC7234 specification for warning headers. This pattern assumes that the warn code
229156 * is always 299. Further, this pattern assumes that the warn agent represents a version of Elasticsearch including the build hash.
230157 */
231- public static Pattern WARNING_HEADER_PATTERN = Pattern .compile (
158+ public static final Pattern WARNING_HEADER_PATTERN = Pattern .compile (
232159 "299 " + // warn code
233160 "Elasticsearch-\\ d+\\ .\\ d+\\ .\\ d+(?:-(?:alpha|beta|rc)\\ d+)?(?:-SNAPSHOT)?-(?:[a-f0-9]{7}|Unknown) " + // warn agent
234- "\" ((?:\t | |!|[\\ x23-\\ x5B]|[\\ x5D-\\ x7E]|[\\ x80-\\ xFF]|\\ \\ |\\ \\ \" )*)\" " + // quoted warning value, captured
161+ "\" ((?:\t | |!|[\\ x23-\\ x5B]|[\\ x5D-\\ x7E]|[\\ x80-\\ xFF]|\\ \\ |\\ \\ \" )*)\" ( " + // quoted warning value, captured
235162 // quoted RFC 1123 date format
236163 "\" " + // opening quote
237164 "(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), " + // weekday
@@ -240,36 +167,31 @@ public void deprecatedAndMaybeLog(final String key, final String msg, final Obje
240167 "\\ d{4} " + // 4-digit year
241168 "\\ d{2}:\\ d{2}:\\ d{2} " + // (two-digit hour):(two-digit minute):(two-digit second)
242169 "GMT" + // GMT
243- "\" " ); // closing quote
170+ "\" )? " ); // closing quote (optional, since an older version can still send a warn-date)
244171
245172 /**
246173 * Extracts the warning value from the value of a warning header that is formatted according to RFC 7234. That is, given a string
247- * {@code 299 Elasticsearch-6.0.0 "warning value" "Sat, 25 Feb 2017 10:27:43 GMT"}, the return value of this method would be {@code
248- * warning value}.
174+ * {@code 299 Elasticsearch-6.0.0 "warning value"}, the return value of this method would be {@code warning value}.
249175 *
250176 * @param s the value of a warning header formatted according to RFC 7234.
251177 * @return the extracted warning value
252178 */
253179 public static String extractWarningValueFromWarningHeader (final String s ) {
254180 /*
255181 * We know the exact format of the warning header, so to extract the warning value we can skip forward from the front to the first
256- * quote, and skip backwards from the end to the penultimate quote:
182+ * quote and we know the last quote is at the end of the string
257183 *
258- * 299 Elasticsearch-6.0.0 "warning value" "Sat, 25, Feb 2017 10:27:43 GMT"
259- * ^ ^ ^
260- * firstQuote penultimateQuote lastQuote
261- *
262- * We do it this way rather than seeking forward after the first quote because there could be escaped quotes in the warning value
263- * but since there are none in the warning date, we can skip backwards to find the quote that closes the quoted warning value.
184+ * 299 Elasticsearch-6.0.0 "warning value"
185+ * ^ ^
186+ * firstQuote lastQuote
264187 *
265188 * We parse this manually rather than using the capturing regular expression because the regular expression involves a lot of
266189 * backtracking and carries a performance penalty. However, when assertions are enabled, we still use the regular expression to
267190 * verify that we are maintaining the warning header format.
268191 */
269192 final int firstQuote = s .indexOf ('\"' );
270- final int lastQuote = s .lastIndexOf ('\"' );
271- final int penultimateQuote = s .lastIndexOf ('\"' , lastQuote - 1 );
272- final String warningValue = s .substring (firstQuote + 1 , penultimateQuote - 2 );
193+ final int lastQuote = s .length () - 1 ;
194+ final String warningValue = s .substring (firstQuote + 1 , lastQuote );
273195 assert assertWarningValue (s , warningValue );
274196 return warningValue ;
275197 }
@@ -299,7 +221,6 @@ void deprecated(final Set<ThreadContext> threadContexts, final String message, f
299221 deprecated (threadContexts , message , true , params );
300222 }
301223
302-
303224 void deprecated (final Set <ThreadContext > threadContexts , final String message , final boolean log , final Object ... params ) {
304225 final Iterator <ThreadContext > iterator = threadContexts .iterator ();
305226
@@ -338,9 +259,7 @@ public Void run() {
338259 * @return a warning value formatted according to RFC 7234
339260 */
340261 public static String formatWarning (final String s ) {
341- return WARNING_PREFIX + " "
342- + "\" " + escapeAndEncode (s ) + "\" " + " "
343- + "\" " + STARTUP_TIME + "\" " ;
262+ return WARNING_PREFIX + " " + "\" " + escapeAndEncode (s ) + "\" " ;
344263 }
345264
346265 /**
@@ -451,7 +370,7 @@ static String encode(final String s) {
451370 int startIndex = i ;
452371 do {
453372 i ++;
454- } while (i < s .length () && ! doesNotNeedEncoding .get (s .charAt (i )));
373+ } while (i < s .length () && doesNotNeedEncoding .get (s .charAt (i )) == false );
455374
456375 final byte [] bytes = s .substring (startIndex , i ).getBytes (UTF_8 );
457376 // noinspection ForLoopReplaceableByForEach
0 commit comments