View | Details | Raw Unified | Return to bug 53960
Collapse All | Expand All

(-)test/org/apache/catalina/startup/SimpleHttpClient.java (-32 / +153 lines)
Lines 39-45 Link Here
39
 */
39
 */
40
public abstract class SimpleHttpClient {
40
public abstract class SimpleHttpClient {
41
    public static final String TEMP_DIR =
41
    public static final String TEMP_DIR =
42
        System.getProperty("java.io.tmpdir");
42
            System.getProperty("java.io.tmpdir");
43
43
44
    public static final String CRLF = "\r\n";
44
    public static final String CRLF = "\r\n";
45
45
Lines 48-61 Link Here
48
    public static final String REDIRECT_302 = "HTTP/1.1 302";
48
    public static final String REDIRECT_302 = "HTTP/1.1 302";
49
    public static final String FAIL_400 = "HTTP/1.1 400";
49
    public static final String FAIL_400 = "HTTP/1.1 400";
50
    public static final String FAIL_404 = "HTTP/1.1 404";
50
    public static final String FAIL_404 = "HTTP/1.1 404";
51
    public static final String TIMEOUT_408 = "HTTP/1.1 408";
51
    public static final String FAIL_413 = "HTTP/1.1 413";
52
    public static final String FAIL_413 = "HTTP/1.1 413";
52
    public static final String FAIL_50X = "HTTP/1.1 50";
53
    public static final String FAIL_50X = "HTTP/1.1 50";
53
    public static final String FAIL_500 = "HTTP/1.1 500";
54
    public static final String FAIL_500 = "HTTP/1.1 500";
54
    public static final String FAIL_501 = "HTTP/1.1 501";
55
    public static final String FAIL_501 = "HTTP/1.1 501";
55
56
57
    private static final String CONTENT_LENGTH_HEADER_PREFIX =
58
            "Content-Length: ";
59
60
    protected static final String SESSION_COOKIE_NAME = "JSESSIONID";
61
    protected static final String SESSION_PARAMETER_NAME =
62
            SESSION_COOKIE_NAME.toLowerCase();
63
64
    private static final String COOKIE_HEADER_PREFIX = "Set-Cookie: ";
56
    private static final String SESSION_COOKIE_HEADER_PREFIX =
65
    private static final String SESSION_COOKIE_HEADER_PREFIX =
57
        "Set-Cookie: JSESSIONID=";
66
            COOKIE_HEADER_PREFIX + SESSION_COOKIE_NAME + "=";
58
67
68
    private static final String REDIRECT_HEADER_PREFIX = "Location: ";
69
    protected static final String SESSION_PATH_PARAMETER_PREFIX =
70
            SESSION_PARAMETER_NAME + "=";
71
    protected static final String SESSION_PATH_PARAMETER_TAILS = CRLF + ";?";
72
73
    private static final String ELEMENT_HEAD = "<";
74
    private static final String ELEMENT_TAIL = ">";
75
    private static final String RESOURCE_TAG = "a";
76
    private static final String LOGIN_TAG = "form";
77
59
    private Socket socket;
78
    private Socket socket;
60
    private Writer writer;
79
    private Writer writer;
61
    private BufferedReader reader;
80
    private BufferedReader reader;
Lines 63-75 Link Here
63
82
64
    private String[] request;
83
    private String[] request;
65
    private boolean useContinue = false;
84
    private boolean useContinue = false;
85
    private boolean useCookies = true;
66
    private int requestPause = 1000;
86
    private int requestPause = 1000;
67
87
68
    private String responseLine;
88
    private String responseLine;
69
    private List<String> responseHeaders = new ArrayList<>();
89
    private List<String> responseHeaders = new ArrayList<>();
70
    private String responseBody;
90
    private String sessionId;
71
    private boolean useContentLength;
91
    private boolean useContentLength;
92
    private int contentLength;
93
    private String redirectUri;
72
94
95
    private String responseBody;
96
    private List<String> bodyUriElments = new ArrayList<>();
97
73
    protected void setPort(int thePort) {
98
    protected void setPort(int thePort) {
74
        port = thePort;
99
        port = thePort;
75
    }
100
    }
Lines 86-91 Link Here
86
        return useContinue;
111
        return useContinue;
87
    }
112
    }
