001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.response.filter; 018 019import java.util.HashMap; 020import java.util.Map; 021 022import org.apache.wicket.Application; 023import org.apache.wicket.model.Model; 024import org.apache.wicket.request.cycle.RequestCycle; 025import org.apache.wicket.util.string.AppendingStringBuffer; 026import org.apache.wicket.core.util.string.JavaScriptUtils; 027import org.slf4j.Logger; 028import org.slf4j.LoggerFactory; 029 030 031/** 032 * This is a filter that injects javascript code to the top head portion and after the body so that 033 * the time can me measured what the client parse time was for this page. It also reports the total 034 * server parse/response time in the client and logs the server response time and response size it 035 * took for a specific response in the server log. 036 * 037 * You can specify what the status text should be like this: ServerAndClientTimeFilter.statustext=My 038 * Application, Server parsetime: ${servertime}, Client parsetime: ${clienttime} 039 * 040 * <p> 041 * Usage: in YourApplication.java: 042 * 043 * <pre> 044 * @Override 045 * public init() 046 * { 047 * super.init(); 048 * getRequestCycleSettings().addResponseFilter(new ServerAndClientTimeFilter()); 049 * } 050 * </pre> 051 * 052 * @author jcompagner 053 * @deprecated This class has been deprecated for several reasons. The way it tries to measure 054 * server and client times is very inaccurate. Modern browsers provide much better tools 055 * to measure Javascript execution times. The measurements were written in a property 056 * that has been deprecated for years and removed in modern browsers. Finally, rendering 057 * the Javascript directly into the response makes it hard to support a strict CSP with 058 * nonces. There is no real replacement for this class. Use the tools provided by the 059 * browser. See {@code WicketExampleApplication} for a simple example of passing 060 * rendering times to the browser via the {@code Server-Timing} header. 061 */ 062@Deprecated 063public class ServerAndClientTimeFilter implements IResponseFilter 064{ 065 private static final Logger log = LoggerFactory.getLogger(ServerAndClientTimeFilter.class); 066 067 /** 068 * @see IResponseFilter#filter(AppendingStringBuffer) 069 */ 070 @Override 071 public AppendingStringBuffer filter(AppendingStringBuffer responseBuffer) 072 { 073 int headIndex = responseBuffer.indexOf("<head>"); 074 int bodyIndex = responseBuffer.indexOf("</body>"); 075 long timeTaken = System.currentTimeMillis() - RequestCycle.get().getStartTime(); 076 if (headIndex != -1 && bodyIndex != -1) 077 { 078 Map<String, String> map = new HashMap<>(4); 079 map.put("clienttime", "' + (new Date().getTime() - clientTimeVariable)/1000 + 's"); 080 map.put("servertime", ((double)timeTaken) / 1000 + "s"); 081 082 AppendingStringBuffer defaultValue = new AppendingStringBuffer(128); 083 defaultValue.append("Server parsetime: "); 084 defaultValue.append(((double)timeTaken) / 1000); 085 defaultValue.append("s, Client parsetime: ' + (new Date().getTime() - clientTimeVariable)/1000 + 's"); 086 087 String txt = Application.get() 088 .getResourceSettings() 089 .getLocalizer() 090 .getString("ServerAndClientTimeFilter.statustext", null, Model.ofMap(map), 091 defaultValue.toString()); 092 AppendingStringBuffer endScript = new AppendingStringBuffer(150); 093 endScript.append("\n").append(JavaScriptUtils.SCRIPT_OPEN_TAG); 094 endScript.append("\nwindow.defaultStatus='"); 095 endScript.append(txt); 096 endScript.append("';\n").append(JavaScriptUtils.SCRIPT_CLOSE_TAG).append("\n"); 097 responseBuffer.insert(bodyIndex - 1, endScript); 098 responseBuffer.insert(headIndex + 6, "\n" + JavaScriptUtils.SCRIPT_OPEN_TAG + 099 "\nvar clientTimeVariable = new Date().getTime();\n" + 100 JavaScriptUtils.SCRIPT_CLOSE_TAG + "\n"); 101 } 102 log.info(timeTaken + "ms server time taken for request " + 103 RequestCycle.get().getRequest().getUrl() + " response size: " + responseBuffer.length()); 104 return responseBuffer; 105 } 106}