http_archive 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/lib/http_archive.rb +7 -0
- data/lib/http_archive/archive.rb +178 -0
- data/lib/http_archive/classes.rb +141 -0
- data/lib/http_archive/version.rb +3 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MTFmYzE0ZGM5ZGNjNzdhZmU2ZjJiMWY2OTdkZGYwN2UzNzg4YWE3ZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
N2E1NTIyOWQ2MWY0NmZlZmFhNGI0MDBhNGU0YmMxMjRkNzMxOWQ4Yw==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NjY0YjU3NDg2NThhYzFmNDYyYmMyOTg3Yzc4YjgyOGMyMDQ1NWQ0YmQ5YjU0
|
10
|
+
MWRiMGY3MDExMTEzZjU5ZjRjMWRmNjhjZjFjNTNjYjA1ZGM0OWZhNWM3MzE0
|
11
|
+
NGVkYjJiOWEyZTZlZGVkMmUxYjc0YzRiZmFiNTk2NWM4OGFiYjc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZTcwNmRhYTcxYzEyMDRhZjdiMDQ2YjMyZDdhODY0NjljMjg2Y2FhNGY0MTk0
|
14
|
+
ODllMzAwM2JlOWMyN2Y4ZTgxNjUyZDA1YmE1NzZhNTY4Njc5OTU4ZDUxMjhi
|
15
|
+
NTVjOTRhZjU5ODhkMWFiYjZhMmU0NmU3ZjQ2ODA2N2E1ZDk3Yjk=
|
data/lib/http_archive.rb
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
# Module that holds all other classes.
|
2
|
+
# Nothing to see here...
|
3
|
+
module HttpArchive
|
4
|
+
##
|
5
|
+
# The main object to interact with.
|
6
|
+
# All accessible objects (see below) hold further information about the archive.
|
7
|
+
#
|
8
|
+
class Archive
|
9
|
+
|
10
|
+
# Returns the 'Creator' object with data of the creator of the archive (Firebug etc.)
|
11
|
+
# @return [Creator]
|
12
|
+
attr_reader :creator
|
13
|
+
# Returns the 'Browser' object with data of the browser
|
14
|
+
# @return [Browser]
|
15
|
+
attr_reader :browser
|
16
|
+
# Returns general information about the page interaction as an array of 'Page' objects, normally just one entry
|
17
|
+
# @return [Array<Page>]
|
18
|
+
attr_reader :pages
|
19
|
+
# Returns all browser interactions with the page as an array of 'Entry' objects
|
20
|
+
# @return [Array<Entry>]
|
21
|
+
attr_reader :entries
|
22
|
+
# For internal use, holds the parsed JSON-data
|
23
|
+
# @return [Hash]
|
24
|
+
attr_writer :content
|
25
|
+
|
26
|
+
# Creates a new Archive object with given input.
|
27
|
+
# @param src [String,File] must be object type String or File
|
28
|
+
# @raise [ArgumentError, JSON::ParserError]
|
29
|
+
def initialize(src)
|
30
|
+
unless src.is_a?(File) || src.is_a?(String)
|
31
|
+
puts 'Argument must be String or File!'
|
32
|
+
raise ArgumentError
|
33
|
+
end
|
34
|
+
src = src.read if src.is_a?(File)
|
35
|
+
begin
|
36
|
+
@content = JSON.parse(src)
|
37
|
+
rescue
|
38
|
+
puts "The input could not be parsed."
|
39
|
+
raise JSON::ParserError
|
40
|
+
end
|
41
|
+
extract_creator
|
42
|
+
extract_browser
|
43
|
+
extract_pages
|
44
|
+
extract_entries
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# Prints a table representation of the Http Archive to STDOUT.
|
49
|
+
# An example is given on the README-file.
|
50
|
+
# Columns are like the "Network"-view of Firebug or Chrome Dev tools.
|
51
|
+
#
|
52
|
+
# @return [String] A string table representation of the archive data
|
53
|
+
def print_table
|
54
|
+
puts
|
55
|
+
size = calc_total_size.to_s
|
56
|
+
load_time = (@pages.first.on_load / 1000.0).to_s
|
57
|
+
|
58
|
+
puts("Metrics for: " +"'" + @pages.first.title + "', " + @entries.size.to_s + " Requests, " + size + "MB downloaded. " + "Load time: " + load_time + "s")
|
59
|
+
puts
|
60
|
+
|
61
|
+
@entries.each do |entry|
|
62
|
+
print_row(entry)
|
63
|
+
end
|
64
|
+
puts
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
private
|
69
|
+
def print_row(entry)
|
70
|
+
method = entry.request.http_method
|
71
|
+
url = entry.request.url
|
72
|
+
if url.end_with?("/")
|
73
|
+
ressource = entry.request.url
|
74
|
+
else
|
75
|
+
r = url.rindex("/")
|
76
|
+
ressource = url[r..-1]
|
77
|
+
end
|
78
|
+
ressource = ressource[0, 30]
|
79
|
+
status = entry.response.status.to_s
|
80
|
+
code = entry.response.status_text
|
81
|
+
size = (entry.response.content['size'] / 1000.0).round(2).to_s
|
82
|
+
duration = (entry.time / 1000.0).to_s
|
83
|
+
|
84
|
+
puts "%s %-32s %s %-20s %-10s %s" % [method, ressource, status, code, size + " KB", duration +"s"]
|
85
|
+
end
|
86
|
+
|
87
|
+
def calc_total_size
|
88
|
+
total = 0
|
89
|
+
@entries.each do |entry|
|
90
|
+
total = total + entry.response.content['size']
|
91
|
+
end
|
92
|
+
total = total / (1024.0 * 1024)
|
93
|
+
total.round(2)
|
94
|
+
end
|
95
|
+
|
96
|
+
def extract_creator
|
97
|
+
creator = HttpArchive::Creator.new
|
98
|
+
creator.name = @content['log']['creator']['name']
|
99
|
+
creator.version = @content['log']['creator']['version']
|
100
|
+
@creator = creator
|
101
|
+
end
|
102
|
+
|
103
|
+
def extract_browser
|
104
|
+
browser = HttpArchive::Browser.new
|
105
|
+
browser.name = @content['log']['browser']['name']
|
106
|
+
browser.version = @content['log']['browser']['version']
|
107
|
+
@browser = browser
|
108
|
+
end
|
109
|
+
|
110
|
+
def extract_pages
|
111
|
+
pages = []
|
112
|
+
hash_pages = @content['log']['pages']
|
113
|
+
hash_pages.each do |page|
|
114
|
+
new_page = Page.new
|
115
|
+
new_page.started_datetime = page['startedDateTime']
|
116
|
+
new_page.id = page['id']
|
117
|
+
new_page.title = page['title']
|
118
|
+
new_page.on_content_load = page['pageTimings']['onContentLoad']
|
119
|
+
new_page.on_load = page['pageTimings']['onLoad']
|
120
|
+
pages << new_page
|
121
|
+
end
|
122
|
+
@pages = pages
|
123
|
+
end
|
124
|
+
|
125
|
+
def extract_entries
|
126
|
+
entries = []
|
127
|
+
entries_hash = @content['log']['entries']
|
128
|
+
entries_hash.each do |entry|
|
129
|
+
new_entry = Entry.new
|
130
|
+
new_entry.pageref = entry['pageref']
|
131
|
+
new_entry.started_datetime = entry['startedDateTime']
|
132
|
+
new_entry.time = entry['time']
|
133
|
+
new_entry.cache = entry['cache']
|
134
|
+
new_entry.timings = entry['timings']
|
135
|
+
new_entry.server_ip_address = entry['serverIPAddress']
|
136
|
+
new_entry.connection = entry['connection']
|
137
|
+
|
138
|
+
new_request = Request.new
|
139
|
+
new_request.http_method = entry['request']['method']
|
140
|
+
new_request.url = entry['request']['url']
|
141
|
+
new_request.http_version = entry['request']['httpVersion']
|
142
|
+
new_request.cookies = entry['request']['cookies']
|
143
|
+
new_request.query_string = entry['request']['queryString']
|
144
|
+
new_request.headers_size = entry['request']['headersSize']
|
145
|
+
new_request.body_size = entry['request']['bodySize']
|
146
|
+
header_hash = {}
|
147
|
+
entry['request']['headers'].each do |info|
|
148
|
+
header_hash[info['name']] = info['value']
|
149
|
+
end
|
150
|
+
new_request.headers = header_hash
|
151
|
+
|
152
|
+
|
153
|
+
new_response = Response.new
|
154
|
+
new_response.status = entry['response']['status']
|
155
|
+
new_response.status_text = entry['response']['statusText']
|
156
|
+
new_response.http_version = entry['response']['httpVersion']
|
157
|
+
new_response.cookies = entry['response']['cookies']
|
158
|
+
new_response.content = entry['response']['content']
|
159
|
+
new_response.redirect_url = entry['response']['redirectURL']
|
160
|
+
new_response.headers_size = entry['response']['headersSize']
|
161
|
+
new_response.body_size = entry['response']['bodySize']
|
162
|
+
header_hash = {}
|
163
|
+
entry['response']['headers'].each do |info|
|
164
|
+
header_hash[info['name']] = info['value']
|
165
|
+
end
|
166
|
+
new_response.headers = header_hash
|
167
|
+
|
168
|
+
|
169
|
+
new_entry.request = new_request
|
170
|
+
new_entry.response = new_response
|
171
|
+
entries << new_entry
|
172
|
+
end
|
173
|
+
@entries = entries
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module HttpArchive
|
2
|
+
|
3
|
+
# Container for information about the HTTP Archive creator.
|
4
|
+
class Creator
|
5
|
+
# Returns the name of the creator of the HTTP Archive
|
6
|
+
# @return [String] String with creator name, e.g. "Firebug"
|
7
|
+
attr_accessor :name
|
8
|
+
# Returns the version of the creator of the HTTP Archive
|
9
|
+
# @return [String] String with creator version, e.g. "1.11"
|
10
|
+
attr_accessor :version
|
11
|
+
end
|
12
|
+
|
13
|
+
# Container for browser-related information.
|
14
|
+
class Browser
|
15
|
+
# Returns the name of the browser the page was loaded
|
16
|
+
# @return [String] String with browser name, e.g. "Firefox"
|
17
|
+
attr_accessor :name
|
18
|
+
# Returns the version of the browser the page was loaded
|
19
|
+
# @return [String] String with browser version, e.g. "21.0"
|
20
|
+
attr_accessor :version
|
21
|
+
end
|
22
|
+
|
23
|
+
# Holds general data of the page and its loading process
|
24
|
+
class Page
|
25
|
+
# Returns the datetime as string when loading of the page started
|
26
|
+
# @return [String] datetime-string, e.g. "2013-05-28T22:16:19.883+02:00"
|
27
|
+
attr_accessor :started_datetime
|
28
|
+
# Returns the id of the page
|
29
|
+
# @return [String] page id as string, e.g. "page_50735"
|
30
|
+
attr_accessor :id
|
31
|
+
# Returns the title of the page
|
32
|
+
# @return [String] page title as string, e.g. "Software is hard"
|
33
|
+
attr_accessor :title
|
34
|
+
# Returns the amount of milliseconds sice the page load started and the content is loaded
|
35
|
+
# @return [Fixnum] milliseconds content is loaded, e.g. 4994
|
36
|
+
attr_accessor :on_content_load
|
37
|
+
# Returns the amount of milliseconds sice the page load started and the page itself is loaded
|
38
|
+
# @return [Fixnum] milliseconds page is loaded, e.g. 6745
|
39
|
+
attr_accessor :on_load
|
40
|
+
end
|
41
|
+
|
42
|
+
# Holds information for every single interaction of the browser with the page.
|
43
|
+
# Entry objects hold the request and response data in seperate objects.
|
44
|
+
class Entry
|
45
|
+
# Returns the reference to the parent page
|
46
|
+
# @return [String] ref to parent page as string, e.g. "page_50735"
|
47
|
+
attr_accessor :pageref
|
48
|
+
# Returns the datetime as string when loading of this element started
|
49
|
+
# @return [String] datetime-string, e.g. "2013-05-28T22:16:19.883+02:00"
|
50
|
+
attr_accessor :started_datetime
|
51
|
+
# Duration of the load time of this interaction
|
52
|
+
# @return [Fixnum] elapsed time of this request in milliseconds
|
53
|
+
attr_accessor :time
|
54
|
+
# Request data for this interaction
|
55
|
+
# @return [Request] 'Request' object with request-related data
|
56
|
+
attr_accessor :request
|
57
|
+
# Response data for this interaction
|
58
|
+
# @return [Response] 'Response' object with response-related data
|
59
|
+
attr_accessor :response
|
60
|
+
# Info about cache usage for this interaction
|
61
|
+
# @return [Hash] data about cache usage as a hash
|
62
|
+
attr_accessor :cache
|
63
|
+
# Info about Request/Response round trip
|
64
|
+
# @return [Hash] timings data as a hash
|
65
|
+
# @example
|
66
|
+
# {"blocked"=>15, "dns"=>0, "connect"=>0, "send"=>0, "wait"=>39, "receive"=>0}
|
67
|
+
attr_accessor :timings
|
68
|
+
# IP address of the server
|
69
|
+
# @return [String] ip address as string, e.g. "91.239.200.165"
|
70
|
+
attr_accessor :server_ip_address
|
71
|
+
# Client or server port number
|
72
|
+
# @return [String] port number as string, e.g. "80"
|
73
|
+
attr_accessor :connection
|
74
|
+
end
|
75
|
+
|
76
|
+
# Holds information about the performed request in an interaction
|
77
|
+
class Request
|
78
|
+
# The method of this request
|
79
|
+
# @return [String] request method as string, e.g. "GET"
|
80
|
+
attr_accessor :http_method
|
81
|
+
# The absolute url of the request
|
82
|
+
# @return [String] url as string, e.g. "http://www.spiegel.de/layout/css/style-V3-23.css"
|
83
|
+
attr_accessor :url
|
84
|
+
# The HTTP version of this request
|
85
|
+
# @return [String] HTTP version as string, e.g. "HTTP/1.1"
|
86
|
+
attr_accessor :http_version
|
87
|
+
# A list of cookie objects for this request
|
88
|
+
# @return [Array] list of cookie objects as an array
|
89
|
+
attr_accessor :cookies
|
90
|
+
# A list of query parameters for this request
|
91
|
+
# @return [Array] list of query parameters as an array
|
92
|
+
attr_accessor :query_string
|
93
|
+
# The headers of this request
|
94
|
+
# @return [Hash] header objects (strings) as a hash
|
95
|
+
# @example
|
96
|
+
# {"Host"=>"...", "User-Agent"=>"...", "Accept"=>"...", "Accept-Language"=>"...", "Accept-Encoding"=>"...", "Connection"=>"..."}
|
97
|
+
attr_accessor :headers
|
98
|
+
# Size of the request header
|
99
|
+
# @return [Fixnum] header size of this request in bytes, -1 if not available
|
100
|
+
attr_accessor :headers_size
|
101
|
+
# Size of the request body (POST data payload)
|
102
|
+
# @return [Fixnum] body size of this request in bytes, -1 if not available
|
103
|
+
attr_accessor :body_size
|
104
|
+
end
|
105
|
+
|
106
|
+
# Holds information about the response for an interaction
|
107
|
+
class Response
|
108
|
+
# The status of this request
|
109
|
+
# @return [Fixnum] response status as number, e.g. 200
|
110
|
+
attr_accessor :status
|
111
|
+
# The status of this request as text description
|
112
|
+
# @return [String] response status as string, e.g. "OK"
|
113
|
+
attr_accessor :status_text
|
114
|
+
# The HTTP version of this response
|
115
|
+
# @return [String] HTTP version as string, e.g. "HTTP/1.1"
|
116
|
+
attr_accessor :http_version
|
117
|
+
# A list of cookie objects for this response
|
118
|
+
# @return [Array] list of cookie objects as an array
|
119
|
+
attr_accessor :cookies
|
120
|
+
# The headers of this response
|
121
|
+
# @return [Hash] header objects (strings) as a hash
|
122
|
+
# @example
|
123
|
+
# {"Date"=>"...", "Server"=>"...", "Location"=>"...", "Cache-Control"=>"...", "Expires"=>"...", "Content-Length"=>"...", "Keep-Alive"=>"...", "Connection"=>"...", "Content-Type"=>"..."}
|
124
|
+
attr_accessor :headers
|
125
|
+
# Size of the response header
|
126
|
+
# @return [Fixnum] header size of this response in bytes, -1 if not available
|
127
|
+
attr_accessor :headers_size
|
128
|
+
# Size of the response body
|
129
|
+
# @return [Fixnum] body size of this request in bytes, -1 if not available, 0 if from cache
|
130
|
+
attr_accessor :body_size
|
131
|
+
# Content of the response body
|
132
|
+
# @return [Hash] response body objects (strings) as a hash
|
133
|
+
# @example
|
134
|
+
# {"mimeType"=>"text/html", "size"=>0}
|
135
|
+
attr_accessor :content
|
136
|
+
# Redirection target URL from location response header.
|
137
|
+
# @return [String] redirect URL as string, e.g. "blog/index.php"
|
138
|
+
attr_accessor :redirect_url
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: http_archive
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexander Huber
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: json
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: A library to interact with HTTP Archives (.har files)
|
70
|
+
email:
|
71
|
+
- alih83@gmx.de
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- lib/http_archive.rb
|
77
|
+
- lib/http_archive/archive.rb
|
78
|
+
- lib/http_archive/classes.rb
|
79
|
+
- lib/http_archive/version.rb
|
80
|
+
homepage: http://github.com/alihuber/http_archive
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.0.3
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Interact with HTTP Archives, loosely following the interface of the Archive::HAR
|
104
|
+
Perl module
|
105
|
+
test_files: []
|
106
|
+
has_rdoc:
|