|
1 | | -# Contributing to this project |
| 1 | +c# Contributing to this project |
2 | 2 |
|
3 | 3 | Please take a moment to review this document in order to make the contribution |
4 | 4 | process easy and effective for everyone involved. |
@@ -136,275 +136,4 @@ license your work under the same license as that used by the project. |
136 | 136 |
|
137 | 137 | ## Creating New Conversion Targets |
138 | 138 |
|
139 | | -Please start by browsing for [available targets](/src/targets) and inspect each implementation. |
140 | | - |
141 | | -a target is a simple module with a constructor that accepts two parameters: `source` and `options`, |
142 | | -where `source` is the HAR Object to process, and `options` is an optional object with any target |
143 | | -specific flags *(used for customizing the output)*. |
144 | | - |
145 | | -### Conversion Rules |
146 | | - |
147 | | -1. start by reading an understanding the [HAR](http://www.softwareishard.com/blog/har-12-spec/#request) format. |
148 | | -2. utilize utility properties created for convenience (`source.headersObj`, `source.uriObj` etc ...) *see below for mode details* |
149 | | -3. follow the guidelines below for best practices and consistency. |
150 | | - |
151 | | -### Guidelines |
152 | | - |
153 | | -Using the following example of a request object, HTTP Snippet will pre-process data and create some additional properties: |
154 | | - |
155 | | -| property | description | |
156 | | -| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | |
157 | | -| `source.fullUrl` | the full & final url, including all query string values | |
158 | | -| `source.uriObj` | the url parsed with `url.parse()`. compatible with `url.format` | |
159 | | -| `source.queryObj` | a key => value pair, "normalized" version of `source.queryString`, adds additional query string values from the `source.url` | |
160 | | -| `source.headersObj` | a key => value pair, "normalized" version of `source.headers`, header names are lowercased | |
161 | | -| `source.allHeaders` | same as `source.headersObj` but with `cookies` header and populated from `source.cookies` array | |
162 | | -| `source.postData.jsonObj` | the parsed value of `source.postData.text`, only for `source.postData.mimeType` = `application/json` *(or equivalent mimeTypes)* | |
163 | | -| `source.postData.paramsObj` | a key => value pair, "normalized" version of `source.postData.params`, only for `source.postData.mimeType` = `application/x-www-form-urlencoded` | |
164 | | - |
165 | | -###### Sample Incoming Request Object |
166 | | - |
167 | | -```js |
168 | | -{ |
169 | | - method: 'POST', |
170 | | - url: 'http://mockbin.com/har?key=value', |
171 | | - httpVersion: 'HTTP/1.1', |
172 | | - queryString: [ |
173 | | - { name: 'foo', value: 'bar' }, |
174 | | - { name: 'foo', value: 'baz' }, |
175 | | - { name: 'baz', value: 'abc' } |
176 | | - ], |
177 | | - headers: [ |
178 | | - { name: 'Accept', value: 'application/json' }, |
179 | | - { name: 'Content-Type', value: 'application/x-www-form-urlencoded' } |
180 | | - ], |
181 | | - |
182 | | - cookies: [ |
183 | | - { name: 'foo', value: 'bar' }, |
184 | | - { name: 'bar', value: 'baz' } |
185 | | - ], |
186 | | - |
187 | | - postData: { |
188 | | - mimeType: 'application/x-www-form-urlencoded', |
189 | | - params: [ |
190 | | - { name: 'foo', value: 'bar' }, |
191 | | - { name: 'foo', value: 'baz' }, |
192 | | - { name: 'baz', value: 'abc' } |
193 | | - ] |
194 | | - } |
195 | | -} |
196 | | -``` |
197 | | - |
198 | | -###### Processed Source Object |
199 | | - |
200 | | -```js |
201 | | -{ |
202 | | - method: 'POST', |
203 | | - |
204 | | - // the base url value stripped of any the query string |
205 | | - url: 'http://mockbin.com/har', |
206 | | - |
207 | | - // the full & final url, including all query string values |
208 | | - fullUrl: 'http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value', |
209 | | - |
210 | | - // the url parsed with url.parse() |
211 | | - // compatible with url.format |
212 | | - uriObj: { |
213 | | - protocol: 'http:', |
214 | | - slashes: true, |
215 | | - auth: null, |
216 | | - host: 'mockbin.com', |
217 | | - port: null, |
218 | | - hostname: 'mockbin.com', |
219 | | - hash: null, |
220 | | - search: 'key=value&baz=abc&foo=bar&foo=baz', |
221 | | - query: { key: 'value', baz: 'abc', foo: [Object] }, |
222 | | - pathname: '/har', |
223 | | - path: '/har?key=value&baz=abc&foo=bar&foo=baz', |
224 | | - href: 'http://mockbin.com/har' |
225 | | - }, |
226 | | - |
227 | | - httpVersion: 'HTTP/1.1', |
228 | | - |
229 | | - // added to pass har-validator |
230 | | - bodySize: 0, |
231 | | - |
232 | | - // added to pass har-validator |
233 | | - headersSize: 0, |
234 | | - |
235 | | - queryString: [ |
236 | | - { name: 'foo', value: 'bar' }, |
237 | | - { name: 'foo', value: 'baz' }, |
238 | | - { name: 'baz', value: 'abc' } |
239 | | - ], |
240 | | - |
241 | | - // "normalized" version of `queryString` |
242 | | - // adds any additional query string values from the url |
243 | | - // compatible with "querystring" node module |
244 | | - queryObj: { |
245 | | - key: 'value', |
246 | | - baz: 'abc', |
247 | | - foo: [ 'bar', 'baz' ] |
248 | | - }, |
249 | | - |
250 | | - headers: [ |
251 | | - { name: 'Accept', value: 'application/json' }, |
252 | | - { name: 'Content-Type', value: 'application/x-www-form-urlencoded' } |
253 | | - ], |
254 | | - |
255 | | - // normalized headers array into a key => value object pair |
256 | | - // header names are lowercased |
257 | | - headersObj: { |
258 | | - 'accept': 'application/json', |
259 | | - 'content-type': 'application/x-www-form-urlencoded' |
260 | | - }, |
261 | | - |
262 | | - // same as headersObj but with Cookies added (if any exist in cookies array) |
263 | | - allHeaders: { |
264 | | - 'accept': 'application/json', |
265 | | - 'content-type': 'application/x-www-form-urlencoded', |
266 | | - 'cookie': 'foo=bar; bar=baz' |
267 | | - }, |
268 | | - |
269 | | - cookies: [ |
270 | | - { name: 'foo', value: 'bar' }, |
271 | | - { name: 'bar', value: 'baz' } |
272 | | - ], |
273 | | - |
274 | | - // see below for different scenarios |
275 | | - postData: [Object] |
276 | | -} |
277 | | -``` |
278 | | - |
279 | | -###### application/x-www-form-urlencoded |
280 | | - |
281 | | -```js |
282 | | -postData: { |
283 | | - // added to pass har-validator |
284 | | - size: 0, |
285 | | - |
286 | | - // original value |
287 | | - mimeType: 'application/x-www-form-urlencoded', |
288 | | - |
289 | | - // original value |
290 | | - params: [ |
291 | | - { name: 'foo', value: 'bar' }, |
292 | | - { name: 'foo', value: 'baz' }, |
293 | | - { name: 'baz', value: 'abc' } |
294 | | - ], |
295 | | - |
296 | | - // "normalized" version of `params` |
297 | | - // compatible with "querystring" node module |
298 | | - paramsObj: { |
299 | | - key: 'value', |
300 | | - baz: 'abc', |
301 | | - foo: [ 'bar', 'baz' ] |
302 | | - } |
303 | | - |
304 | | - // the raw body in plain text |
305 | | - // this value will be always overwritten in this scenario |
306 | | - text: 'baz=abc&foo=bar&foo=baz' |
307 | | - |
308 | | - // see below |
309 | | - jsonObj: false |
310 | | -} |
311 | | -``` |
312 | | - |
313 | | -###### application/json |
314 | | - |
315 | | -- will match when `postData.mimeType` is one of: `application/json`, `text/json`, `text/x-json`, `application/x-json` |
316 | | -- In case of failure to parse `postData.text` as a JSON object, `postData.mimeType` is set to `text/plain`, `postData.jsonObj` remains as `false`. this is done so that the implementing target, would still attempt to post the raw body as is. |
317 | | -- This also emphasizes not to rely on `postData.mimeType` for the `Content-Type` header! |
318 | | - |
319 | | -```js |
320 | | -postData: { |
321 | | - // added to pass har-validator |
322 | | - size: 0, |
323 | | - |
324 | | - // original value |
325 | | - mimeType: 'application/json', |
326 | | - |
327 | | - // ignored |
328 | | - params: [], |
329 | | - |
330 | | - // default value |
331 | | - paramsObj: false |
332 | | - |
333 | | - // the raw body in plain text |
334 | | - text: '"{\"foo\": \"bar\"}"' |
335 | | - |
336 | | - // the parsed value of postData.text |
337 | | - jsonObj: { |
338 | | - foo: 'bar' |
339 | | - } |
340 | | -} |
341 | | -``` |
342 | | - |
343 | | -###### multipart/form-data |
344 | | - |
345 | | -- will match when `postData.mimeType` is one of: `multipart/mixed` `multipart/related`, `multipart/form-data`, `multipart/alternative` |
346 | | -- will force `postData.mimeType` to `multipart/form-data` |
347 | | -- will create/overwrite the `Content-Type` header if it does not exist, with the appropriate boundary flag. |
348 | | -- when no `params[].value` is present, will default to empty content |
349 | | - |
350 | | -```js |
351 | | -postData: { |
352 | | - // added to pass har-validator |
353 | | - size: 0, |
354 | | - |
355 | | - // original value |
356 | | - mimeType: 'multipart/form-data', |
357 | | - |
358 | | - // parsed into text values |
359 | | - params: [ |
360 | | - { |
361 | | - name: 'foo', |
362 | | - value: 'bar' |
363 | | - } |
364 | | - ] |
365 | | - |
366 | | - // ignored |
367 | | - paramsObj: false |
368 | | - |
369 | | - // the raw body in plain text |
370 | | - // generated based on appropriately parsing the `params` into a multi-boundary content string |
371 | | - // this value will be always overwritten in this scenario |
372 | | - text: '----------------------------591447866569479977899212\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n----------------------------591447866569479977899212--' |
373 | | - |
374 | | - // ignored |
375 | | - jsonObj: false |
376 | | -} |
377 | | -``` |
378 | | - |
379 | | -###### multipart/form-data (File Uploads) |
380 | | - |
381 | | -```js |
382 | | -postData: { |
383 | | - // added to pass har-validator |
384 | | - size: 0, |
385 | | - |
386 | | - // original value |
387 | | - mimeType: 'multipart/form-data', |
388 | | - |
389 | | - // parsed into text values |
390 | | - params: [ |
391 | | - { |
392 | | - name: 'foo', |
393 | | - value: 'Hello World', |
394 | | - fileName: 'test/fixtures/files/hello.txt', |
395 | | - contentType: 'text/plain' |
396 | | - } |
397 | | - ] |
398 | | - |
399 | | - // ignored |
400 | | - paramsObj: false |
401 | | - |
402 | | - // the raw body in plain text |
403 | | - // generated based on appropriately parsing the `params` into a multi-boundary content string |
404 | | - // this value will be always overwritten in this scenario |
405 | | - text: '----------------------------771333709043252625002993\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"hello.txt\"\r\nContent-Type: text/plain\r\n\r\nHello World\r\n----------------------------771333709043252625002993--' |
406 | | - |
407 | | - // ignored |
408 | | - jsonObj: false |
409 | | -} |
410 | | -``` |
| 139 | +For a info on creating new conversion targets, please review this [guideline](https://github.com/Mashape/httpsnippet/wiki/Creating-Targets) |
0 commit comments