1 | 'use strict'
|
2 |
|
3 | var fs = require('fs')
|
4 | var qs = require('querystring')
|
5 | var validate = require('har-validator')
|
6 | var extend = require('extend')
|
7 |
|
8 | function Har (request) {
|
9 | this.request = request
|
10 | }
|
11 |
|
12 | Har.prototype.reducer = function (obj, pair) {
|
13 |
|
14 | if (obj[pair.name] === undefined) {
|
15 | obj[pair.name] = pair.value
|
16 | return obj
|
17 | }
|
18 |
|
19 |
|
20 | var arr = [
|
21 | obj[pair.name],
|
22 | pair.value
|
23 | ]
|
24 |
|
25 | obj[pair.name] = arr
|
26 |
|
27 | return obj
|
28 | }
|
29 |
|
30 | Har.prototype.prep = function (data) {
|
31 |
|
32 | data.queryObj = {}
|
33 | data.headersObj = {}
|
34 | data.postData.jsonObj = false
|
35 | data.postData.paramsObj = false
|
36 |
|
37 |
|
38 | if (data.queryString && data.queryString.length) {
|
39 | data.queryObj = data.queryString.reduce(this.reducer, {})
|
40 | }
|
41 |
|
42 |
|
43 | if (data.headers && data.headers.length) {
|
44 |
|
45 | data.headersObj = data.headers.reduceRight(function (headers, header) {
|
46 | headers[header.name] = header.value
|
47 | return headers
|
48 | }, {})
|
49 | }
|
50 |
|
51 |
|
52 | if (data.cookies && data.cookies.length) {
|
53 | var cookies = data.cookies.map(function (cookie) {
|
54 | return cookie.name + '=' + cookie.value
|
55 | })
|
56 |
|
57 | if (cookies.length) {
|
58 | data.headersObj.cookie = cookies.join('; ')
|
59 | }
|
60 | }
|
61 |
|
62 |
|
63 | function some (arr) {
|
64 | return arr.some(function (type) {
|
65 | return data.postData.mimeType.indexOf(type) === 0
|
66 | })
|
67 | }
|
68 |
|
69 | if (some([
|
70 | 'multipart/mixed',
|
71 | 'multipart/related',
|
72 | 'multipart/form-data',
|
73 | 'multipart/alternative'])) {
|
74 |
|
75 |
|
76 | data.postData.mimeType = 'multipart/form-data'
|
77 | }
|
78 |
|
79 | else if (some([
|
80 | 'application/x-www-form-urlencoded'])) {
|
81 |
|
82 | if (!data.postData.params) {
|
83 | data.postData.text = ''
|
84 | } else {
|
85 | data.postData.paramsObj = data.postData.params.reduce(this.reducer, {})
|
86 |
|
87 |
|
88 | data.postData.text = qs.stringify(data.postData.paramsObj)
|
89 | }
|
90 | }
|
91 |
|
92 | else if (some([
|
93 | 'text/json',
|
94 | 'text/x-json',
|
95 | 'application/json',
|
96 | 'application/x-json'])) {
|
97 |
|
98 | data.postData.mimeType = 'application/json'
|
99 |
|
100 | if (data.postData.text) {
|
101 | try {
|
102 | data.postData.jsonObj = JSON.parse(data.postData.text)
|
103 | } catch (e) {
|
104 | this.request.debug(e)
|
105 |
|
106 |
|
107 | data.postData.mimeType = 'text/plain'
|
108 | }
|
109 | }
|
110 | }
|
111 |
|
112 | return data
|
113 | }
|
114 |
|
115 | Har.prototype.options = function (options) {
|
116 |
|
117 | if (!options.har) {
|
118 | return options
|
119 | }
|
120 |
|
121 | var har = {}
|
122 | extend(har, options.har)
|
123 |
|
124 |
|
125 | if (har.log && har.log.entries) {
|
126 | har = har.log.entries[0]
|
127 | }
|
128 |
|
129 |
|
130 | har.url = har.url || options.url || options.uri || options.baseUrl || '/'
|
131 | har.httpVersion = har.httpVersion || 'HTTP/1.1'
|
132 | har.queryString = har.queryString || []
|
133 | har.headers = har.headers || []
|
134 | har.cookies = har.cookies || []
|
135 | har.postData = har.postData || {}
|
136 | har.postData.mimeType = har.postData.mimeType || 'application/octet-stream'
|
137 |
|
138 | har.bodySize = 0
|
139 | har.headersSize = 0
|
140 | har.postData.size = 0
|
141 |
|
142 | if (!validate.request(har)) {
|
143 | return options
|
144 | }
|
145 |
|
146 |
|
147 | var req = this.prep(har)
|
148 |
|
149 |
|
150 | if (req.url) {
|
151 | options.url = req.url
|
152 | }
|
153 |
|
154 | if (req.method) {
|
155 | options.method = req.method
|
156 | }
|
157 |
|
158 | if (Object.keys(req.queryObj).length) {
|
159 | options.qs = req.queryObj
|
160 | }
|
161 |
|
162 | if (Object.keys(req.headersObj).length) {
|
163 | options.headers = req.headersObj
|
164 | }
|
165 |
|
166 | function test (type) {
|
167 | return req.postData.mimeType.indexOf(type) === 0
|
168 | }
|
169 | if (test('application/x-www-form-urlencoded')) {
|
170 | options.form = req.postData.paramsObj
|
171 | }
|
172 | else if (test('application/json')) {
|
173 | if (req.postData.jsonObj) {
|
174 | options.body = req.postData.jsonObj
|
175 | options.json = true
|
176 | }
|
177 | }
|
178 | else if (test('multipart/form-data')) {
|
179 | options.formData = {}
|
180 |
|
181 | req.postData.params.forEach(function (param) {
|
182 | var attachment = {}
|
183 |
|
184 | if (!param.fileName && !param.fileName && !param.contentType) {
|
185 | options.formData[param.name] = param.value
|
186 | return
|
187 | }
|
188 |
|
189 |
|
190 | if (param.fileName && !param.value) {
|
191 | attachment.value = fs.createReadStream(param.fileName)
|
192 | } else if (param.value) {
|
193 | attachment.value = param.value
|
194 | }
|
195 |
|
196 | if (param.fileName) {
|
197 | attachment.options = {
|
198 | filename: param.fileName,
|
199 | contentType: param.contentType ? param.contentType : null
|
200 | }
|
201 | }
|
202 |
|
203 | options.formData[param.name] = attachment
|
204 | })
|
205 | }
|
206 | else {
|
207 | if (req.postData.text) {
|
208 | options.body = req.postData.text
|
209 | }
|
210 | }
|
211 |
|
212 | return options
|
213 | }
|
214 |
|
215 | exports.Har = Har
|