apollo-link-http
Advanced tools
Comparing version 1.6.0-alpha.2 to 1.6.0-alpha.3
@@ -27,2 +27,5 @@ (function (global, factory) { | ||
var MESSAGE_NO_READABLE_STREAM = "Your browser does not support the ReadableStream API, which is needed to read streaming multipart HTTP responses for deferred queries.\nApollo Client will only parse the response when all the parts arrive."; | ||
function throwParseError() { | ||
throw new Error('Invalid multipart response from GraphQL server'); | ||
} | ||
/** | ||
@@ -33,2 +36,6 @@ * Given the plaintext of a HTTP response body that follows the Multipart | ||
* deferred query. | ||
* | ||
* Returns null if a part is incomplete, i.e. the length of the body does not | ||
* match the Content-Length header. This occurs on large payloads that get | ||
* transferred in multiple chunks. | ||
* @param plaintext | ||
@@ -39,3 +46,2 @@ */ | ||
// Split plaintext using encapsulation boundary | ||
// See: | ||
var boundary = '\r\n---\r\n'; | ||
@@ -46,10 +52,27 @@ var terminatingBoundary = '\r\n-----\r\n'; | ||
var part = parts_1[_i]; | ||
// Get the body of the part, we don't need the headers for | ||
// each part, but it is sent anyway as per the spec. | ||
// Split part into header and body | ||
if (part.length) { | ||
var partArr = part.split('\r\n\r\n'); | ||
if (!partArr || partArr.length !== 2) { | ||
throw new Error('Invalid multipart response from GraphQL server'); | ||
if (!partArr || partArr.length !== 2) ; | ||
// Read the Content-Length header, which must be included in the response | ||
var headers = partArr[0]; | ||
var headersArr = headers.split('\r\n'); | ||
var contentLengthHeader = headersArr.find(function (headerLine) { return headerLine.toLowerCase().indexOf('content-length:') >= 0; }); | ||
if (contentLengthHeader === undefined) { | ||
throwParseError(); | ||
} | ||
var contentLengthArr = contentLengthHeader.split(':'); | ||
var contentLength = void 0; | ||
if (contentLengthArr.length === 2 && | ||
!isNaN(parseInt(contentLengthArr[1]))) { | ||
contentLength = parseInt(contentLengthArr[1]); | ||
} | ||
else { | ||
throwParseError(); | ||
} | ||
var body = partArr[1]; | ||
// Check that length of body matches the Content-Length | ||
if (Buffer.byteLength(body, 'UTF-8') !== contentLength) { | ||
return null; | ||
} | ||
if (body && body.length) { | ||
@@ -61,3 +84,3 @@ // Strip out the terminating boundary | ||
else { | ||
throw new Error('Invalid multipart response from GraphQL server'); | ||
throwParseError(); | ||
} | ||
@@ -144,2 +167,3 @@ } | ||
var textDecoder_1 = new TextDecoder(); | ||
var chunkBuffer_1 = ''; | ||
reader_1.read().then(function sendNext(_a) { | ||
@@ -151,7 +175,16 @@ var value = _a.value, done = _a.done; | ||
plaintext = textDecoder_1.decode(value); | ||
var parts = parseMultipartHTTP(plaintext); | ||
for (var _i = 0, parts_2 = parts; _i < parts_2.length; _i++) { | ||
var part = parts_2[_i]; | ||
observer.next(part); | ||
// Read the header to get the Content-Length | ||
var parts = parseMultipartHTTP(chunkBuffer_1 + plaintext); | ||
if (parts === null) { | ||
// The part is not complete yet, add it to the buffer | ||
// and wait for the next chunk to arrive | ||
chunkBuffer_1 += plaintext; | ||
} | ||
else { | ||
chunkBuffer_1 = ''; // Reset | ||
for (var _i = 0, parts_2 = parts; _i < parts_2.length; _i++) { | ||
var part = parts_2[_i]; | ||
observer.next(part); | ||
} | ||
} | ||
} | ||
@@ -158,0 +191,0 @@ catch (err) { |
@@ -23,2 +23,5 @@ var __extends = (this && this.__extends) || (function () { | ||
var MESSAGE_NO_READABLE_STREAM = "Your browser does not support the ReadableStream API, which is needed to read streaming multipart HTTP responses for deferred queries.\nApollo Client will only parse the response when all the parts arrive."; | ||
function throwParseError() { | ||
throw new Error('Invalid multipart response from GraphQL server'); | ||
} | ||
/** | ||
@@ -29,2 +32,6 @@ * Given the plaintext of a HTTP response body that follows the Multipart | ||
* deferred query. | ||
* | ||
* Returns null if a part is incomplete, i.e. the length of the body does not | ||
* match the Content-Length header. This occurs on large payloads that get | ||
* transferred in multiple chunks. | ||
* @param plaintext | ||
@@ -35,3 +42,2 @@ */ | ||
// Split plaintext using encapsulation boundary | ||
// See: | ||
var boundary = '\r\n---\r\n'; | ||
@@ -42,10 +48,28 @@ var terminatingBoundary = '\r\n-----\r\n'; | ||
var part = parts_1[_i]; | ||
// Get the body of the part, we don't need the headers for | ||
// each part, but it is sent anyway as per the spec. | ||
// Split part into header and body | ||
if (part.length) { | ||
var partArr = part.split('\r\n\r\n'); | ||
if (!partArr || partArr.length !== 2) { | ||
throw new Error('Invalid multipart response from GraphQL server'); | ||
} | ||
// Read the Content-Length header, which must be included in the response | ||
var headers = partArr[0]; | ||
var headersArr = headers.split('\r\n'); | ||
var contentLengthHeader = headersArr.find(function (headerLine) { return headerLine.toLowerCase().indexOf('content-length:') >= 0; }); | ||
if (contentLengthHeader === undefined) { | ||
throwParseError(); | ||
} | ||
var contentLengthArr = contentLengthHeader.split(':'); | ||
var contentLength = void 0; | ||
if (contentLengthArr.length === 2 && | ||
!isNaN(parseInt(contentLengthArr[1]))) { | ||
contentLength = parseInt(contentLengthArr[1]); | ||
} | ||
else { | ||
throwParseError(); | ||
} | ||
var body = partArr[1]; | ||
// Check that length of body matches the Content-Length | ||
if (Buffer.byteLength(body, 'UTF-8') !== contentLength) { | ||
return null; | ||
} | ||
if (body && body.length) { | ||
@@ -57,3 +81,3 @@ // Strip out the terminating boundary | ||
else { | ||
throw new Error('Invalid multipart response from GraphQL server'); | ||
throwParseError(); | ||
} | ||
@@ -140,2 +164,3 @@ } | ||
var textDecoder_1 = new TextDecoder(); | ||
var chunkBuffer_1 = ''; | ||
reader_1.read().then(function sendNext(_a) { | ||
@@ -147,7 +172,16 @@ var value = _a.value, done = _a.done; | ||
plaintext = textDecoder_1.decode(value); | ||
var parts = parseMultipartHTTP(plaintext); | ||
for (var _i = 0, parts_2 = parts; _i < parts_2.length; _i++) { | ||
var part = parts_2[_i]; | ||
observer.next(part); | ||
// Read the header to get the Content-Length | ||
var parts = parseMultipartHTTP(chunkBuffer_1 + plaintext); | ||
if (parts === null) { | ||
// The part is not complete yet, add it to the buffer | ||
// and wait for the next chunk to arrive | ||
chunkBuffer_1 += plaintext; | ||
} | ||
else { | ||
chunkBuffer_1 = ''; // Reset | ||
for (var _i = 0, parts_2 = parts; _i < parts_2.length; _i++) { | ||
var part = parts_2[_i]; | ||
observer.next(part); | ||
} | ||
} | ||
} | ||
@@ -154,0 +188,0 @@ catch (err) { |
{ | ||
"name": "apollo-link-http", | ||
"version": "1.6.0-alpha.2", | ||
"version": "1.6.0-alpha.3", | ||
"description": "HTTP transport layer for GraphQL", | ||
@@ -5,0 +5,0 @@ "author": "Evans Hauser <evanshauser@gmail.com>", |
@@ -38,2 +38,6 @@ import { | ||
function throwParseError() { | ||
throw new Error('Invalid multipart response from GraphQL server'); | ||
} | ||
/** | ||
@@ -44,9 +48,12 @@ * Given the plaintext of a HTTP response body that follows the Multipart | ||
* deferred query. | ||
* | ||
* Returns null if a part is incomplete, i.e. the length of the body does not | ||
* match the Content-Length header. This occurs on large payloads that get | ||
* transferred in multiple chunks. | ||
* @param plaintext | ||
*/ | ||
function parseMultipartHTTP(plaintext: string): FetchResult[] { | ||
function parseMultipartHTTP(plaintext: string): FetchResult[] | null { | ||
const results: FetchResult[] = []; | ||
// Split plaintext using encapsulation boundary | ||
// See: | ||
const boundary = '\r\n---\r\n'; | ||
@@ -57,10 +64,34 @@ const terminatingBoundary = '\r\n-----\r\n'; | ||
for (const part of parts) { | ||
// Get the body of the part, we don't need the headers for | ||
// each part, but it is sent anyway as per the spec. | ||
// Split part into header and body | ||
if (part.length) { | ||
let partArr = part.split('\r\n\r\n'); | ||
if (!partArr || partArr.length !== 2) { | ||
throw new Error('Invalid multipart response from GraphQL server'); | ||
} | ||
// Read the Content-Length header, which must be included in the response | ||
let headers = partArr[0]; | ||
const headersArr = headers.split('\r\n'); | ||
const contentLengthHeader = headersArr.find( | ||
headerLine => headerLine.toLowerCase().indexOf('content-length:') >= 0, | ||
); | ||
if (contentLengthHeader === undefined) { | ||
throwParseError(); | ||
} | ||
const contentLengthArr = contentLengthHeader.split(':'); | ||
let contentLength: number; | ||
if ( | ||
contentLengthArr.length === 2 && | ||
!isNaN(parseInt(contentLengthArr[1])) | ||
) { | ||
contentLength = parseInt(contentLengthArr[1]); | ||
} else { | ||
throwParseError(); | ||
} | ||
let body = partArr[1]; | ||
// Check that length of body matches the Content-Length | ||
if (Buffer.byteLength(body, 'UTF-8') !== contentLength) { | ||
return null; | ||
} | ||
if (body && body.length) { | ||
@@ -71,3 +102,3 @@ // Strip out the terminating boundary | ||
} else { | ||
throw new Error('Invalid multipart response from GraphQL server'); | ||
throwParseError(); | ||
} | ||
@@ -181,2 +212,3 @@ } | ||
const textDecoder = new TextDecoder(); | ||
let chunkBuffer: string = ''; | ||
reader.read().then(function sendNext({ value, done }) { | ||
@@ -187,5 +219,14 @@ if (!done) { | ||
plaintext = textDecoder.decode(value); | ||
const parts = parseMultipartHTTP(plaintext); | ||
for (const part of parts) { | ||
observer.next(part); | ||
// Read the header to get the Content-Length | ||
const parts = parseMultipartHTTP(chunkBuffer + plaintext); | ||
if (parts === null) { | ||
// The part is not complete yet, add it to the buffer | ||
// and wait for the next chunk to arrive | ||
chunkBuffer += plaintext; | ||
} else { | ||
chunkBuffer = ''; // Reset | ||
for (const part of parts) { | ||
observer.next(part); | ||
} | ||
} | ||
@@ -192,0 +233,0 @@ } catch (err) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
123815
1999