Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
issue #41 - add support for XHRs on Network Panel
  • Loading branch information
pmuellr committed Oct 25, 2011
1 parent 18477de commit 87625ae8f52388f2882a920bf69c3bdc3f2092df
Showing 7 changed files with 196 additions and 5 deletions.
@@ -26,7 +26,8 @@ module.exports = class InspectorFrontendHostImpl

#---------------------------------------------------------------------------
hiddenPanels: ->
"audits,profiles,network"
# "audits,profiles,network"
"audits,profiles"

#---------------------------------------------------------------------------
platform: ->
@@ -11,6 +11,15 @@ StackTrace = require('./StackTrace')
#-------------------------------------------------------------------------------
module.exports = class Ex

#---------------------------------------------------------------------------
@catching: (func) ->
try
func.call(this)
catch e
console.log "runtime error: #{e}"
StackTrace.dump arguments

#---------------------------------------------------------------------------
constructor: (args, message) ->
if not args or not args.callee
throw Ex(arguments, "first parameter must be an Arguments object")
@@ -192,7 +192,9 @@ module.exports = class WebSocketXhr
xhr.open method, url, true

xhr.setRequestHeader "Content-Type", "text/plain"
xhr.send data

HookLib.ignoreHooks ->
xhr.send data

#-------------------------------------------------------------------------------
_xhrEventHandler = (event) ->
@@ -62,7 +62,6 @@ module.exports = class ElementHighlighterDivs2 extends ElementHighlighter

#---------------------------------------------------------------------------
redraw: (metrics) ->
console.log(JSON.stringify(metrics, null, 4))

@hElement1.style.top = px metrics.y
@hElement1.style.left = px metrics.x
@@ -19,6 +19,7 @@ HookSites.window_setTimeout = HookLib.addHookSite window, "setTime
HookSites.window_addEventListener = HookLib.addHookSite window, "addEventListener"
HookSites.Node_addEventListener = HookLib.addHookSite Node.prototype, "addEventListener"
HookSites.XMLHttpRequest_open = HookLib.addHookSite XMLHttpRequest.prototype, "open"
HookSites.XMLHttpRequest_send = HookLib.addHookSite XMLHttpRequest.prototype, "send"
HookSites.XMLHttpRequest_addEventListener = HookLib.addHookSite XMLHttpRequest.prototype, "addEventListener"

if window.openDatabase
@@ -0,0 +1,176 @@

#---------------------------------------------------------------------------------
# weinre is available under *either* the terms of the modified BSD license *or* the
# MIT License (2008). See http:#opensource.org/licenses/alphabetical for full text.
#
# Copyright (c) 2011 IBM Corporation
#---------------------------------------------------------------------------------

StackTrace = require('../common/StackTrace')
IDGenerator = require('../common/IDGenerator')
HookLib = require('../common/HookLib')
Weinre = require('../common/Weinre')
Ex = require('../common/Ex')
HookSites = require('./HookSites')

Loader =
url: window.location.href
frameId: 0
loaderId: 0

#-------------------------------------------------------------------------------
module.exports = class NetworkRequest

#---------------------------------------------------------------------------
constructor: (@xhr, @id, @method, @url, @stackTrace) ->

#---------------------------------------------------------------------------
handleSend: (data) ->
Weinre.wi.NetworkNotify.identifierForInitialRequest(@id, @url, Loader, @stackTrace)

time = Date.now() / 1000.0
request = getRequest(@url, @method, @xhr, data)
redirectResponse = {isNull: true}

Weinre.wi.NetworkNotify.willSendRequest(@id, time, request, redirectResponse)

#---------------------------------------------------------------------------
handleHeadersReceived: ->
time = Date.now() / 1000.0
response = getResponse(@xhr)
Weinre.wi.NetworkNotify.didReceiveResponse(@id, time, "XHR", response)

#---------------------------------------------------------------------------
handleLoading: ->

#---------------------------------------------------------------------------
handleDone: ->
sourceString = @xhr.responseText
Weinre.wi.NetworkNotify.setInitialContent(@id, sourceString, "XHR")

time = Date.now() / 1000.0
status = @xhr.status
status = 200 if status == 0
statusText = @xhr.statusText

success = status >= 200 and status < 300

if success
Weinre.wi.NetworkNotify.didFinishLoading(@id, time)
else
description = "#{status} - #{statusText}"
Weinre.wi.NetworkNotify.didFailLoading(@id, time, description)

#---------------------------------------------------------------------------
@installNativeHooks: ->

