Skip to content

Commit 136abf0

Browse files
committed
Inline 'Creating Targets' wiki page into CONTRIBUTING
This should let us remove wiki references and generally allow us to start versioning all the documentation alongside the source code.
1 parent 69008ff commit 136abf0

File tree

1 file changed

+289
-2
lines changed

1 file changed

+289
-2
lines changed

CONTRIBUTING.md

Lines changed: 289 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ patches and features.
1111
## Using the issue tracker
1212

1313
The [issue tracker](/issues) is the preferred channel for [bug reports](#bug-reports),
14-
[features requests](#feature-requests) and [submitting pull requests](#pull-requests),
14+
[features requests](#feature-requests) and [submitting pull requests](#pull-requests),
1515
but please respect the following restrictions:
1616

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

0 commit comments

Comments
 (0)