UNPKG

2.66 kBJavaScriptView Raw
1//
2
3
4
5const contentType = require('content-type');
6const ResponseMergerBase = require('./ResponseMergerBase');
7
8const md5 = require('md5');
9
10/**
11 * @classdesc
12 * Takes in a collection of sub-responses and assembles a single response.
13 *
14 * @class MultipartRelatedResponse
15 */
16class MultipartRelatedResponse extends ResponseMergerBase {
17 /**
18 * Merges many responses into a single one.
19 *
20 * @param {Response[]} responses
21 * An object containing information about the response body and headers.
22 *
23 * @return {Response}
24 * A single response containing all the responses.
25 */
26 static mergeResponses(responses ) {
27 const delimiter = this._generateDelimiter();
28 const crlf = this.getCrlf();
29 const headers = new Map();
30 // The status is always set to multi-status.
31 headers.set('Status', '207');
32 // The content type contains the delimiter.
33 const ct = contentType.format({
34 type: 'multipart/related',
35 parameters: {
36 boundary: delimiter,
37 type: this._negotiateSubContentType(responses),
38 },
39 });
40 // The content type: 'multipart/related; boundary=1234; type=text/plain'
41 headers.set('Content-Type', ct);
42 const output = {
43 headers,
44 body: '',
45 };
46
47 const parts = responses
48 .map(this._cleanResponse.bind(this))
49 .map(this.serializeResponse.bind(this));
50
51 // Put the correct delimiters in place for the `multipart/related`
52 output.body += `${delimiter}--${crlf}`;
53 output.body += parts.join(`${crlf}--${delimiter}${crlf}`);
54 output.body += `${crlf}--${delimiter}--`;
55 return output;
56 }
57
58 /**
59 * Builds a subresponse object based on the response to the subrequest.
60 *
61 * @param {Response} response
62 * The individual subresponse.
63 *
64 * @return {string}
65 * The serialized subresponse.
66 *
67 * @private
68 */
69 static serializeResponse(response ) {
70 let output = '';
71 // Encode the response headers in the output.
72 const crlf = this.getCrlf();
73 response.headers.forEach((value, name) => {
74 output += `${name}: ${value}${crlf}`;
75 });
76
77 return `${output}${crlf}${response.body}`;
78 }
79
80 /**
81 * Generate a random subresponse delimiter.
82 *
83 * @return {string}
84 * The hex delimiter.
85 *
86 * @private
87 */
88 static _generateDelimiter() {
89 return md5(Date.now()).substr(0, 6);
90 }
91}
92(MultipartRelatedResponse ); // eslint-disable-line no-unused-expressions
93
94module.exports = MultipartRelatedResponse;