UNPKG

@sap/xsodata

Version:

Expose data from a HANA database as OData V2 service with help of .xsodata files.

150 lines (122 loc) 4.51 kB
'use strict'; var utils = require('./../utils'); var batchObjects = require('./batchObjects'); exports.getBoundary = function (headerValue) { var l = headerValue.split(';'); for (var i = 0; i < l.length; i++) { var ll = l[i].split('='); if (ll[0].trim() === 'boundary') { return ll[1]; } } }; function readAppHttp(batchContent, boundary) { var headers = {}; var payload = []; var state = 0; //read url var url = batchContent.readLine(); state = 1; //read header var line = batchContent.lookLine(); while ((line !== null && line !== undefined) && line.indexOf(boundary) !== 0) { if (state === 1) { if (line.length === 0) { state = 2; //read body batchContent.inc(); } else { var h = readHeader(line); headers[h.name] = h.value; batchContent.inc(); } } else if (state === 2) { payload.push(line); batchContent.inc(); } line = batchContent.lookLine(); } if (line === undefined) { throw new Error("Invalid boundary while parsing batch request. Expect boundary " + boundary); } return new batchObjects.AppHttp(url, headers, payload); } function parsePart(batchContent, boundary) { var boundaryNext = boundary; var boundaryEnd = boundary + '--'; var headers = {}; var content; var state = 1; //read header var line = batchContent.lookLine(); while ((line !== null && line !== undefined) && line !== boundaryNext && line !== boundaryEnd) { if (state === 1) { if (line.length === 0) { state = 2; //read body batchContent.inc(); } else { var h = readHeader(line); headers[h.name] = h.value; batchContent.inc(); } } else if (state === 2) { if (!headers['content-type']) { throw new Error('Missing header "content-type" in batch part'); } else if (headers['content-type'] === 'application/http') { content = readAppHttp(batchContent, boundary); } else if (utils.startsWith(headers['content-type'], 'multipart/mixed;')) { var changeSetBoundary = exports.getBoundary(headers['content-type']); content = parseBatch(batchContent, changeSetBoundary, "changeset"); } else { //TODO not supported } } line = batchContent.lookLine(); } if (line === undefined) { throw new Error("Invalid boundary while parsing batch request. Expect boundary " + boundary); } return content; //return new batchObjects.BatchPart(headers, content); } function readHeader(line) { var colPos = line.indexOf(':'); if (colPos === -1) { throw new Error('Invalid header "content-type" in batch part'); } var s0 = line.substr(0, colPos); var s1 = line.substr(colPos + 1); return { name: s0.toLowerCase(), value: s1.trim() }; } function parseBatch(content, boundary, type) { var boundaryNext = '--' + boundary; var boundaryEnd = '--' + boundary + '--'; var batch = new batchObjects.Batch(type); var part; var line = content.readLine(); while ((line !== null && line !== undefined) && line !== boundaryNext) { //read lines before first boundary line = content.readLine(); } if (line === undefined) { throw new Error("Invalid boundary while parsing batch request"); } //line is now read boundary line = content.lookLine(); //read line behind while ((line !== null && line !== undefined) && line !== boundaryEnd) { part = parsePart(content, boundaryNext); batch.parts.push(part); line = content.lookLine(); //now on boundary if (line === boundaryNext) { line = content.readLine();//consume boundaryNext } } content.readLine();//consume boundaryEnd line = content.lookLine(); //read line behind while ((line !== null && line !== undefined) && line.length === 0) { //read empty lines after first boundaryend content.readLine(); line = content.lookLine(); } return batch; } exports.convertBatch = function (payload, boundary) { return parseBatch(new batchObjects.BatchContent(payload), boundary, "batch"); };