1010import javax .servlet .http .HttpServletResponse ;
1111
1212public class ThreadResourceAbuse extends HttpServlet {
13+ static final int DEFAULT_RETRY_AFTER = 5 *1000 ;
14+ static final int MAX_RETRY_AFTER = 10 *1000 ;
15+
1316 protected void doGet (HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException {
1417 // Get thread pause time from request parameter
1518 String delayTimeStr = request .getParameter ("DelayTime" );
@@ -20,6 +23,15 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
2023 }
2124 }
2225
26+ protected void doGet2 (HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException {
27+ // Get thread pause time from request parameter
28+ try {
29+ int delayTime = request .getParameter ("nodelay" ) != null ? 0 : Integer .valueOf (request .getParameter ("DelayTime" ));
30+ new UncheckedSyncAction (delayTime ).start ();
31+ } catch (NumberFormatException e ) {
32+ }
33+ }
34+
2335 protected void doPost (HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException {
2436 // Get thread pause time from init container parameter
2537 String delayTimeStr = getServletContext ().getInitParameter ("DelayTime" );
@@ -78,11 +90,43 @@ public CheckedSyncAction(int waitTime) {
7890 public void run () {
7991 try {
8092 if (waitTime > 0 && waitTime < 5000 ) {
81- Thread .sleep (waitTime );
93+ Thread .sleep (waitTime );
94+ // Do other updates
95+ }
96+ } catch (InterruptedException e ) {
97+ }
98+ }
99+ }
100+
101+ class CheckedSyncAction2 extends Thread {
102+ int waitTime ;
103+
104+ public CheckedSyncAction2 (int waitTime ) {
105+ this .waitTime = waitTime ;
106+ }
107+
108+ // GOOD: enforce an upper limit on wait time
109+ @ Override
110+ public void run () {
111+ try {
112+ if (waitTime >= 5000 ) {
113+ // No action
114+ } else {
115+ Thread .sleep (waitTime );
116+ }
82117 // Do other updates
118+ } catch (InterruptedException e ) {
83119 }
84- } catch (InterruptedException e ) {
85- }
120+ }
121+ }
122+
123+ protected void doPost2 (HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException {
124+ // Get thread pause time from init container parameter
125+ String delayTimeStr = getServletContext ().getInitParameter ("DelayTime" );
126+ try {
127+ int delayTime = Integer .valueOf (delayTimeStr );
128+ new CheckedSyncAction2 (delayTime ).start ();
129+ } catch (NumberFormatException e ) {
86130 }
87131 }
88132
@@ -105,4 +149,47 @@ protected void doHead(HttpServletRequest request, HttpServletResponse response)
105149 }
106150 }
107151 }
152+
153+ int parseReplyAfter (String value ) {
154+ if (value == null || value .isEmpty ()) {
155+ return DEFAULT_RETRY_AFTER ;
156+ }
157+
158+ try {
159+ int n = Integer .parseInt (value );
160+ if (n < 0 ) {
161+ return DEFAULT_RETRY_AFTER ;
162+ }
163+
164+ return Math .min (n , MAX_RETRY_AFTER );
165+ } catch (NumberFormatException e ) {
166+ return DEFAULT_RETRY_AFTER ;
167+ }
168+ }
169+
170+ protected void doHead2 (HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException {
171+ // Get thread pause time from request header
172+ String header = request .getHeader ("Retry-After" );
173+ int retryAfter = Integer .parseInt (header );
174+
175+ try {
176+ // BAD: wait for retry-after without input validation
177+ Thread .sleep (retryAfter );
178+ } catch (InterruptedException ignore ) {
179+ // ignore
180+ }
181+ }
182+
183+ protected void doHead3 (HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException {
184+ // Get thread pause time from request header
185+ String header = request .getHeader ("Retry-After" );
186+ int retryAfter = parseReplyAfter (header );
187+
188+ try {
189+ // GOOD: wait for retry-after with input validation
190+ Thread .sleep (retryAfter );
191+ } catch (InterruptedException ignore ) {
192+ // ignore
193+ }
194+ }
108195}
0 commit comments