4 Provides an In-Depth Tool to Analyze Ajax Interactions with Web Servers.
5 Copyright (C) 2007 Steven Ray Schronk
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 // DETERMINE WHICH BROWSER IS PRESENT
24 // FIREFOX DOES NOT SUPPORT SENDING DATA TO THE OS KEYBOARD
25 // ALSO FIREFOX DOES NOT REACT WELL TO AN UNCOMMENTED PAYLOAD
26 var agent
= navigator
.userAgent
.toLowerCase();
27 if ( agent
.indexOf("firefox") != -1 ){ agent
="firefox"; }
28 else if ( agent
.indexOf("msie") != -1 ){ agent
="exploder"; }
29 else if ( agent
.indexOf("opera") != -1 ){ agent
="opera"; }
30 else { agent
="unknown"; }
32 var ajax_event_no
= 0; // AJAX EVENT COUNTER
33 var event_no
= 0; // EVENT COUNTER
34 var ajax_min
= "X"; // AJAX MINIMUM TIME
35 var ajax_max
= "X"; // AJAX MAXIMUM TIME
36 var ajax_avg
= "X"; // AJAX AVERAGE TIME
38 // OPENS NEW WINDOW THAT WILL DISPLAY ALL DEBUG INFO
39 function openDebug() {
40 //var pageLocation = parent.window.location.toString();
41 // RESET ALL COUNTERS AND COLLECTED TIME DATA
42 ajax_event_no
= 0; // RESET AJAX EVENTS COUNTER
43 event_no
= 0; // RESET EVENTS COUNTER
44 ajax_min
= 0; // RESET AJAX MINIMUM TIME
45 ajax_max
= 0; // RESET AJAX MAXIMUM TIME
46 ajax_avg
= 0; // RESET AJAX AVERAGE TIME
47 debug
= window
.open("debug_popup.html", "Debugger","location=no,status=no,toolbar=no,menubar=no,resizable=yes,height=500,width=600,top=550,left-500,scrollbars=1")
50 // CLEAR ALL DEBUG VALUES MADE SO FAR
51 function clearDebugger() {
52 document
.getElementById("main").innerHTML
= "";
55 function copyInfo(pageElement
) {
56 window
.clipboardData
.setData('Text', document
.getElementById(pageElement
).innerHTML
);
59 // DISPLAY RUNNING CLOCK AT TOP OF DEBUGGER
62 function UpdateClock() {
64 clearTimeout(clockID
);
68 var tDate
= new Date();
69 // ADD LEADING ZEROS TO TIME VALUES
70 var hours
= tDate
.getHours().toString();
71 if (hours
< 10) { hours
= "0" + hours
;}
73 var minutes
= tDate
.getMinutes().toString();
74 if (minutes
< 10) { minutes
= "0" + minutes
;}
76 var seconds
= tDate
.getSeconds().toString();
77 if (seconds
< 10) { seconds
= "0" + seconds
;}
79 document
.getElementById("time").innerHTML
= "" + hours
+ ":" + minutes
+ ":" + seconds
;
80 clockID
= setTimeout("UpdateClock()", 1000);
83 function StartClock() {
84 clockID
= setTimeout("UpdateClock()", 500);
87 function KillClock() {
89 clearTimeout(clockID
);
94 // IF DISPLAY IS NONE, DISPLAYS CONTENT - OTHERWISE ERASE CONTENT
95 function viewContent(pageElement
, icon
) {
96 // INSERT INPUT INTO DIV
97 if (document
.getElementById(pageElement
).style
.display
== "none") {
98 document
.getElementById(pageElement
).style
.display
="inline";
99 document
.getElementById(icon
).innerHTML
= "~";
101 // CLEAR DIV - CONTENT SHOULD DISAPPEAR
103 document
.getElementById(pageElement
).style
.display
="none";
104 //document.getElementById(pageElement).innerHTML = ""
105 document
.getElementById(icon
).innerHTML
= "+";
109 // BUG WHEN USED IN REMOTE WINDOW, DISPLAYS UNDEFINED AS IT GOES THOUGH ARRAY :(
110 // PRINTS OUT A COLORED CHART OF NAME VALUE PAIRS
111 // ALL COOLIES FOR THIS DOMAIN SHOULD BE DISPLAYED
112 function getAllCookies() {
113 if (document
.cookie
) {
114 var everycookievalue
= document
.cookie
;
115 var pairsSplit
= everycookievalue
.split(";");
116 var patternNospace
= /[^\s]+/;
119 var string
= ""; // CONTAINS STRING OF COOKIE VALUES
120 for ( count
=0 ; ( pairsSplit
[count
] != undefined ) ; count
++ ) {
121 elementsSplit
= pairsSplit
[count
].split("=");
123 //document.writeln("<div id=right_justify><div id=blue>" + finalName + "</div> = </div>");
124 string
+= "<div id=right_justify><div id=blue>" + elementsSplit
[0].match(patternNospace
) + "</div> = </div>";
126 //document.writeln("<div id=left_justify><div id=red>" + finalValue + "</div></div><br />");
127 string
+= "<div id=left_justify><div id=red>" + elementsSplit
[1].match(patternNospace
) + "</div></div><br />";
133 // SIMPLIFIED VERSION OF ABOVE SCRIPT
134 // MIGHT COME IN HANDY SOME DAY
135 function getAllCookies2() {
137 var cookies
= document
.cookie
.replace(/ /g
,"").split(";");
138 for (var i
= 0; i
< cookies
.length
; i
++){
139 cookiePair
= cookies
[i
].split("=");
140 //document.write("["+cookiePair[0]+"] = ["+cookiePair[1]+"]<br><br>");
141 string
+= cookiePair
[0] + cookiePair
[1] + "<br />";
146 // ADDS EVENT TO DEBUGGER CONSOLE
147 // url = address of event on page
148 // style = type (color) of box to be displayed
149 // payload = data recieved from ajax event
150 // time = ping time data sent from ajax event - listed in milliseconds
151 function debugEvent(url
, style
, payload
, time
) {
152 if (style
== "got") { ajax_event_no
++; }
153 event_no
++; // INCREMENT EVENTS COUNTER
154 debug
.document
.getElementById("events").innerHTML
= "Event: "+event_no
;
156 // ADJUST AJAX TIMES ON BANNER
158 if (undefined != time
) {
159 if ((ajax_min
== "X" )) { // AJAX NEVER USED BEFORE - SET MIN,MAX,AVG TO THIS INITAL VALUE
163 } else { // MODIFY AJAX TIMES
165 if (time
> ajax_max
) { ajax_max
=time
}
167 if (time
< ajax_min
) { ajax_min
=time
}
168 // RECALCULATE AVERAGE
169 //ajax_avg = (ajax_avg + (time * 1/event_no))/2;
170 //ajax_avg = (ajax_avg+time)/2;
171 ajax_avg
= ((ajax_avg
*(ajax_event_no
-1))+time
)/(ajax_event_no
);
173 ajax_avg
= Math
.round(ajax_avg
);
175 debug
.document
.getElementById("ajax_max").innerHTML
= "Max: "+ajax_max
;
176 debug
.document
.getElementById("ajax_min").innerHTML
= "Min: "+ajax_min
;
177 debug
.document
.getElementById("ajax_avg").innerHTML
= "Avg: "+ajax_avg
;
180 var tDate
= new Date();
181 var hours
= tDate
.getHours().toString();
182 if (hours
< 10) { hours
= "0" + hours
; }
184 var minutes
= tDate
.getMinutes().toString();
185 if (minutes
< 10) { minutes
= "0" + minutes
; }
187 var seconds
= tDate
.getSeconds().toString();
188 if (seconds
< 10) { seconds
= "0" + seconds
; }
190 var millisec
= tDate
.getTime();
191 var random
= parseInt(Math
.random()*9999);
192 // CONVERT BOTH VALUES TO STRINGS AND APPEND THEM
193 // PROVIDES A GAURANTEED RANDOM VALUE FOR DIV IDs :)
194 var divid
= millisec
.toString() +"-"+ random
.toString();
196 var payload_stripped
= payload
;
198 // STRIP HTML TAGS OUT OF PAYLOAD
200 //payload = payload.replace(/(<([^>]+)>)/ig,"");
201 payload_stripped
= payload_stripped
.replace(/&/g
,"&");
202 payload_stripped
= payload_stripped
.replace(/</g
,"<");
203 payload_stripped
= payload_stripped
.replace(/>/g
,">");
204 payload_stripped
= payload_stripped
.replace(/[\n\t]{1,}/g,"<br />");
206 // ADD INLINE DIVS TO payload_stripped - WILL ADD COLOR
207 // ALL TAGS TURN BLUE
208 payload_stripped
= payload_stripped
.replace(/(<.*?>)/g, "<div id=blue>$1</div> ");
209 // EVERYTHING IN QUOTES TURNS RED
210 payload_stripped
= payload_stripped
.replace(/(".*?")/g, "<div id=red>$1</div> ");
211 // ALL HTML COMMENTS TURN GRAY
212 payload_stripped
= payload_stripped
.replace(/(<!--.*?-->)/g, "<div id=gray>$1</div> ");
213 // ALL JAVASCRIPT COMMENTS TURN GRAY
214 payload_stripped
= payload_stripped
.replace(/(\/\/.*?<br \/>)/g, "<div id=gray>$1</div> ");
215 // ALL JAVASCRIPT VARIABLES TURN GREEN
216 payload_stripped
= payload_stripped
.replace(/(var)/g, "<div id=green>$1</div> ");
217 // ALL JAVASCRIPT FUNCTIONS TURN BOLD
218 payload_stripped
= payload_stripped
.replace(/(function.*?){/g, "<div id=bold>$1</div> { ");
220 else { payload
= "No Data Sent"; payload_stripped
= "No Data Sent"; }
222 // DETERMINE TYPE OF EVENT - SETS STYLES IN WINDOW
223 if (style
== "get") {
224 var div
= "get_headline";
227 else if (style
== "got") {
228 var div
= "got_headline";
231 else if (style
== "error_403") {
232 var div
= "error_headline";
233 var banner
= "ERROR: 403 FORBIDDEN";
235 else if (style
== "error_404") {
236 var div
= "error_headline";
237 var banner
= "ERROR: 404 FILE NOT FOUND";
239 else if (style
== "error_500") {
240 var div
= "error_headline";
241 var banner
= "ERROR: 500 INTERNAL SERVER ERROR";
244 var div
= "unknown_headline";
245 var banner
= "UNKNOWN";
248 // IF TIME NOT SENT - PRINT NICE MESSAGE
249 if (time
== 0 ) { time
= "<div id=ping>PING: "+time
+"</div>"; }
250 else if (time
> 0) { time
= "<div id=ping>PING: "+time
+"</div>"; }
253 var cookies
= getAllCookies();
254 // NICE MESSAGE IF NO COOKIE FOUND
255 if (cookies
) { } else { cookies
= "No Data Sent"; }
259 // THIS DIV CONTAINS AN UN-ESCAPED VERSION OF "PAYLOAD"
260 // IT IS NEVER VISIBLE AND IS USED ONLY FOR THE "C" BUTTON
261 // FIREFOX DOES NOT LIKE THIS ONE, SO IT ONLY APPLIES TO OTHER BROWSERS
262 if (agent
!= "firefox") {event
+= "<div id=P"+divid
+" style='display:none;'>"+payload
+"</div>";}
265 event
+= "<div id="+div
+">";
266 event
+= hours
+":"+minutes
+":"+seconds
+" "+banner
;
268 event
+= "<br />URL: ";
269 event
+= "<div class=url id=U"+divid
+">"+url
+"</div>";
270 // THESE NEXT TWO BUTTINS DO NOT WORK IN FIREFOX, SO THEY ARE REMOVED
271 if (agent
!= "firefox") {event
+= "<div class=content onClick='copyInfo(\"P"+divid
+"\")'>P</div>";}
272 if (agent
!= "firefox") {event
+= "<div class=address onClick='copyInfo(\"U"+divid
+"\")'>U</div>";}
273 event
+= "<div class=icon id=B"+divid
+" onClick='viewContent(\"A"+divid
+"\", \"B"+divid
+"\")'>+</div>";
277 event
+= "<div class=payload id=A"+divid
+" style='display:none;'>";
278 event
+= "<div class=code><div id=bold>PAYLOAD DATA:</div><br />"+payload_stripped
+"</div>";
279 event
+= "<div class=post><div id=bold>POST DATA:</div><br />No Data Sent</div>";
280 event
+= "<div class=cookie><div id=bold>COOKIE DATA:</div><br />"+cookies
+"</div>";
283 // MUST GET OLD "MAIN" DATA AND APPENT TO EVENT
284 // ALL THIS IS DONE BECUASE FIREFOX DOES NOT SUPPORT insertAdjacentHTML
285 event
+= debug
.document
.getElementById("main").innerHTML
;
287 debug
.document
.getElementById("main").innerHTML
= event
;