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

(-)src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPSampler.java (-11 / +49 lines)
Lines 20-33 Link Here
20
import java.io.FileNotFoundException;
20
import java.io.FileNotFoundException;
21
import java.io.IOException;
21
import java.io.IOException;
22
import java.io.InputStream;
22
import java.io.InputStream;
23
24
import java.net.BindException;
23
import java.net.BindException;
25
import java.net.HttpURLConnection;
24
import java.net.HttpURLConnection;
26
import java.net.InetSocketAddress;
25
import java.net.InetSocketAddress;
27
import java.net.Proxy;
26
import java.net.Proxy;
28
import java.net.URL;
27
import java.net.URL;
29
import java.net.URLConnection;
28
import java.net.URLConnection;
30
29
import java.text.SimpleDateFormat;
30
import java.util.Date;
31
import java.util.Iterator;
31
import java.util.Iterator;
32
import java.util.List;
32
import java.util.List;
33
import java.util.Map;
33
import java.util.Map;
Lines 40-56 Link Here
40
import org.apache.jmeter.protocol.http.control.CookieManager;
40
import org.apache.jmeter.protocol.http.control.CookieManager;
41
import org.apache.jmeter.protocol.http.control.Header;
41
import org.apache.jmeter.protocol.http.control.Header;
42
import org.apache.jmeter.protocol.http.control.HeaderManager;
42
import org.apache.jmeter.protocol.http.control.HeaderManager;
43
43
import org.apache.jmeter.protocol.http.control.CacheManager.CacheEntry;
44
import org.apache.jmeter.samplers.Interruptible;
44
import org.apache.jmeter.samplers.Interruptible;
45
import org.apache.jmeter.samplers.SampleResult;
45
import org.apache.jmeter.samplers.SampleResult;
46
import org.apache.jmeter.testelement.property.CollectionProperty;
46
import org.apache.jmeter.testelement.property.CollectionProperty;
47
import org.apache.jmeter.testelement.property.PropertyIterator;
47
import org.apache.jmeter.testelement.property.PropertyIterator;
48
49
import org.apache.jmeter.util.JMeterUtils;
48
import org.apache.jmeter.util.JMeterUtils;
50
import org.apache.jmeter.util.SSLManager;
49
import org.apache.jmeter.util.SSLManager;
51
52
import org.apache.jorphan.logging.LoggingManager;
50
import org.apache.jorphan.logging.LoggingManager;
53
54
import org.apache.log.Logger;
51
import org.apache.log.Logger;
55
52
56
/**
53
/**
Lines 78-83 Link Here
78
    private transient PostWriter postOrPutWriter;
75
    private transient PostWriter postOrPutWriter;
79
76
80
    private volatile HttpURLConnection savedConn;
77
    private volatile HttpURLConnection savedConn;
78
	private transient SimpleDateFormat mExpiresDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
79
81
80
82
    /**
81
    /**
83
     * Constructor for the HTTPSampler object.
82
     * Constructor for the HTTPSampler object.
Lines 244-250 Link Here
244
243
245
        // works OK even if ContentEncoding is null
244
        // works OK even if ContentEncoding is null
246
        boolean gzipped = ENCODING_GZIP.equals(conn.getContentEncoding());
245
        boolean gzipped = ENCODING_GZIP.equals(conn.getContentEncoding());
247
246
        if (log.isDebugEnabled()) {
247
        	log.debug("gzipped page " + gzipped + " " + conn.getURL().toString());
248
        }
248
        try {
249
        try {
249
            if (gzipped) {
250
            if (gzipped) {
250
                in = new BufferedInputStream(new GZIPInputStream(conn.getInputStream()));
251
                in = new BufferedInputStream(new GZIPInputStream(conn.getInputStream()));
Lines 361-366 Link Here
361
                    Header header = (Header) i.next().getObjectValue();
362
                    Header header = (Header) i.next().getObjectValue();
362
                    String n = header.getName();
363
                    String n = header.getName();
363
                    String v = header.getValue();
364
                    String v = header.getValue();
365
                    log.info("adding request property " + n + " " + v);
364
                    conn.addRequestProperty(n, v);
366
                    conn.addRequestProperty(n, v);
365
                }
367
                }
366
            }
368
            }
Lines 443-459 Link Here
443
     */
445
     */
444
    @Override
446
    @Override
