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

(-)src/protocol/http/org/apache/jmeter/protocol/http/util/accesslog/TCLogParser.java (-40 / +79 lines)
Lines 28-39 Link Here
28
import java.net.URLDecoder;
28
import java.net.URLDecoder;
29
import java.nio.charset.StandardCharsets;
29
import java.nio.charset.StandardCharsets;
30
import java.util.ArrayList;
30
import java.util.ArrayList;
31
import java.util.Arrays;
32
import java.util.Collections;
31
import java.util.List;
33
import java.util.List;
32
import java.util.StringTokenizer;
34
import java.util.StringTokenizer;
33
import java.util.zip.GZIPInputStream;
35
import java.util.zip.GZIPInputStream;
34
36
37
import org.apache.commons.lang3.StringUtils;
35
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
38
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
39
import org.apache.jmeter.protocol.http.util.HTTPConstants;
36
import org.apache.jmeter.testelement.TestElement;
40
import org.apache.jmeter.testelement.TestElement;
41
import org.apache.jmeter.util.JMeterUtils;
37
import org.slf4j.Logger;
42
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
43
import org.slf4j.LoggerFactory;
39
44
Lines 75-95 Link Here
75
public class TCLogParser implements LogParser {
80
public class TCLogParser implements LogParser {
76
    protected static final Logger log = LoggerFactory.getLogger(TCLogParser.class);
81
    protected static final Logger log = LoggerFactory.getLogger(TCLogParser.class);
77
82
78
    /*
83
    /**
79
     * TODO should these fields be public?
84
     * @deprecated since 5.1
80
     * They don't appear to be used externally.
85
     * Use {@link HTTPConstants#GET} instead
81
     * 
82
     * Also, are they any different from HTTPConstants.GET etc. ?
83
     * In some cases they seem to be used as the method name from the Tomcat log.
84
     * However the RMETHOD field is used as the value for HTTPSamplerBase.METHOD,
85
     * for which HTTPConstants is most appropriate.
86
     */
86
     */
87
    @Deprecated
87
    public static final String GET = "GET";
88
    public static final String GET = "GET";
88
89
90
    /**
91
     * @deprecated since 5.1
92
     * Use {@link HTTPConstants#POST} instead
93
     */
94
    @Deprecated
89
    public static final String POST = "POST";
95
    public static final String POST = "POST";
90
96
97
    /**
98
     * @deprecated since 5.1
99
     * Use {@link HTTPConstants#HEAD} instead
100
     */
101
    @Deprecated
91
    public static final String HEAD = "HEAD";
102
    public static final String HEAD = "HEAD";
92
103
104
    private static final List<String> HTTP_METHODS;
105
    static {
106
        List<String> defaultMethods = new ArrayList<>(Arrays.asList(
107
            HTTPConstants.GET,
108
            HTTPConstants.POST,
109
            HTTPConstants.HEAD,
110
            HTTPConstants.PUT,
111
            HTTPConstants.OPTIONS,
112
            HTTPConstants.TRACE,
113
            HTTPConstants.DELETE,
114
            HTTPConstants.PATCH,
115
            HTTPConstants.PROPFIND,
116
            HTTPConstants.PROPPATCH,
117
            HTTPConstants.MKCOL,
118
            HTTPConstants.COPY,
119
            HTTPConstants.MOVE,
120
            HTTPConstants.LOCK,
121
            HTTPConstants.UNLOCK,
122
            HTTPConstants.REPORT,
123
            HTTPConstants.MKCALENDAR,
124
            HTTPConstants.SEARCH
125
        ));
126
        String userDefinedMethods = JMeterUtils.getPropDefault(
127
                "httpsampler.user_defined_methods", "");
128
        if (StringUtils.isNotBlank(userDefinedMethods)) {
129
            defaultMethods.addAll(Arrays.asList(userDefinedMethods.split("\\s*,\\s*")));
130
        }
131
        HTTP_METHODS = Collections.unmodifiableList(defaultMethods);
132
    }
133
93
    /** protected members * */
134
    /** protected members * */
94
    protected String RMETHOD = null;
135
    protected String RMETHOD = null;
95
136
Lines 278-284 Link Here
278
        // we clean the line to get
319
        // we clean the line to get
279
        // rid of extra stuff
320
        // rid of extra stuff
280
        String cleanedLine = this.cleanURL(line);
321
        String cleanedLine = this.cleanURL(line);
281
        log.debug("parsing line: " + line);
322
        log.debug("parsing line: {}", line);
282
        // now we set request method
323
        // now we set request method
283
        el.setProperty(HTTPSamplerBase.METHOD, RMETHOD);
324
        el.setProperty(HTTPSamplerBase.METHOD, RMETHOD);
284
        if (FILTER != null) {
325
        if (FILTER != null) {
Lines 353-378 Link Here
353
            while (tokens.hasMoreTokens()) {
394
            while (tokens.hasMoreTokens()) {
354
                String token = tokens.nextToken();
395
                String token = tokens.nextToken();
355
                if (checkMethod(token)) {
396
                if (checkMethod(token)) {
356
                    // we tokenzie it using space and escape
397
                    url = extractURL(url, token);
357
                    // the while loop. Only the first matching
358
                    // token will be used
359
                    StringTokenizer token2 = this.tokenize(token, " ");
360
                    while (token2.hasMoreTokens()) {
361
                        String t = (String) token2.nextElement();
362
                        if (t.equalsIgnoreCase(GET)) {
363
                            RMETHOD = GET;
364
                        } else if (t.equalsIgnoreCase(POST)) {
365
                            RMETHOD = POST;
366
                        } else if (t.equalsIgnoreCase(HEAD)) {
367
                            RMETHOD = HEAD;
368
                        }
369
                        // there should only be one token
370
                        // that starts with slash character
371
                        if (t.startsWith("/")) {
372
                            url = t;
373
                            break;
374
                        }
375
                    }
376
                    break;
398
                    break;
377
                }
399
                }
378
            }
400
            }
Lines 382-387 Link Here
382
        return url;
404
        return url;
383
    }
405
    }
384
406
407
    private String extractURL(String url, String token) {
408
        // we tokenize it using space and escape
409
        // the while loop. Only the first matching
410
        // token will be used
411
        StringTokenizer token2 = this.tokenize(token, " ");
412
        while (token2.hasMoreTokens()) {
413
            String t = token2.nextToken();
414
            for (String httpMethod: HTTP_METHODS) {
415
                if (t.equalsIgnoreCase(httpMethod)) {
416
                    RMETHOD = httpMethod;
417
                    break;
418
                }
419
            }
420
            // there should only be one token
421
            // that starts with slash character
422
            if (t.startsWith("/")) {
423
                return t;
424
            }
425
        }
426
        return url;
427
    }
428
385
    /**
429
    /**
386
     * The method checks for <code>POST</code>, <code>GET</code> and <code>HEAD</code> methods currently.
430
     * The method checks for <code>POST</code>, <code>GET</code> and <code>HEAD</code> methods currently.
387
     * The other methods aren't supported yet.
431
     * The other methods aren't supported yet.
Lines 390-407 Link Here
390
     * @return <code>true</code> if method is supported, <code>false</code> otherwise
434
     * @return <code>true</code> if method is supported, <code>false</code> otherwise
391
     */
435
     */
392
    public boolean checkMethod(String text) {
436
    public boolean checkMethod(String text) {
393
        if (text.contains("GET")) {
437
        for (String httpMethod: HTTP_METHODS) {
394
            this.RMETHOD = GET;
438
            if (text.contains(httpMethod)) {
395
            return true;
439
                this.RMETHOD = httpMethod;
396
        } else if (text.contains("POST")) {
440
                return true;
397
            this.RMETHOD = POST;
441
            }
398
            return true;
399
        } else if (text.contains("HEAD")) {
400
            this.RMETHOD = HEAD;
401
            return true;
402
        } else {
403
            return false;
404
        }
442
        }
443
        return false;
405
    }
444
    }
406
445
407
    /**
446
    /**
(-)test/src/org/apache/jmeter/protocol/http/util/accesslog/TestTCLogParser.java (+30 lines)
Lines 25-30 Link Here
25
25
26
import org.apache.jmeter.junit.JMeterTestCase;
26
import org.apache.jmeter.junit.JMeterTestCase;
27
import org.apache.jmeter.protocol.http.sampler.HTTPNullSampler;
27
import org.apache.jmeter.protocol.http.sampler.HTTPNullSampler;
28
import org.hamcrest.CoreMatchers;
29
import org.junit.Assert;
28
import org.junit.Test;
30
import org.junit.Test;
29
31
30
// TODO - more tests needed
32
// TODO - more tests needed
Lines 69-72 Link Here
69
            assertNull(tclp.stripFile(res, new HTTPNullSampler()));
71
            assertNull(tclp.stripFile(res, new HTTPNullSampler()));
70
        }
72
        }
71
73
74
        @Test
75
        public void testAWSLogsOPTIONSNoQueryParameter() throws Exception {
76
            String awsLog = "https 2018-11-05T12:55:39.303736Z app/prod-WebTierLoadBalancer/abf54370cbaedbc3 109.147.85.126:55054"
77
                    + " 10.248.3.69:8443 0.000 0.001 0.000 200 200 286 485 \"OPTIONS /free/api/1/virtual-portfolio HTTP/2.0\""
78
                    + " \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100"
79
                    + " Safari/537.36 OPR/56.0.3051.52\" ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 arn:aws:elasticloadbalancing:eu-west-1:"
80
                    + "544611607123:targetgroup/prod-FreeuserGatewayTargetGroup/b930521f9e6c192d \"Root=1-5be03dcb-a99d15f81d0716bcf502eb63\""
81
                    + " \"api-prod.ii.co.uk\" \"arn:aws:acm:eu-west-1:544611607123:certificate/989815d5-8e0b-474b-a93f-6ac0c0780b6a\""
82
                    + " 1 2018-11-05T12:55:39.302000Z \"forward\" \"-\"";
83
            String res = tclp.cleanURL(awsLog);
84
            Assert.assertThat(res, CoreMatchers.is("/free/api/1/virtual-portfolio"));
85
            Assert.assertThat(tclp.stripFile(res, new HTTPNullSampler()), CoreMatchers.nullValue());
86
        }
87
88
        @Test
89
        public void testAWSLogsOPTIONSWithQueryParameter() throws Exception {
90
            String awsLog = "https 2018-11-05T12:55:19.717286Z app/prod-WebTierLoadBalancer/abf54370cbaedbc3 83.100.225.10:50054"
91
                    + " 10.248.130.234:8443 0.000 0.002 0.000 200 200 53 485 \"OPTIONS /free/api/1/virtual-portfolio/258226/item?pageNo=1 HTTP/2.0\""
92
                    + " \"Mozilla/5.0 (iPad; CPU OS 11_0_3 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A432 Safari/604.1\""
93
                    + " ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 arn:aws:elasticloadbalancing:eu-west-1:544611607123:"
94
                    + "targetgroup/prod-FreeuserGatewayTargetGroup/b930521f9e6c192d \"Root=1-5be03db7-2e5563ecd086f154e5f7195c\""
95
                    + " \"api-prod.ii.co.uk\" \"arn:aws:acm:eu-west-1:544611607123:certificate/989815d5-8e0b-474b-a93f-6ac0c0780b6a\""
96
                    + " 1 2018-11-05T12:55:19.715000Z \"forward\" \"-\"";
97
            String res = tclp.cleanURL(awsLog);
98
            Assert.assertThat(res, CoreMatchers.is("/free/api/1/virtual-portfolio/258226/item?pageNo=1"));
99
            Assert.assertThat(tclp.stripFile(res, new HTTPNullSampler()), CoreMatchers.is("pageNo=1"));
100
            Assert.assertThat(tclp.URL_PATH, CoreMatchers.is("/free/api/1/virtual-portfolio/258226/item"));
101
        }
72
}
102
}

Return to bug 62885