#-----------------------------------------------------------------------
HookSites.XMLHttpRequest_open.addHooks

before: (receiver, args) ->
xhr = receiver

method = args[0]
url = args[1]
id = IDGenerator.next()

rawStackTrace = new StackTrace(args).trace.slice(1)

stackTrace = []
for frame in rawStackTrace
stackTrace.push({functionName: frame})

xhr.__weinreNetworkRequest__ = new NetworkRequest(xhr, id, method, url, stackTrace)

HookLib.ignoreHooks ->
xhr.addEventListener "readystatechange", getXhrEventHandler(xhr), false

#-----------------------------------------------------------------------
HookSites.XMLHttpRequest_send.addHooks

before: (receiver, args) ->
xhr = receiver
data = args[0]
nr = xhr.__weinreNetworkRequest__
return unless nr

nr.handleSend(data)

#-------------------------------------------------------------------------------
getRequest = (url, method, xhr, data) ->

return {
url: url
httpMethod: method
httpHeaderFields: {}
requestFormData: getFormData(url, data)
}

#-------------------------------------------------------------------------------
getResponse = (xhr) ->
contentType = xhr.getResponseHeader("Content-Type")

[contentType, encoding] = splitContentType(contentType)

headers = getHeaders(xhr)

return {
mimeType: contentType
expectedContentLength: contentType
textEncodingName: encoding
httpStatusCode: xhr.status
httpStatusText: xhr.statusText
httpHeaderFields: headers
connectionReused: false
connectionID: 0
wasCached: false
}

#-------------------------------------------------------------------------------
getHeaders = (xhr) ->
string = xhr.getAllResponseHeaders()
lines = string.split('\r\n')

result = {}
for line in lines
line = trim(line)
break if line == ""

[key, val] = line.split(':', 2)
result[trim(key)] = trim(val)

result

#-------------------------------------------------------------------------------
trim = (string) ->
string.replace(/^\s+|\s+$/g, '')

#-------------------------------------------------------------------------------
getFormData = (url, data) ->
return data if data

pattern = /.*?\?(.*?)(#.*)?$/
match = url.match(pattern)
return match[1] if match

return ""

#-------------------------------------------------------------------------------
splitContentType = (contentType) ->
pattern = /\s*(.*?)\s*(;\s*(.*))?\s*$/
match = contentType.match(pattern)
return [contentType, ""] unless match

return [match[1], match[3]]

#-------------------------------------------------------------------------------
getXhrEventHandler = (xhr) ->
->
nr = xhr.__weinreNetworkRequest__
return unless nr

switch xhr.readyState
when 2 then nr.handleHeadersReceived()
when 3 then nr.handleLoading()
when 4 then nr.handleDone()

@@ -19,6 +19,7 @@ CSSStore = require('./CSSStore')
ElementHighlighter = require('./ElementHighlighter')
ExceptionalCallbacks = require('./ExceptionalCallbacks')
InjectedScriptHostImpl = require('./InjectedScriptHostImpl')
NetworkRequest = require('./NetworkRequest')
WeinreTargetEventsImpl = require('./WeinreTargetEventsImpl')
WeinreExtraClientCommandsImpl = require('./WeinreExtraClientCommandsImpl')
WiConsoleImpl = require('./WiConsoleImpl')
@@ -40,8 +41,6 @@ module.exports = class Target
Weinre.target = new Target()
Weinre.target.initialize()

ExceptionalCallbacks.addHooks()

#----------------------------------------------------------------------------
setWeinreServerURLFromScriptSrc: (element) ->
return if window.WeinreServerURL
@@ -143,6 +142,7 @@ module.exports = class Target
Weinre.wi.DatabaseNotify = messageDispatcher.createProxy("DatabaseNotify")
Weinre.wi.InspectorNotify = messageDispatcher.createProxy("InspectorNotify")
Weinre.wi.TimelineNotify = messageDispatcher.createProxy("TimelineNotify")
Weinre.wi.NetworkNotify = messageDispatcher.createProxy("NetworkNotify")
Weinre.WeinreTargetCommands = messageDispatcher.createProxy("WeinreTargetCommands")
Weinre.WeinreExtraTargetEvents = messageDispatcher.createProxy("WeinreExtraTargetEvents")

@@ -155,6 +155,9 @@ module.exports = class Target
Target.handleError e
), false

ExceptionalCallbacks.addHooks()
NetworkRequest.installNativeHooks()

#---------------------------------------------------------------------------
@handleError: (event) ->
filename = event.filename or "[unknown filename]"

0 comments on commit 87625ae

Please sign in to comment.