88
113
114
    public void setUseCookies(boolean theUseCookiesFlag) {
115
        useCookies = theUseCookiesFlag;
116
    }
117
118
    public boolean getUseCookies() {
119
        return useCookies;
120
    }
121
89
    public void setRequestPause(int theRequestPause) {
122
    public void setRequestPause(int theRequestPause) {
90
        requestPause = theRequestPause;
123
        requestPause = theRequestPause;
91
    }
124
    }
Lines 106-123 Link Here
106
        useContentLength = b;
139
        useContentLength = b;
107
    }
140
    }
108
141
142
    public void setSessionId(String theSessionId) {
143
        sessionId = theSessionId;
144
    }
145
109
    public String getSessionId() {
146
    public String getSessionId() {
110
        for (String header : responseHeaders) {
147
        return sessionId;
111
            if (header.startsWith(SESSION_COOKIE_HEADER_PREFIX)) {
112
                header = header.substring(SESSION_COOKIE_HEADER_PREFIX.length());
113
                header = header.substring(0, header.indexOf(';'));
114
                return header;
115
            }
116
        }
117
        return null;
118
    }
148
    }
119
149
120
    public void connect(int connectTimeout, int soTimeout) throws UnknownHostException, IOException {
150
    public String getRedirectUri() {
151
        return redirectUri;
152
    }
153
154
    public void connect(int connectTimeout, int soTimeout)
155
           throws UnknownHostException, IOException {
121
        final String encoding = "ISO-8859-1";
156
        final String encoding = "ISO-8859-1";
122
        SocketAddress addr = new InetSocketAddress("localhost", port);
157
        SocketAddress addr = new InetSocketAddress("localhost", port);
123
        socket = new Socket();
158
        socket = new Socket();
Lines 137-146 Link Here
137
        processRequest(true);
172
        processRequest(true);
138
    }
173
    }
139
174
140
    public void processRequest(boolean readBody) throws IOException, InterruptedException {
175
    public void processRequest(boolean wantBody)
176
            throws IOException, InterruptedException {
141
        sendRequest();
177
        sendRequest();
142
178
143
        readResponse(readBody);
179
        readResponse(wantBody);
144
180
145
    }
181
    }
146
182
Lines 158-170 Link Here
158
        }
194
        }
159
    }
195
    }
160
196
161
    public void readResponse(boolean readBody) throws IOException {
197
    public void readResponse(boolean wantBody) throws IOException {
162
        // Reset fields use to hold response
198
        // clear any residual data before starting on this response
163
        responseLine = null;
164
        responseHeaders.clear();
199
        responseHeaders.clear();
165
        responseBody = null;
200
        responseBody = null;
201
        bodyUriElments.clear();
166
202
167
        // Read the response
203
        // Read the response status line
168
        responseLine = readLine();
204
        responseLine = readLine();
169
205
170
        // Is a 100 continue response expected?
206
        // Is a 100 continue response expected?
Lines 179-213 Link Here
179
            }
215
            }
180
        }
216
        }
181
217
182
        // Put the headers into the map
218
        // Put the headers into a map, and process interesting ones
219
        processHeaders();
220
221
        // Read the body, if requested and if one exists
222
        processBody(wantBody);
223
224
        if (isResponse408()) {
225
            // the session has timed out
226
            sessionId = null;
227
        }
228
    }
229
230
    /*
231
     * Accumulate the response headers into a map, and extract
232
     * interesting details at the same time
233
     */
234
    private void processHeaders() throws IOException {
235
        // Reset response fields
236
        redirectUri = null;
237
        contentLength = -1;
238
183
        String line = readLine();
239
        String line = readLine();
184
        int cl = -1;
240
        while ((line != null) && (line.length() > 0)) {
185
        while (line!=null && line.length() > 0) {
186
            responseHeaders.add(line);
241
            responseHeaders.add(line);
242
            if (line.startsWith(CONTENT_LENGTH_HEADER_PREFIX)) {
243
                contentLength = Integer.parseInt(line.substring(16));
244
            }
245
            else if (line.startsWith(COOKIE_HEADER_PREFIX)) {
246
                if (useCookies) {
247
                    String temp = line.substring(
248
                            SESSION_COOKIE_HEADER_PREFIX.length());
249
                    temp = temp.substring(0, temp.indexOf(';'));
250
                    setSessionId(temp);
251
                }
252
            }
253
            else if (line.startsWith(REDIRECT_HEADER_PREFIX)) {
254
                redirectUri = line.substring(REDIRECT_HEADER_PREFIX.length());
255
            }
187
            line = readLine();
256
            line = readLine();
188
            if (line != null && line.startsWith("Content-Length: ")) {
189
                cl = Integer.parseInt(line.substring(16));
190
            }
191
        }
257
        }
258
    }
