diff --git a/src/Transaction/MultipartDocument.php b/src/Transaction/MultipartDocument.php index 9c03fe4f7..0088b1f88 100644 --- a/src/Transaction/MultipartDocument.php +++ b/src/Transaction/MultipartDocument.php @@ -118,9 +118,16 @@ public function parseDocuments(): self foreach ($documents as $document) { $multipart = new self(); - list($headers, $body) = array_map('trim', explode("\r\n\r\n", $document, 2)); - - foreach (explode("\r\n", $headers) as $header) { + list($headers, $body) = array_map( + 'trim', + explode( + "\n\n", + str_replace("\r\n", "\n", $document), + 2 + ) + ); + + foreach (explode("\n", $headers) as $header) { list($key, $value) = explode(':', $header, 2); $key = strtolower($key); $multipart->headers[$key] = $multipart->headers[$key] ?? []; @@ -140,7 +147,7 @@ public function parseDocuments(): self */ public function toRequest(): Request { - $httpRequest = explode("\r\n", $this->body); + $httpRequest = explode("\n", $this->body); $requestLine = array_shift($httpRequest); list($method, $requestURI, $httpVersion) = array_pad(explode(' ', $requestLine), 3, ''); @@ -181,7 +188,7 @@ public function toRequest(): Request $headers[$key] = trim($value); } - $body = implode("\r\n", $httpRequest); + $body = implode("\n", $httpRequest); $request = Request::create($uri, $method, [], [], [], [], $body); $request->headers->replace($headers); diff --git a/tests/Helpers/Request.php b/tests/Helpers/Request.php index b4ff0c395..0cecd02fe 100644 --- a/tests/Helpers/Request.php +++ b/tests/Helpers/Request.php @@ -167,10 +167,10 @@ public function post(): self return $this->method(\Illuminate\Http\Request::METHOD_POST); } - public function multipart(string $body): self + public function multipart(string $body, bool $convertNewlines = true): self { $this->header('accept', 'multipart/mixed'); - $this->body = str_replace("\n", "\r\n", $body); + $this->body = $convertNewlines ? str_replace("\n", "\r\n", $body) : $body; return $this; } diff --git a/tests/Protocol/BatchMultipartTest.php b/tests/Protocol/BatchMultipartTest.php index 0dd440aa2..49ba4956b 100644 --- a/tests/Protocol/BatchMultipartTest.php +++ b/tests/Protocol/BatchMultipartTest.php @@ -265,6 +265,27 @@ public function test_relative_path() ); } + public function test_non_crlf_newlines() + { + $this->assertTextMetadataResponse( + (new Request) + ->path('/$batch') + ->header('content-type', 'multipart/mixed; boundary=batch_36522ad7-fc75-4b56-8c71-56071383e77b') + ->post() + ->multipart(<<assertTextMetadataResponse( diff --git a/tests/__snapshots__/Protocol/BatchMultipartTest__test_non_crlf_newlines__1.txt b/tests/__snapshots__/Protocol/BatchMultipartTest__test_non_crlf_newlines__1.txt new file mode 100644 index 000000000..0da6a97b5 --- /dev/null +++ b/tests/__snapshots__/Protocol/BatchMultipartTest__test_non_crlf_newlines__1.txt @@ -0,0 +1,10 @@ + +--00000000-0000-0000-0000-000000000002 +content-type: application/http + +HTTP/1.0 200 OK +content-type: application/json;metadata=minimal +etag: W/"a714e2db58e276ecdcfcd98c25a0085a1465f571f780135a3ef2e976ec3a0afe" + +{"@context":"http://localhost/odata/$metadata#flights/$entity","id":1,"origin":"lhr","destination":"lax","gate":null,"duration":"PT11H25M0S"} +--00000000-0000-0000-0000-000000000002-- diff --git a/tests/__snapshots__/Protocol/BatchMultipartTest__test_non_crlf_newlines__2.json b/tests/__snapshots__/Protocol/BatchMultipartTest__test_non_crlf_newlines__2.json new file mode 100644 index 000000000..020300581 --- /dev/null +++ b/tests/__snapshots__/Protocol/BatchMultipartTest__test_non_crlf_newlines__2.json @@ -0,0 +1,14 @@ +{ + "headers": { + "cache-control": [ + "no-cache, private" + ], + "content-type": [ + "multipart/mixed;boundary=00000000-0000-0000-0000-000000000002" + ], + "odata-version": [ + "4.01" + ] + }, + "status": 200 +}