1 | 'use strict'
|
2 |
|
3 | var fs = require('fs')
|
4 | var qs = require('querystring')
|
5 | var validate = require('har-validator')
|
6 | var util = require('util')
|
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 | switch (data.postData.mimeType) {
|
64 | case 'multipart/mixed':
|
65 | case 'multipart/related':
|
66 | case 'multipart/form-data':
|
67 | case 'multipart/alternative':
|
68 |
|
69 | data.postData.mimeType = 'multipart/form-data'
|
70 | break
|
71 |
|
72 | case 'application/x-www-form-urlencoded':
|
73 | if (!data.postData.params) {
|
74 | data.postData.text = ''
|
75 | } else {
|
76 | data.postData.paramsObj = data.postData.params.reduce(this.reducer, {})
|
77 |
|
78 |
|
79 | data.postData.text = qs.stringify(data.postData.paramsObj)
|
80 | }
|
81 | break
|
82 |
|
83 | case 'text/json':
|
84 | case 'text/x-json':
|
85 | case 'application/json':
|
86 | case 'application/x-json':
|
87 | data.postData.mimeType = 'application/json'
|
88 |
|
89 | if (data.postData.text) {
|
90 | try {
|
91 | data.postData.jsonObj = JSON.parse(data.postData.text)
|
92 | } catch (e) {
|
93 | this.request.debug(e)
|
94 |
|
95 |
|
96 | data.postData.mimeType = 'text/plain'
|
97 | }
|
98 | }
|
99 | break
|
100 | }
|
101 |
|
102 | return data
|
103 | }
|
104 |
|
105 | Har.prototype.options = function (options) {
|
106 |
|
107 | if (!options.har) {
|
108 | return options
|
109 | }
|
110 |
|
111 | var har = util._extend({}, options.har)
|
112 |
|
113 |
|
114 | if (har.log && har.log.entries) {
|
115 | har = har.log.entries[0]
|
116 | }
|
117 |
|
118 |
|
119 | har.url = har.url || options.url || options.uri || options.baseUrl || '/'
|
120 | har.httpVersion = har.httpVersion || 'HTTP/1.1'
|
121 | har.queryString = har.queryString || []
|
122 | har.headers = har.headers || []
|
123 | har.cookies = har.cookies || []
|
124 | har.postData = har.postData || {}
|
125 | har.postData.mimeType = har.postData.mimeType || 'application/octet-stream'
|
126 |
|
127 | har.bodySize = 0
|
128 | har.headersSize = 0
|
129 | har.postData.size = 0
|
130 |
|
131 | if (!validate.request(har)) {
|
132 | return options
|
133 | }
|
134 |
|
135 |
|
136 | var req = this.prep(har)
|
137 |
|
138 |
|
139 | if (req.url) {
|
140 | options.url = req.url
|
141 | }
|
142 |
|
143 | if (req.method) {
|
144 | options.method = req.method
|
145 | }
|
146 |
|
147 | if (Object.keys(req.queryObj).length) {
|
148 | options.qs = req.queryObj
|
149 | }
|
150 |
|
151 | if (Object.keys(req.headersObj).length) {
|
152 | options.headers = req.headersObj
|
153 | }
|
154 |
|
155 | switch (req.postData.mimeType) {
|
156 | case 'application/x-www-form-urlencoded':
|
157 | options.form = req.postData.paramsObj
|
158 | break
|
159 |
|
160 | case 'application/json':
|
161 | if (req.postData.jsonObj) {
|
162 | options.body = req.postData.jsonObj
|
163 | options.json = true
|
164 | }
|
165 | break
|
166 |
|
167 | case 'multipart/form-data':
|
168 | options.formData = {}
|
169 |
|
170 | req.postData.params.forEach(function (param) {
|
171 | var attachment = {}
|
172 |
|
173 | if (!param.fileName && !param.fileName && !param.contentType) {
|
174 | options.formData[param.name] = param.value
|
175 | return
|
176 | }
|
177 |
|
178 |
|
179 | if (param.fileName && !param.value) {
|
180 | attachment.value = fs.createReadStream(param.fileName)
|
181 | } else if (param.value) {
|
182 | attachment.value = param.value
|
183 | }
|
184 |
|
185 | if (param.fileName) {
|
186 | attachment.options = {
|
187 | filename: param.fileName,
|
188 | contentType: param.contentType ? param.contentType : null
|
189 | }
|
190 | }
|
191 |
|
192 | options.formData[param.name] = attachment
|
193 | })
|
194 | break
|
195 |
|
196 | default:
|
197 | if (req.postData.text) {
|
198 | options.body = req.postData.text
|
199 | }
|
200 | }
|
201 |
|
202 | return options
|
203 | }
|
204 |
|
205 | exports.Har = Har
|