445
    protected HTTPSampleResult sample(URL url, String method, boolean areFollowingRedirect, int frameDepth) {
447
    protected HTTPSampleResult sample(URL url, String method, boolean areFollowingRedirect, int frameDepth) {
446
        HttpURLConnection conn = null;
448
    	HttpURLConnection conn = null;
447
449
448
        String urlStr = url.toString();
450
        String urlString = url.toString();
449
        log.debug("Start : sample " + urlStr);
451
        log.debug("Start : sample " + urlString);
450
452
451
        HTTPSampleResult res = new HTTPSampleResult();
453
        HTTPSampleResult res = new HTTPSampleResult();
452
        res.setMonitor(isMonitor());
454
        res.setMonitor(isMonitor());
453
455
454
        res.setSampleLabel(urlStr);
456
        res.setSampleLabel(urlString);
457
        CacheEntry cacheEntry = getCacheManager() == null ? null : getCacheManager().getCacheEntry(urlString);
458
        boolean isCached = false;
459
        if (cacheEntry != null) {
460
        	String cacheControl = cacheEntry.getCacheControl();
461
        	String expires = cacheEntry.getExpires();
462
        	if (cacheControl != null && cacheControl.contains("public") && cacheControl.contains("max-age=")) {
463
        		long maxAge = Long.parseLong(cacheControl.substring(cacheControl.indexOf("max-age=")+8))*1000;
464
        		long millisSinceCached = System.currentTimeMillis()-cacheEntry.getCreationTime();
465
        		isCached = millisSinceCached < maxAge;
466
        		if (log.isDebugEnabled()) {
467
        			log.debug("attempting cache control " + cacheControl + " max age of [" + maxAge +"] isCached= " + isCached  + " for " + urlString);
468
        		}
469
        	} else if (expires != null) {
470
        		try {
471
        			Date dt = mExpiresDateFormat.parse(expires);
472
        			isCached = dt.compareTo(new Date()) >= 0;
473
            		if (log.isDebugEnabled()) {
474
            			log.debug("attempting expires " + expires + " with date of " + dt + " isCached= " + isCached + " for " + urlString);
475
            		}
476
        		} catch (Exception ignore) {}
477
        	}
478
        }
455
        
479
        
456
        res.sampleStart(); // Count the retries as well in the time
480
        res.sampleStart(); // Count the retries as well in the time
481
        
482
        if (isCached) {
483
    		if (log.isDebugEnabled()) {
484
    			log.debug("cache hit on " + urlString);
485
    		}
486
    		res.setHTTPMethod(method);
487
    		res.setURL(url);
488
    		res.setQueryString(url.getQuery());
489
        	res.setResponseCode("204");
490
        	res.sampleEnd();
491
            res.setSuccessful(true);
492
        	return res;
493
        }
494
        
457
        try {
495
        try {
458
            // Sampling proper - establish the connection and read the response:
496
            // Sampling proper - establish the connection and read the response:
459
            // Repeatedly try to connect:
497
            // Repeatedly try to connect:
(-)src/protocol/http/org/apache/jmeter/protocol/http/util/HTTPConstantsInterface.java (+5 lines)
Lines 61-65 Link Here
61
    public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; // $NON-NLS-1$
61
    public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; // $NON-NLS-1$
62
    public static final String ETAG = "Etag"; // $NON-NLS-1$
62
    public static final String ETAG = "Etag"; // $NON-NLS-1$
63
    public static final String LAST_MODIFIED = "Last-Modified"; // $NON-NLS-1$
63
    public static final String LAST_MODIFIED = "Last-Modified"; // $NON-NLS-1$
64
    public static final String CACHE_CONTROL = "Cache-Control";	 //public, max-age=259200
65
    public static final String EXPIRES = "Expires"; //Sat, 07 Nov 2009 19:02:05 GMT
66
    	
67
    
68
    
64
69
65
}
70
}
(-)src/protocol/http/org/apache/jmeter/protocol/http/control/CacheManager.java (-14 / +37 lines)
Lines 61-82 Link Here
61
     * Holder for storing cache details.
61
     * Holder for storing cache details.
62
     * Perhaps add original response later?
62
     * Perhaps add original response later?
63
     */
63
     */
64
    private static class CacheEntry{
64
    public static class CacheEntry{
65
        private final String lastModified;
65
        private String mLastModified;
66
        private final String etag;
66
        private String mEtag;
67
        public CacheEntry(String lastModified, String etag){
67
		private String mCacheControl;
68
           this.lastModified = lastModified;
68
		private String mExpires;
69
           this.etag = etag;
69
		private long mCreationTime;
70
       public CacheEntry(String expires, String cacheControl, String lastModified, String etag){
71
    	   mExpires = expires;
72
    	   mCacheControl = cacheControl;
73
           mLastModified = lastModified;
74
           mEtag = etag;
75
           mCreationTime = System.currentTimeMillis();
70
       }
76
       }
71
        public String getLastModified() {
77
        public String getExpires() {
72
            return lastModified;
78
        	return mExpires;
79
        }
80
        public String getCacheControl() {
81
			return mCacheControl;
82
		}
83
		public String getLastModified() {
84
            return mLastModified;
73
        }
85
        }
74
        public String getEtag() {
86
        public String getEtag() {
75
            return etag;
87
            return mEtag;
88
        }
89
        public long getCreationTime() {
90
        	return mCreationTime;
76
        }
91
        }
77
        @Override
92
        @Override
78
        public String toString(){
93
        public String toString(){
79
            return lastModified+" "+etag;
94
            return mExpires + " " + mCacheControl + " " + mLastModified+" "+mEtag;
80
        }
95
        }
81
    }
96
    }
82
97
Lines 90-97 Link Here
90
        if (isCacheable(res)){
105
        if (isCacheable(res)){
91
            String lastModified = conn.getHeaderField(HTTPConstantsInterface.LAST_MODIFIED);
106
            String lastModified = conn.getHeaderField(HTTPConstantsInterface.LAST_MODIFIED);
92
            String etag = conn.getHeaderField(HTTPConstantsInterface.ETAG);
107
            String etag = conn.getHeaderField(HTTPConstantsInterface.ETAG);
108
            String cacheControl = conn.getHeaderField(HTTPConstantsInterface.CACHE_CONTROL);
109
            String expires = conn.getHeaderField(HTTPConstantsInterface.EXPIRES);
93
            String url = conn.getURL().toString();
110
            String url = conn.getURL().toString();
94
            setCache(lastModified, etag, url);
111
            setCache(expires, cacheControl, lastModified, etag, url);
95
        }
112
        }
96
    }
113
    }
