mu 5.7.8 → 5.7.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/mu.rb +1 -1
- data/lib/mu/command.rb +18 -2
- data/lib/mu/command/cmd_musl.rb +165 -0
- data/lib/mu/command/cmd_runscale.rb +12 -8
- data/lib/mu/command/help.rb +1 -0
- data/lib/mu/har.rb +449 -0
- data/lib/mu/libxml.rb +21 -0
- data/lib/mu/maker.rb +288 -0
- data/lib/mu/xmlizable.rb +559 -0
- metadata +78 -267
- data/rdoc/Gemfile.html +0 -194
- data/rdoc/LICENSE_txt.html +0 -201
- data/rdoc/Mu.html +0 -478
- data/rdoc/Mu/Client.html +0 -461
- data/rdoc/Mu/Command.html +0 -338
- data/rdoc/Mu/Command/API.html +0 -844
- data/rdoc/Mu/Command/Cmd_appid.html +0 -1341
- data/rdoc/Mu/Command/Cmd_cli.html +0 -800
- data/rdoc/Mu/Command/Cmd_ddt.html +0 -1612
- data/rdoc/Mu/Command/Cmd_homepage.html +0 -762
- data/rdoc/Mu/Command/Cmd_muapi.html +0 -1363
- data/rdoc/Mu/Command/Cmd_netconfig.html +0 -1077
- data/rdoc/Mu/Command/Cmd_runscale.html +0 -1441
- data/rdoc/Mu/Command/Cmd_runscenario.html +0 -787
- data/rdoc/Mu/Command/Cmd_runverify.html +0 -893
- data/rdoc/Mu/Command/Cmd_scale.html +0 -1323
- data/rdoc/Mu/Command/Cmd_system.html +0 -677
- data/rdoc/Mu/Command/Curl.html +0 -751
- data/rdoc/Mu/Command/Help.html +0 -305
- data/rdoc/Mu/Curl.html +0 -243
- data/rdoc/Mu/Curl/Error.html +0 -304
- data/rdoc/Mu/Curl/Error/Authorize.html +0 -355
- data/rdoc/Mu/Curl/Error/Connect.html +0 -286
- data/rdoc/Mu/Curl/Error/DNS.html +0 -236
- data/rdoc/Mu/Curl/Error/Region.html +0 -307
- data/rdoc/Mu/Curl/Error/Status.html +0 -286
- data/rdoc/Mu/Curl/Error/Timeout.html +0 -286
- data/rdoc/Mu/Curl/Verify.html +0 -472
- data/rdoc/Mu/Curl/Verify/Request.html +0 -424
- data/rdoc/Mu/Curl/Verify/Response.html +0 -372
- data/rdoc/Mu/Curl/Verify/Result.html +0 -373
- data/rdoc/Mu/Ddt.html +0 -1347
- data/rdoc/Mu/Helper.html +0 -517
- data/rdoc/Mu/Homepage.html +0 -719
- data/rdoc/Mu/HttpHelper.html +0 -890
- data/rdoc/Mu/Muapi.html +0 -1226
- data/rdoc/Mu/Netconfig.html +0 -1178
- data/rdoc/Mu/Scale.html +0 -1359
- data/rdoc/Mu/System.html +0 -504
- data/rdoc/Object.html +0 -285
- data/rdoc/README_rdoc.html +0 -892
- data/rdoc/Rakefile.html +0 -257
- data/rdoc/TCTestMu.html +0 -2583
- data/rdoc/Test.html +0 -235
- data/rdoc/Test/Unit.html +0 -235
- data/rdoc/Test/Unit/TestCase.html +0 -236
- data/rdoc/Test/helper_rb.html +0 -62
- data/rdoc/Test/tc_test_mu_rb.html +0 -60
- data/rdoc/VERSION.html +0 -179
- data/rdoc/bin/mu.html +0 -54
- data/rdoc/classes/Mu.html +0 -132
- data/rdoc/classes/Mu/Client.html +0 -214
- data/rdoc/classes/Mu/Command.html +0 -129
- data/rdoc/classes/Mu/Command/API.html +0 -362
- data/rdoc/classes/Mu/Command/Cmd_appid.html +0 -238
- data/rdoc/classes/Mu/Command/Cmd_cli.html +0 -273
- data/rdoc/classes/Mu/Command/Cmd_ddt.html +0 -639
- data/rdoc/classes/Mu/Command/Cmd_homepage.html +0 -276
- data/rdoc/classes/Mu/Command/Cmd_muapi.html +0 -527
- data/rdoc/classes/Mu/Command/Cmd_netconfig.html +0 -399
- data/rdoc/classes/Mu/Command/Cmd_runscale.html +0 -220
- data/rdoc/classes/Mu/Command/Cmd_runscenario.html +0 -197
- data/rdoc/classes/Mu/Command/Cmd_runverify.html +0 -196
- data/rdoc/classes/Mu/Command/Cmd_scale.html +0 -511
- data/rdoc/classes/Mu/Command/Cmd_system.html +0 -236
- data/rdoc/classes/Mu/Command/Curl.html +0 -182
- data/rdoc/classes/Mu/Command/Help.html +0 -137
- data/rdoc/classes/Mu/Curl.html +0 -116
- data/rdoc/classes/Mu/Curl/Error.html +0 -148
- data/rdoc/classes/Mu/Curl/Error/Authorize.html +0 -165
- data/rdoc/classes/Mu/Curl/Error/Connect.html +0 -139
- data/rdoc/classes/Mu/Curl/Error/DNS.html +0 -113
- data/rdoc/classes/Mu/Curl/Error/Region.html +0 -150
- data/rdoc/classes/Mu/Curl/Error/Status.html +0 -139
- data/rdoc/classes/Mu/Curl/Error/Timeout.html +0 -139
- data/rdoc/classes/Mu/Curl/Verify.html +0 -207
- data/rdoc/classes/Mu/Curl/Verify/Request.html +0 -187
- data/rdoc/classes/Mu/Curl/Verify/Response.html +0 -172
- data/rdoc/classes/Mu/Curl/Verify/Result.html +0 -172
- data/rdoc/classes/Mu/Ddt.html +0 -610
- data/rdoc/classes/Mu/Helper.html +0 -308
- data/rdoc/classes/Mu/Homepage.html +0 -306
- data/rdoc/classes/Mu/HttpHelper.html +0 -393
- data/rdoc/classes/Mu/Muapi.html +0 -549
- data/rdoc/classes/Mu/Netconfig.html +0 -478
- data/rdoc/classes/Mu/Scale.html +0 -580
- data/rdoc/classes/Mu/System.html +0 -232
- data/rdoc/classes/Object.html +0 -139
- data/rdoc/classes/TCTestMu.html +0 -948
- data/rdoc/classes/Test.html +0 -107
- data/rdoc/classes/Test/Unit.html +0 -107
- data/rdoc/classes/Test/Unit/TestCase.html +0 -113
- data/rdoc/created.rid +0 -36
- data/rdoc/files/lib/mu/api/ddt_rb.html +0 -101
- data/rdoc/files/lib/mu/api/homepage_rb.html +0 -101
- data/rdoc/files/lib/mu/api/muapi_rb.html +0 -101
- data/rdoc/files/lib/mu/api/netconfig_rb.html +0 -101
- data/rdoc/files/lib/mu/api/scale_rb.html +0 -101
- data/rdoc/files/lib/mu/api/system_rb.html +0 -101
- data/rdoc/files/lib/mu/client_rb.html +0 -101
- data/rdoc/files/lib/mu/command/api_rb.html +0 -101
- data/rdoc/files/lib/mu/command/cmd_appid_rb.html +0 -119
- data/rdoc/files/lib/mu/command/cmd_cli_rb.html +0 -108
- data/rdoc/files/lib/mu/command/cmd_ddt_rb.html +0 -116
- data/rdoc/files/lib/mu/command/cmd_homepage_rb.html +0 -115
- data/rdoc/files/lib/mu/command/cmd_muapi_rb.html +0 -115
- data/rdoc/files/lib/mu/command/cmd_netconfig_rb.html +0 -116
- data/rdoc/files/lib/mu/command/cmd_runscale_rb.html +0 -119
- data/rdoc/files/lib/mu/command/cmd_runscenario_rb.html +0 -115
- data/rdoc/files/lib/mu/command/cmd_runverify_rb.html +0 -118
- data/rdoc/files/lib/mu/command/cmd_scale_rb.html +0 -115
- data/rdoc/files/lib/mu/command/cmd_system_rb.html +0 -116
- data/rdoc/files/lib/mu/command/curl_rb.html +0 -101
- data/rdoc/files/lib/mu/command/help_rb.html +0 -101
- data/rdoc/files/lib/mu/command_rb.html +0 -107
- data/rdoc/files/lib/mu/curl/error_rb.html +0 -101
- data/rdoc/files/lib/mu/curl/verify_rb.html +0 -101
- data/rdoc/files/lib/mu/helper_rb.html +0 -101
- data/rdoc/files/lib/mu/http_helper_rb.html +0 -101
- data/rdoc/files/lib/mu_rb.html +0 -121
- data/rdoc/files/test/helper_rb.html +0 -112
- data/rdoc/files/test/tc_test_mu_rb.html +0 -111
- data/rdoc/fr_class_index.html +0 -34
- data/rdoc/fr_file_index.html +0 -31
- data/rdoc/fr_method_index.html +0 -112
- data/rdoc/images/brick.png +0 -0
- data/rdoc/images/brick_link.png +0 -0
- data/rdoc/images/bug.png +0 -0
- data/rdoc/images/bullet_black.png +0 -0
- data/rdoc/images/bullet_toggle_minus.png +0 -0
- data/rdoc/images/bullet_toggle_plus.png +0 -0
- data/rdoc/images/date.png +0 -0
- data/rdoc/images/find.png +0 -0
- data/rdoc/images/loadingAnimation.gif +0 -0
- data/rdoc/images/macFFBgHack.png +0 -0
- data/rdoc/images/package.png +0 -0
- data/rdoc/images/page_green.png +0 -0
- data/rdoc/images/page_white_text.png +0 -0
- data/rdoc/images/page_white_width.png +0 -0
- data/rdoc/images/plugin.png +0 -0
- data/rdoc/images/ruby.png +0 -0
- data/rdoc/images/tag_green.png +0 -0
- data/rdoc/images/wrench.png +0 -0
- data/rdoc/images/wrench_orange.png +0 -0
- data/rdoc/images/zoom.png +0 -0
- data/rdoc/index.html +0 -884
- data/rdoc/js/darkfish.js +0 -116
- data/rdoc/js/jquery.js +0 -32
- data/rdoc/js/quicksearch.js +0 -114
- data/rdoc/js/thickbox-compressed.js +0 -10
- data/rdoc/lib/mu/api/ddt_rb.html +0 -52
- data/rdoc/lib/mu/api/homepage_rb.html +0 -52
- data/rdoc/lib/mu/api/muapi_rb.html +0 -52
- data/rdoc/lib/mu/api/netconfig_rb.html +0 -52
- data/rdoc/lib/mu/api/scale_rb.html +0 -52
- data/rdoc/lib/mu/api/system_rb.html +0 -52
- data/rdoc/lib/mu/client_rb.html +0 -52
- data/rdoc/lib/mu/command/api_rb.html +0 -52
- data/rdoc/lib/mu/command/cmd_appid_rb.html +0 -62
- data/rdoc/lib/mu/command/cmd_cli_rb.html +0 -55
- data/rdoc/lib/mu/command/cmd_ddt_rb.html +0 -60
- data/rdoc/lib/mu/command/cmd_homepage_rb.html +0 -57
- data/rdoc/lib/mu/command/cmd_muapi_rb.html +0 -59
- data/rdoc/lib/mu/command/cmd_netconfig_rb.html +0 -58
- data/rdoc/lib/mu/command/cmd_runscale_rb.html +0 -62
- data/rdoc/lib/mu/command/cmd_runscenario_rb.html +0 -57
- data/rdoc/lib/mu/command/cmd_runverify_rb.html +0 -61
- data/rdoc/lib/mu/command/cmd_scale_rb.html +0 -58
- data/rdoc/lib/mu/command/cmd_system_rb.html +0 -59
- data/rdoc/lib/mu/command/curl_rb.html +0 -52
- data/rdoc/lib/mu/command/help_rb.html +0 -52
- data/rdoc/lib/mu/command_rb.html +0 -55
- data/rdoc/lib/mu/curl/error_rb.html +0 -52
- data/rdoc/lib/mu/curl/verify_rb.html +0 -52
- data/rdoc/lib/mu/helper_rb.html +0 -52
- data/rdoc/lib/mu/http_helper_rb.html +0 -52
- data/rdoc/lib/mu_rb.html +0 -80
- data/rdoc/rdoc-style.css +0 -208
- data/rdoc/rdoc.css +0 -706
- data/test/data/app_id_stats.csv +0 -1
- data/test/data/app_id_status.json +0 -156
- data/test/data/data_cgi.msl +0 -94
- data/test/data/data_cgi.xml +0 -322
- data/test/data/default_test.csv +0 -3
- data/test/data/ftp_with_channel.xml +0 -1643
- data/test/data/irc.xml +0 -3837
- data/test/data/scale.json +0 -25
- data/test/data/test_data_cgi_error.xml +0 -35
data/lib/mu.rb
CHANGED
data/lib/mu/command.rb
CHANGED
|
@@ -13,16 +13,32 @@ class Test::Unit::Assertions::AssertionMessage
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
=end
|
|
16
|
+
require 'optparse'
|
|
17
|
+
require 'ostruct'
|
|
16
18
|
|
|
17
19
|
class Mu
|
|
18
|
-
class Command
|
|
20
|
+
class Command
|
|
19
21
|
#include Test::Unit::Assertions
|
|
20
22
|
include Helper
|
|
23
|
+
|
|
24
|
+
attr_accessor :options, :opts
|
|
25
|
+
|
|
26
|
+
def initialize
|
|
27
|
+
# Set defaults
|
|
28
|
+
@options = OpenStruct.new
|
|
29
|
+
@options.verbose = false
|
|
30
|
+
|
|
31
|
+
# TO DO - add additional defaults
|
|
32
|
+
@opts = OptionParser.new
|
|
33
|
+
@opts.on('-V', '--verbose') { @options.verbose = true }
|
|
34
|
+
|
|
35
|
+
end
|
|
21
36
|
|
|
22
37
|
@@mu_ip = ENV['MU_IP']
|
|
23
38
|
@@mu_admin_user = ENV['MU_ADMIN_USER']
|
|
24
39
|
@@mu_admin_pass = ENV['MU_ADMIN_PASS']
|
|
25
|
-
|
|
40
|
+
|
|
41
|
+
end # Command
|
|
26
42
|
end # Mu
|
|
27
43
|
|
|
28
44
|
Dir["#{File.dirname(__FILE__)}/command/*.rb"].each { |c| require c }
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# File manipulation and generation class for creating musl files from other file formats.
|
|
2
|
+
# Example: $mu cmd_musl:from_har --ignore-css --ignore-js --endpoint <path_to_har_file>
|
|
3
|
+
require 'mu/maker'
|
|
4
|
+
require 'mu/har'
|
|
5
|
+
|
|
6
|
+
class Mu
|
|
7
|
+
class Command
|
|
8
|
+
class Cmd_musl < Command
|
|
9
|
+
include MuSL
|
|
10
|
+
|
|
11
|
+
attr_accessor :arguments, :scenario, :ignores, :har
|
|
12
|
+
|
|
13
|
+
def initialize
|
|
14
|
+
super
|
|
15
|
+
@options.strip_large_content = false
|
|
16
|
+
@options.large_content_size = nil
|
|
17
|
+
# TO-DO clean up variable usage and declaration
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# displays command-line help
|
|
22
|
+
def cmd_help argv
|
|
23
|
+
setup argv
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# checks and parses the command line arguments, displays help if missing
|
|
27
|
+
def setup argv
|
|
28
|
+
@arguments = argv
|
|
29
|
+
@ignores = Array.new
|
|
30
|
+
|
|
31
|
+
# If options are parsed and args are valid setup is good else show help
|
|
32
|
+
if parsed_options? && arguments_valid?
|
|
33
|
+
true
|
|
34
|
+
else
|
|
35
|
+
cmds = [
|
|
36
|
+
"mu cmd_musl:help",
|
|
37
|
+
"mu cmd_musl:from_har <options> <har_file>",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
puts "#{@opts}"
|
|
41
|
+
puts
|
|
42
|
+
puts "Available Commands:"
|
|
43
|
+
cmds.each do | c |
|
|
44
|
+
puts c
|
|
45
|
+
end
|
|
46
|
+
puts
|
|
47
|
+
puts "Outputs:"
|
|
48
|
+
puts "Scenario file: <harfilename>.msl by default or filename from -s"
|
|
49
|
+
|
|
50
|
+
false
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end # setup
|
|
54
|
+
|
|
55
|
+
# Turns a har file into a musl scenario file
|
|
56
|
+
def cmd_from_har argv
|
|
57
|
+
# Check if our command line arguments are valid
|
|
58
|
+
if setup argv
|
|
59
|
+
# Get har object and hosts
|
|
60
|
+
har_file = @options.har_files[0]
|
|
61
|
+
@har = Har.new har_file, @options, @ignores
|
|
62
|
+
msl_file = File.open(@options.scenario,'w')
|
|
63
|
+
created_musl = @har.generate msl_file
|
|
64
|
+
msl_file.write created_musl
|
|
65
|
+
msl_file.close
|
|
66
|
+
puts "You have successfully generated a scenario: #{@options.scenario}"
|
|
67
|
+
else
|
|
68
|
+
# Handle failure logic here
|
|
69
|
+
raise "Invalid Command Line Options"
|
|
70
|
+
end
|
|
71
|
+
end # end cmd_from_har
|
|
72
|
+
|
|
73
|
+
# Turns a pcap into a scenario file
|
|
74
|
+
def cmd_from_pcap argv
|
|
75
|
+
# TODO LATER
|
|
76
|
+
raise "This command isn't implemented yet"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
# Show the help banner
|
|
84
|
+
def help
|
|
85
|
+
setup ARGV
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# True if at least one har file has been entered
|
|
89
|
+
def arguments_valid?
|
|
90
|
+
# TO DO - implement better logic here
|
|
91
|
+
if(@arguments.length > 0)
|
|
92
|
+
true
|
|
93
|
+
else
|
|
94
|
+
false
|
|
95
|
+
end
|
|
96
|
+
end # arguments valid()
|
|
97
|
+
|
|
98
|
+
# True if options were parsed or not needed
|
|
99
|
+
def parsed_options?
|
|
100
|
+
# specify the command line options and their logic
|
|
101
|
+
|
|
102
|
+
# Set a banner, displayed at the top
|
|
103
|
+
# of the help screen.
|
|
104
|
+
@opts.banner = "Usage: mu cmd_musl:<command> <options> [FILE]"
|
|
105
|
+
|
|
106
|
+
# Define the options, and what they do
|
|
107
|
+
@opts.on( '--ignore-non-essentials', 'Ignore App-Unknown/JS/CSS/Image files' ) do
|
|
108
|
+
@options.ignore = true
|
|
109
|
+
@ignores.push('text/css','application/javascript','application/x-javascript','text/javascript','application/octet-stream','application/x-unknown-content-type','image/png','image/jpg','image/jpeg','image/gif')
|
|
110
|
+
end
|
|
111
|
+
# Define the options, and what they do
|
|
112
|
+
@opts.on( '--ignore-images', 'Ignore Image files' ) do
|
|
113
|
+
@options.ignore = true
|
|
114
|
+
@ignores.push('image/png','image/jpg','image/jpeg','image/gif')
|
|
115
|
+
end
|
|
116
|
+
# Define the options, and what they do
|
|
117
|
+
@opts.on( '--ignore-css', 'Ignore CSS files' ) do
|
|
118
|
+
@options.ignore = true
|
|
119
|
+
@ignores.push('text/css')
|
|
120
|
+
end
|
|
121
|
+
@opts.on( '--ignore-js', 'Ignore Javascript files' ) do
|
|
122
|
+
@options.ignore = true
|
|
123
|
+
@ignores.push('application/javascript','application/x-javascript','text/javascript')
|
|
124
|
+
end
|
|
125
|
+
@opts.on( '--ignore-payload', 'Ignore the content payload' ) do
|
|
126
|
+
@options.ignore_payload = true
|
|
127
|
+
end
|
|
128
|
+
@opts.on('--strip-large-content [SIZE]',
|
|
129
|
+
Integer,
|
|
130
|
+
'Replace large response content with a repeated field') do |size|
|
|
131
|
+
@options.strip_large_content = true
|
|
132
|
+
@options.large_content_size = size
|
|
133
|
+
end
|
|
134
|
+
@opts.on( '--endpoint', 'One way communication' ) do
|
|
135
|
+
@options.endpoint = true
|
|
136
|
+
end
|
|
137
|
+
@opts.on( '-s', '--scenario [FILENAME]', 'Specify the msl filename to be created' ) do |scenario|
|
|
138
|
+
@options.scenario = scenario
|
|
139
|
+
end
|
|
140
|
+
# Remove all options just leaving the harfiles
|
|
141
|
+
@opts.parse! @arguments rescue return false
|
|
142
|
+
@options.har_files = @arguments
|
|
143
|
+
unless @options.scenario
|
|
144
|
+
# Identical filename replacing the extension har with msl
|
|
145
|
+
begin
|
|
146
|
+
filename = @options.har_files[0].dup
|
|
147
|
+
@options.scenario = filename.gsub!(/\.har/,".msl")
|
|
148
|
+
rescue
|
|
149
|
+
# Filename is missing which means we'll show help string
|
|
150
|
+
return false
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
true
|
|
156
|
+
end # parsed_options()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
end # Cmd_musl
|
|
163
|
+
end # Command
|
|
164
|
+
end # Mu
|
|
165
|
+
|
|
@@ -187,7 +187,10 @@ class Mu
|
|
|
187
187
|
raise "Failed to read in scenario #{scenario}"
|
|
188
188
|
end
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
if @testset.empty?
|
|
191
|
+
@api.configure("csv", "")
|
|
192
|
+
else
|
|
193
|
+
msg "using testset [#{@testset}]", Logger::INFO
|
|
191
194
|
@api.configure("csv", File.read(@testset))
|
|
192
195
|
end
|
|
193
196
|
|
|
@@ -339,7 +342,7 @@ class Mu
|
|
|
339
342
|
|
|
340
343
|
def dump_status(status, msl)
|
|
341
344
|
filename = "app_id_status.json"
|
|
342
|
-
msg "Update status to: #{File.
|
|
345
|
+
msg "Update status to: #{File.expand_path(filename)}", Logger::INFO
|
|
343
346
|
f = File.open(filename, "a")
|
|
344
347
|
status["filename"] = msl
|
|
345
348
|
str = JSON.pretty_generate(status)
|
|
@@ -350,7 +353,7 @@ class Mu
|
|
|
350
353
|
|
|
351
354
|
def output_csv(msl_file)
|
|
352
355
|
filename = "app_id_stats.csv"
|
|
353
|
-
msg "Update stats to: #{File.
|
|
356
|
+
msg "Update stats to: #{File.expand_path(filename)}", Logger::INFO
|
|
354
357
|
unless File.exists?(filename)
|
|
355
358
|
heading = "scenario,executed,errors,timeouts,client_tx_bytes,client_tx_msgs,client_rx_bytes,client_rx_msgs,server_tx_bytes,server_tx_msgs,server_rx_bytes,server_rx_msgs"
|
|
356
359
|
File.open(filename, 'a'){|f| f.puts(heading)}
|
|
@@ -361,9 +364,9 @@ class Mu
|
|
|
361
364
|
|
|
362
365
|
def output_verify_results(msl_file)
|
|
363
366
|
filename = "app_id_stats.csv"
|
|
364
|
-
msg "Update verify results to: #{File.
|
|
367
|
+
msg "Update verify results to: #{File.expand_path(filename)}", Logger::DEBUG
|
|
365
368
|
unless File.exists?(filename)
|
|
366
|
-
msg "Writting verify results to: #{File.
|
|
369
|
+
msg "Writting verify results to: #{File.expand_path(filename)}", Logger::INFO
|
|
367
370
|
heading = "scenario, status"
|
|
368
371
|
File.open(filename, 'a'){|f| f.puts(heading)}
|
|
369
372
|
end
|
|
@@ -372,7 +375,7 @@ class Mu
|
|
|
372
375
|
|
|
373
376
|
def parse_verify_response(response)
|
|
374
377
|
if response.nil? # || response.empty?
|
|
375
|
-
msg "*** error = no response received from /verify
|
|
378
|
+
msg "*** error = no response received from /verify ***", Logger::ERROR
|
|
376
379
|
@verify_response = "Error = No response from verify"
|
|
377
380
|
return @verify_response
|
|
378
381
|
end
|
|
@@ -382,7 +385,7 @@ class Mu
|
|
|
382
385
|
if response["status"]["error"] == true
|
|
383
386
|
@error = response["status"]["error"]
|
|
384
387
|
@reason = response["status"]["reason"]
|
|
385
|
-
msg "*** Error = #{@error}, reason = #{@reason}
|
|
388
|
+
msg "*** Error = #{@error}, reason = #{@reason} ***", Logger::ERROR
|
|
386
389
|
@verify_response = "Error = #{@error}, reason = #{@reason}"
|
|
387
390
|
return @verify_response
|
|
388
391
|
end
|
|
@@ -404,7 +407,7 @@ class Mu
|
|
|
404
407
|
if status["status"]["error"] == true
|
|
405
408
|
@error = status["status"]["error"]
|
|
406
409
|
@reason = status["status"]["reason"]
|
|
407
|
-
msg "*** Error = #{@error}, reason = #{@reason}
|
|
410
|
+
msg "*** Error = #{@error}, reason = #{@reason} ***"
|
|
408
411
|
return nil
|
|
409
412
|
end
|
|
410
413
|
end
|
|
@@ -527,6 +530,7 @@ class Mu
|
|
|
527
530
|
|
|
528
531
|
if [ '-o', '--output' ].member? k
|
|
529
532
|
$stdout.reopen(shift(k, argv), "w")
|
|
533
|
+
$stdout.sync = true
|
|
530
534
|
next
|
|
531
535
|
end
|
|
532
536
|
|
data/lib/mu/command/help.rb
CHANGED
|
@@ -11,6 +11,7 @@ class Help < Command
|
|
|
11
11
|
{ :cmd => 'mu cmd_ddt:help', :help => 'Show help on using the Studio Verify Api through the command-line' },
|
|
12
12
|
{ :cmd => 'mu cmd_homepage:help', :help => 'Show help on using the Homepage Api through the command-line' },
|
|
13
13
|
{ :cmd => 'mu cmd_muapi:help', :help => 'Show help on using the Mu Api for fuzzing, templates, backup and archive' },
|
|
14
|
+
{ :cmd => 'mu cmd_musl:help', :help => 'Show help on using the Musl Api through the command-line' },
|
|
14
15
|
{ :cmd => 'mu cmd_netconfig:help', :help => 'Show help on using the Netconfig Api through the command-line'},
|
|
15
16
|
{ :cmd => 'mu cmd_runscale:help', :help => 'Show help on running the Studio Scale app'},
|
|
16
17
|
{ :cmd => 'mu cmd_runscenario:help', :help => 'Show help on running the Scenario Editor Verify app' },
|
data/lib/mu/har.rb
ADDED
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
# To change this template, choose Tools | Templates
|
|
2
|
+
# and open the template in the editor.
|
|
3
|
+
require 'mu/maker'
|
|
4
|
+
require 'mu/xmlizable'
|
|
5
|
+
|
|
6
|
+
class Har
|
|
7
|
+
HTTP_CONTENT_LENGTH_HEADER = 'Content-Length'
|
|
8
|
+
HTTP_CONTENT_TYPE_HEADER = 'Content-Type'
|
|
9
|
+
HTTP_CONTENT_ENCODING_HEADER = 'Content-Encoding'
|
|
10
|
+
HTTP_TRANSFER_ENCODING_HEADER = 'Transfer-Encoding'
|
|
11
|
+
HTTP_CONTENT_TRANSFER_ENCODING_HEADER = 'Content-Transfer-Encoding'
|
|
12
|
+
|
|
13
|
+
HTTP_FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded'
|
|
14
|
+
HTTP_TEXT_PLAIN_CONTENT_TYPE = 'text/plain'
|
|
15
|
+
HTTP_TEXT_HTML_CONTENT_TYPE = 'text/html'
|
|
16
|
+
HTTP_TEXT_XML_CONTENT_TYPE = 'text/xml'
|
|
17
|
+
HTTP_APPLICATION_XML_CONTENT_TYPE = 'application/xml'
|
|
18
|
+
HTTP_TEXT_JSON_CONTENT_TYPE = 'text/json'
|
|
19
|
+
HTTP_APPLICATION_JSON_CONTENT_TYPE = 'application/json'
|
|
20
|
+
HTTP_TEXT_JAVASCRIPT_CONTENT_TYPE = 'text/javascript'
|
|
21
|
+
HTTP_APPLICATION_JAVASCRIPT_CONTENT_TYPE = 'application/x-javascript'
|
|
22
|
+
HTTP_TEXT_CSS_CONTENT_TYPE = 'text/css'
|
|
23
|
+
|
|
24
|
+
HTTP_TEXT_CONTENT_TYPES = [ HTTP_FORM_CONTENT_TYPE,
|
|
25
|
+
HTTP_TEXT_PLAIN_CONTENT_TYPE,
|
|
26
|
+
HTTP_TEXT_HTML_CONTENT_TYPE,
|
|
27
|
+
HTTP_TEXT_XML_CONTENT_TYPE,
|
|
28
|
+
HTTP_APPLICATION_XML_CONTENT_TYPE,
|
|
29
|
+
HTTP_TEXT_JSON_CONTENT_TYPE,
|
|
30
|
+
HTTP_APPLICATION_JSON_CONTENT_TYPE,
|
|
31
|
+
HTTP_TEXT_JAVASCRIPT_CONTENT_TYPE,
|
|
32
|
+
HTTP_APPLICATION_JAVASCRIPT_CONTENT_TYPE,
|
|
33
|
+
HTTP_TEXT_CSS_CONTENT_TYPE ]
|
|
34
|
+
|
|
35
|
+
HTTP_GZIP_CONTENT_ENCODING = 'gzip'
|
|
36
|
+
HTTP_DEFLATE_CONTENT_ENCODING = 'deflate'
|
|
37
|
+
|
|
38
|
+
HTTP_EMPTY_GZIP_BODY = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\x03\x00\x00" +
|
|
39
|
+
"\x00\x00\x00\x00\x00\x00\x00"
|
|
40
|
+
|
|
41
|
+
HTTP_CHUNKED_TRANSFER_ENCODING = 'chunked'
|
|
42
|
+
|
|
43
|
+
HTTP_VIDEO_X_MS_WMV_CONTENT_TYPE = 'video/x-ms-wmv'
|
|
44
|
+
HTTP_VIDEO_X_MS_WMA_CONTENT_TYPE = 'audio/x-ms-wma'
|
|
45
|
+
|
|
46
|
+
HTTP_STREAMING_CONTENT_TYPES = [ HTTP_VIDEO_X_MS_WMV_CONTENT_TYPE,
|
|
47
|
+
HTTP_VIDEO_X_MS_WMA_CONTENT_TYPE ]
|
|
48
|
+
|
|
49
|
+
HTTP_CONTENT_SLICE_SIZE = 1024
|
|
50
|
+
|
|
51
|
+
MSL_ESCAPES = XMLizable::ESCAPES.dup
|
|
52
|
+
MSL_ESCAPES['"'.ord] = %q{\"}
|
|
53
|
+
MSL_ESCAPES["'".ord] = %q{\'}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
attr_reader :har_file
|
|
57
|
+
attr_accessor :entries,:hosts,:har,:har_hosts
|
|
58
|
+
|
|
59
|
+
def initialize har_file, options, ignores
|
|
60
|
+
@har_file = har_file
|
|
61
|
+
@hosts = {}
|
|
62
|
+
@options = options
|
|
63
|
+
@ignores = ignores
|
|
64
|
+
begin
|
|
65
|
+
@har = JSON File.read(@har_file)
|
|
66
|
+
rescue Exception=>e
|
|
67
|
+
raise e
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Return a list of entries from the har file
|
|
73
|
+
def get_entries
|
|
74
|
+
@entries = @har['log']['entries']
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def generate ios
|
|
78
|
+
# Attempt to create the scenario
|
|
79
|
+
generated = MuSL::Maker.create do |scenario|
|
|
80
|
+
# First declare all the hosts
|
|
81
|
+
scenario.hosts do |host|
|
|
82
|
+
self.build_hosts host
|
|
83
|
+
end
|
|
84
|
+
# Then build all the steps
|
|
85
|
+
scenario.steps do |step|
|
|
86
|
+
self.build_steps step, scenario
|
|
87
|
+
end # scenario.steps
|
|
88
|
+
end # Maker.create
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Return a list of hosts from the har file
|
|
92
|
+
def get_hosts ignores, options
|
|
93
|
+
|
|
94
|
+
# Regex to check if certain kinds of entries should be ignored, like css, js, images based on command line options
|
|
95
|
+
ignores_regex = ignores.join('|')
|
|
96
|
+
|
|
97
|
+
# Iterate through each har entry and parse out the important url pieces
|
|
98
|
+
begin
|
|
99
|
+
hosts_seen = Hash.new(0)
|
|
100
|
+
host_count = 0
|
|
101
|
+
@har["log"]["entries"].each_with_index do |entry, index|
|
|
102
|
+
# Check our command line exclusions
|
|
103
|
+
if(options.ignore)
|
|
104
|
+
next if (entry['response']['content']['mimeType'] =~ /#{ignores_regex}/o )
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Build the hosts list
|
|
108
|
+
host = nil
|
|
109
|
+
m = entry["musl"] = {}
|
|
110
|
+
m["url_object"] = URI.parse entry["request"]["url"]
|
|
111
|
+
m["url"] = {}
|
|
112
|
+
m['url']['port'] = m["url_object"].port || (m["url_object"].scheme === 'http' ? 80 : 443)
|
|
113
|
+
m['url']['pathname'] = m['url_object'].path || '/'
|
|
114
|
+
m["url"]["search"] = m["url_object"].query || ''
|
|
115
|
+
m["url"]["hash"] = m["url_object"].fragment || ''
|
|
116
|
+
|
|
117
|
+
# Create the host entry hash with underscores instead of dots for the host value
|
|
118
|
+
entry['request']['headers'].each do |header|
|
|
119
|
+
if (!host && header['name'].downcase === 'host')
|
|
120
|
+
host = header['value']
|
|
121
|
+
# Set the hosts_seen value to host_count and increment the host_count unless we have already seen the host
|
|
122
|
+
hosts_seen[host] += host_count && host_count += 1 unless hosts_seen.has_key?(host)
|
|
123
|
+
|
|
124
|
+
# OLD WAY - Substitute the dots with underscores for the musl host
|
|
125
|
+
# OLD WAY entry['musl'][host] = host.gsub(/[^a-zA-Z0-9_]/, '_')
|
|
126
|
+
entry['musl'][host] = hosts_seen[host].to_s
|
|
127
|
+
|
|
128
|
+
if entry['musl'][host].match /^[0-9]/
|
|
129
|
+
entry['musl'][host] = 'host_' + entry['musl'][host]
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
@hosts[host] = entry['musl'][host]
|
|
136
|
+
entry['musl']['host'] = entry['musl'][host]
|
|
137
|
+
|
|
138
|
+
host = nil
|
|
139
|
+
|
|
140
|
+
if entry['response']['cookies']
|
|
141
|
+
#p "Entry-response-cookies: #{entry['response']['cookies']}"
|
|
142
|
+
entry['response']['cookies'].each do |cookie|
|
|
143
|
+
# TODO: Need to mark the index of this entry against
|
|
144
|
+
# this cookie so we can search for it easily.
|
|
145
|
+
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
end
|
|
150
|
+
rescue Exception => e
|
|
151
|
+
puts e.message
|
|
152
|
+
puts e.backtrace.inspect
|
|
153
|
+
raise e
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
return @hosts
|
|
157
|
+
end # get_hosts
|
|
158
|
+
|
|
159
|
+
# Finds a specific cookie from the response cookies
|
|
160
|
+
def find_cookie name, step
|
|
161
|
+
if step === 0
|
|
162
|
+
return
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
(step-1).downto(0) {|i|
|
|
166
|
+
entry = @entries[i]
|
|
167
|
+
res = entry['response']
|
|
168
|
+
if (res['cookies'] && res['cookies'].length > 0)
|
|
169
|
+
for j in 0..res['cookies'].length do
|
|
170
|
+
cookie = res['cookies'][j]
|
|
171
|
+
unless cookie.nil?
|
|
172
|
+
if cookie['name'] === name
|
|
173
|
+
return i
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return
|
|
181
|
+
end # find_cookie
|
|
182
|
+
|
|
183
|
+
# Takes the headers
|
|
184
|
+
def build_headers cs, headers, cookies, i
|
|
185
|
+
headers.each do |header|
|
|
186
|
+
# If this is a Cookie header, try and map the cookie
|
|
187
|
+
# value to a step variable preceding this step
|
|
188
|
+
if ('cookie' === header['name'].downcase)
|
|
189
|
+
#value = header['value']
|
|
190
|
+
value = XMLizable.escape(header['value'], MSL_ESCAPES)
|
|
191
|
+
for j in 0..cookies.length
|
|
192
|
+
cookie = cookies[j]
|
|
193
|
+
|
|
194
|
+
if defined? cookie['name']
|
|
195
|
+
step = self.find_cookie cookie['name'], i
|
|
196
|
+
# THE FOLLOWING LOGIC PROBABLY NEEDS FIXING FOR COOKIES
|
|
197
|
+
if (step != nil)
|
|
198
|
+
regex = /"(#{cookie['name']})" + "=([^;]*)"/
|
|
199
|
+
if value.match regex
|
|
200
|
+
raise "I KNOW THERE IS A PROBLE WITH THE code below"
|
|
201
|
+
# TODO: FIX THIS LOGIC
|
|
202
|
+
value = value.replace(regex, cookie['name'] + '=#{@cr' + step + '.' + cookie['name'].gsub(/[^a-zA-Z0-9_]/, '_') + '}')
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
cs.line(header['name'] + ': ' + value)
|
|
208
|
+
else
|
|
209
|
+
cs.line(header['name'] + ': ' + header['value'])
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
end #end headers.each
|
|
213
|
+
end # end build_headers
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def build_postdata cs, req, entry_count, scenario
|
|
217
|
+
|
|
218
|
+
if req['postData']['params'].length > 0
|
|
219
|
+
cs.header('Content-Length') do
|
|
220
|
+
cs.length_string({'of' => "body_#{entry_count}"})
|
|
221
|
+
end
|
|
222
|
+
cs.line()
|
|
223
|
+
|
|
224
|
+
cs.block('body_' + "#{entry_count}" + ' = struct [', ']') do
|
|
225
|
+
#assert_equal(req['postData']['mimeType'], 'application/x-www-form-urlencoded', 'unsupported mime type')
|
|
226
|
+
cs.block('dsv(delimiter: "&") [',']') do
|
|
227
|
+
req['postData']['params'].each do |param|
|
|
228
|
+
cs.block('struct [',']') do
|
|
229
|
+
cs.string(param['name'] + '=')
|
|
230
|
+
cs.block('uri_percent_encode [',']') do
|
|
231
|
+
cs.string param['value']
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
else
|
|
238
|
+
unless(@options.ignore_payload)
|
|
239
|
+
cs.line()
|
|
240
|
+
self.build_payload(cs, entry_count, req, scenario)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end # end build_postdata
|
|
244
|
+
|
|
245
|
+
def build_hosts hosts
|
|
246
|
+
# TODO: Right now v4 is hard-coded, need to change this
|
|
247
|
+
hosts.create 'host_0', 'v4', 'browser'
|
|
248
|
+
|
|
249
|
+
har_hosts = self.get_hosts @ignores, @options
|
|
250
|
+
|
|
251
|
+
# Build the host entries into the scenario
|
|
252
|
+
har_hosts.each do |hhost,har_host_value|
|
|
253
|
+
hosts.create(har_hosts[hhost], 'v4', hhost)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def build_steps steps, scenario
|
|
258
|
+
# Create the steps
|
|
259
|
+
entries = self.get_entries
|
|
260
|
+
entry_count = 0
|
|
261
|
+
for i in 0..entries.length
|
|
262
|
+
entry = entries[i]
|
|
263
|
+
next unless defined? entry['musl']
|
|
264
|
+
|
|
265
|
+
m = entry['musl']
|
|
266
|
+
req = entry['request']
|
|
267
|
+
res = entry['response']
|
|
268
|
+
next if m.nil?
|
|
269
|
+
|
|
270
|
+
xopts = { 'src' => '&host_0', 'dst' => '&' + "#{m['host']}" }
|
|
271
|
+
xklass = m['url_object'].scheme === 'http' ? 'tcp' : 'ssl'
|
|
272
|
+
xopts['dst_port'] = m['url']['port']
|
|
273
|
+
# Create the xport options in the scenario
|
|
274
|
+
steps.xport("xport#{entry_count}", xklass, xopts)
|
|
275
|
+
|
|
276
|
+
# client_send comments for each entry
|
|
277
|
+
steps.comment(req["method"] + ' ' + m['url']['pathname'] + ' ' + req['httpVersion'])
|
|
278
|
+
|
|
279
|
+
# main client_send lines for each entry
|
|
280
|
+
steps.client_send("cs#{entry_count}","xport#{entry_count}") do |cs|
|
|
281
|
+
cs.line(req['method'] + ' ' + m['url']['pathname'] + m['url']['search'] + m['url']['hash'] + ' ' + req['httpVersion'])
|
|
282
|
+
# For each header
|
|
283
|
+
self.build_headers cs, req['headers'], req['cookies'], i
|
|
284
|
+
|
|
285
|
+
# For building the form post params block
|
|
286
|
+
if req.has_key?('postData')
|
|
287
|
+
self.build_postdata cs, req, entry_count, scenario
|
|
288
|
+
else
|
|
289
|
+
cs.line('Content-Length: 0')
|
|
290
|
+
end # end if req.has_key('postData')
|
|
291
|
+
cs.line()
|
|
292
|
+
|
|
293
|
+
# For building the client content payload block into the scenario
|
|
294
|
+
if req.has_key?('content')
|
|
295
|
+
self.build_payload(cs, entry_count, req, scenario)
|
|
296
|
+
end unless @options.ignore_payload
|
|
297
|
+
|
|
298
|
+
end # end steps.client_send
|
|
299
|
+
|
|
300
|
+
# Skip the server side if the command line option included --endpint
|
|
301
|
+
unless @options.endpoint
|
|
302
|
+
steps.server_receive("sr#{entry_count}", "cs#{entry_count}") do ||
|
|
303
|
+
#return nil
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# For adding comment headers for the server side
|
|
307
|
+
steps.comment(res['httpVersion'] + ' ' + "#{res['status']}" + ' ' + res['statusText'])
|
|
308
|
+
|
|
309
|
+
# Build server_send portion
|
|
310
|
+
steps.server_send("ss#{entry_count}", "xport#{entry_count}") do |ss|
|
|
311
|
+
ss.line(res['httpVersion'] + ' ' + "#{res['status']}" + ' ' + res['statusText'])
|
|
312
|
+
res['headers'].each do |header|
|
|
313
|
+
ss.line(header['name'] + ': ' + header['value'])
|
|
314
|
+
end
|
|
315
|
+
ss.line()
|
|
316
|
+
|
|
317
|
+
# For building the server content payload block into the scenario
|
|
318
|
+
if res.has_key?('content')
|
|
319
|
+
build_payload ss, entry_count, res, scenario
|
|
320
|
+
end unless @options.ignore_payload
|
|
321
|
+
end # end server_send
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# If the endpoint option is chosen only include cs 'client send' values instead of ss 'server send' values
|
|
325
|
+
receive_side = @options.endpoint ? 'cs' : 'ss'
|
|
326
|
+
|
|
327
|
+
# Build client_receive portion
|
|
328
|
+
steps.client_receive("cr#{entry_count}", "#{receive_side}#{entry_count}") do |cr|
|
|
329
|
+
cr.assertions do |as|
|
|
330
|
+
as.create('/^HTTP\\/1\\.1 (\\d+)/ == ' + "#{res['status']}")
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
if (res['cookies'] && res['cookies'].length > 0)
|
|
334
|
+
cr.variables do |vs|
|
|
335
|
+
res['cookies'].each do |cookie|
|
|
336
|
+
vs.create('@' + cookie['name'].gsub(/[^a-zA-Z0-9_]/, '_') + ' = ' + '/' + cookie['name'] + '=([^;]*)' + '/:1')
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
entry_count += 1
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# If the payload is to be included, handle the inclusion logic here
|
|
346
|
+
def build_payload(cs_send, entry_count, req_res, scenario)
|
|
347
|
+
# If it is coming from the client side it will be part of the postData
|
|
348
|
+
payload = req_res.has_key?('content') ? req_res['content']['text'] : req_res['postData']['text']
|
|
349
|
+
#raise "req_res #{req_res} PAYLOAD #{payload}"
|
|
350
|
+
return if payload.nil?
|
|
351
|
+
|
|
352
|
+
content_encoding = false
|
|
353
|
+
transfer_encoding = false
|
|
354
|
+
|
|
355
|
+
# In case we need encoding types different than gzip, and chunked later on
|
|
356
|
+
req_res['headers'].each do |header|
|
|
357
|
+
if(header['name'] === 'Transfer-Encoding')
|
|
358
|
+
# We can do chunked
|
|
359
|
+
if header['value'] == HTTP_CHUNKED_TRANSFER_ENCODING
|
|
360
|
+
transfer_encoding = true
|
|
361
|
+
else
|
|
362
|
+
raise NotImplementedError, "Transfer-Encoding: #{header['value']}"
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
elsif(header['name'] === 'Content-Encoding')
|
|
366
|
+
# Check out content encoding
|
|
367
|
+
# We can do GZIP
|
|
368
|
+
if header['value'] == HTTP_GZIP_CONTENT_ENCODING
|
|
369
|
+
content_encoding = true
|
|
370
|
+
else
|
|
371
|
+
raise NotImplementedError, "Content-Encoding: #{header['value']}"
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
# http chunked
|
|
378
|
+
if transfer_encoding
|
|
379
|
+
cs_send.literal_no_format("http_chunk_encode(chunk_size: #{req_res['content']['size']}) [")
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
# gzip only for now
|
|
383
|
+
if content_encoding
|
|
384
|
+
cs_send.literal_no_format("gzip_compress[")
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# If we need to replace the content with a special repeated field
|
|
388
|
+
if @options.strip_large_content
|
|
389
|
+
body = []
|
|
390
|
+
|
|
391
|
+
if req_res['content']['size'] > @options.large_content_size
|
|
392
|
+
# Take first 1K bytes from the content and repeat
|
|
393
|
+
body << payload[0, HTTP_CONTENT_SLICE_SIZE]
|
|
394
|
+
else
|
|
395
|
+
# Set response body
|
|
396
|
+
body << payload
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# Yes calculate the number of 1K chunks we need to inject
|
|
400
|
+
count = req_res['content']['size'] / HTTP_CONTENT_SLICE_SIZE
|
|
401
|
+
remainder = req_res['content']['size'] % HTTP_CONTENT_SLICE_SIZE
|
|
402
|
+
|
|
403
|
+
# TODO: If there is a reminder add one more repeat count for now
|
|
404
|
+
if remainder > 0
|
|
405
|
+
count += 1
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
# Open the field
|
|
409
|
+
cs_send.literal_no_format("repeat(count: %d) [" % [count])
|
|
410
|
+
# No, write the content as binary string
|
|
411
|
+
cs_send.literal_no_format("\"0h")
|
|
412
|
+
|
|
413
|
+
# Write all blocks
|
|
414
|
+
body.each do |block|
|
|
415
|
+
# Write each byte in the block
|
|
416
|
+
block.each_byte do |byte|
|
|
417
|
+
cs_send.literal_no_format("%02x" % byte)
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
cs_send.literal_no_format("\"");
|
|
421
|
+
else
|
|
422
|
+
cs_send.literal_no_format("\"" + XMLizable.escape(payload, MSL_ESCAPES) + "\"")
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
# Close repeat field
|
|
427
|
+
if @options.strip_large_content
|
|
428
|
+
cs_send.literal_no_format("]")
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
# Close content encoding, if needed
|
|
432
|
+
if content_encoding
|
|
433
|
+
cs_send.literal_no_format("]")
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
# Close transfer encoding, if needed
|
|
437
|
+
if transfer_encoding
|
|
438
|
+
cs_send.literal_no_format("]")
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
end # build_payload()
|
|
442
|
+
|
|
443
|
+
# TO-DO: Implement this check
|
|
444
|
+
def text_body?
|
|
445
|
+
HTTP_TEXT_CONTENT_TYPES.include?(@content_type) and
|
|
446
|
+
not @content_transfer_encoding.to_s == 'binary' and
|
|
447
|
+
not @mu_content_transfer_encoding.to_s == 'binary'
|
|
448
|
+
end
|
|
449
|
+
end
|