192
259
193
        // Read the body, if any
260
    /*
261
     * Read the body of the server response. Save its contents and
262
     * search it for uri-elements only if requested
263
     */
264
    private void processBody(boolean wantBody) throws IOException {
265
        // Read the body, if one exists
194
        StringBuilder builder = new StringBuilder();
266
        StringBuilder builder = new StringBuilder();
195
        if (readBody) {
267
        if (wantBody) {
196
            if (cl > -1 && useContentLength) {
268
            if (useContentLength && (contentLength > -1)) {
197
                char[] body = new char[cl];
269
                char[] body = new char[contentLength];
198
                reader.read(body);
270
                reader.read(body);
199
                builder.append(body);
271
                builder.append(body);
200
            } else {
272
            }
201
                line = readLine();
273
            else {
202
                while (line != null) {
274
                // not using content length, so just read it line by line
275
                String line = null;
276
                while ((line = readLine()) != null) {
203
                    builder.append(line);
277
                    builder.append(line);
204
                    line = readLine();
205
                }
278
                }
206
            }
279
            }
207
        }
280
        }
208
        responseBody = builder.toString();
281
        responseBody = builder.toString();
282
        extractUriElements(responseBody);
209
    }
283
    }
210
284
285
    /*
286
     * Scan an html body for useful html uri elements. If any are found,
287
     * then accumulate them. Test classes might not use them, but they
288
     * are collected anyway.
289
     */
290
    private void extractUriElements(String body) {
291
        if (body.length() > 0) {
292
            int ix = 0;
293
            while ((ix = extractUriElement(body, ix, RESOURCE_TAG)) > 0){}
294
            ix = 0;
295
            while ((ix = extractUriElement(body, ix, LOGIN_TAG)) > 0){}
296
        }
297
    }
298
299
    /*
300
     * Scan an html body for a given html uri element, starting from the
301
     * given index into the source string. If any are found, simply
302
     * accumulate them as literal strings, including angle brackets.
303
     * note: nested elements will not be collected.
304
     *
305
     * @param body HTTP body of the response
306
     * @param startIx offset into the body to resume the scan (for iteration)
307
     * @param elementName to scan for (only one at a time)
308
     * @returns the index into the body to continue the scan (for iteration)
309
     */
310
    private int extractUriElement(String body, int startIx, String elementName) {
311
        String detector = ELEMENT_HEAD + elementName + " ";
312
        int iStart = body.indexOf(detector, startIx);
313
        if (iStart > -1) {
314
            int iEnd = body.indexOf(ELEMENT_TAIL, iStart);
315
            if (iEnd < 0) {
316
                throw new IllegalArgumentException(
317
                        "Response body check failure.\n"
318
                        + "element [" + detector + "] is not terminated with ["
319
                        + ELEMENT_TAIL + "]\nActual: [" + body + "]");
320
            }
321
            String element = body.substring(iStart, iEnd);
322
            bodyUriElments.add(element);
323
            iStart += element.length();
324
        }
325
        return iStart;
326
    }
327
211
    public String readLine() throws IOException {
328
    public String readLine() throws IOException {
212
        return reader.readLine();
329
        return reader.readLine();
213
    }
330
    }
Lines 253-258 Link Here
253
        return getResponseLine().startsWith(FAIL_404);
370
        return getResponseLine().startsWith(FAIL_404);
254
    }
371
    }
255
372
373
    public boolean isResponse408() {
374
        return getResponseLine().startsWith(TIMEOUT_408);
375
    }
376
256
    public boolean isResponse413() {
377
    public boolean isResponse413() {
257
        return getResponseLine().startsWith(FAIL_413);
378
        return getResponseLine().startsWith(FAIL_413);
258
    }
379
    }

Return to bug 53960