97
114
Lines 105-121 Link Here
105
        if (isCacheable(res)){
122
        if (isCacheable(res)){
106
            String lastModified = getHeader(method ,HTTPConstantsInterface.LAST_MODIFIED);
123
            String lastModified = getHeader(method ,HTTPConstantsInterface.LAST_MODIFIED);
107
            String etag = getHeader(method ,HTTPConstantsInterface.ETAG);
124
            String etag = getHeader(method ,HTTPConstantsInterface.ETAG);
125
            String cacheControl = getHeader(method, HTTPConstantsInterface.CACHE_CONTROL);
126
            String expires = getHeader(method, HTTPConstantsInterface.EXPIRES);
108
            String url = method.getURI().toString();
127
            String url = method.getURI().toString();
109
            setCache(lastModified, etag, url);
128
            setCache(expires, cacheControl, lastModified, etag, url);
110
        }
129
        }
111
    }
130
    }
112
131
113
    // helper method to save the cache entry
132
    // helper method to save the cache entry
114
    private void setCache(String lastModified, String etag, String url) {
133
    private void setCache(String expires, String cacheControl, String lastModified, String etag, String url) {
115
        if (log.isDebugEnabled()){
134
        if (log.isDebugEnabled()){
116
            log.debug("SET(both) "+url + " " + lastModified + " " + etag);
135
            log.debug("SET(both) "+url + " " + lastModified + " " + etag);
117
        }
136
        }
118
        getCache().put(url, new CacheEntry(lastModified, etag));
137
        getCache().put(url, new CacheEntry(expires, cacheControl, lastModified, etag));
119
    }
138
    }
120
139
121
    // Helper method to deal with missing headers
140
    // Helper method to deal with missing headers
Lines 133-138 Link Here
133
        return "200".compareTo(responseCode) <= 0  // $NON-NLS-1$
152
        return "200".compareTo(responseCode) <= 0  // $NON-NLS-1$
134
            && "299".compareTo(responseCode) >= 0; // $NON-NLS-1$
153
            && "299".compareTo(responseCode) >= 0; // $NON-NLS-1$
135
    }
154
    }
155
    
156
    public CacheEntry getCacheEntry(String url) {
157
    	return getCache().get(url);
158
    }
136
159
137
    /**
160
    /**
138
     * Check the cache, and if there is a match, set the headers:<br/>
161
     * Check the cache, and if there is a match, set the headers:<br/>

Return to bug 48153