Search code examples
phplaravelhttpresponseattachment

Access file attachment from HTTP response with no body


This is essentially the same question as this one from last year, but for PHP (Laravel, specifically), and that question doesn’t have any answers.

I have an external URL which should return an Excel file. Visiting the URL in a browser correctly downloads the file with the correct content (about 270 KB in size), but trying to get the contents of the file through an HTTP request, I’m not having much luck.

The request is in a Laravel app, so I would prefer to use Laravel’s HTTP client if possible, but I’ll take a cURL or even file_get_contents answer if that’s what it takes.

When I send the request through Insomnia or Postman and inspect the timeline, this is what I get:

> GET /path/to/file.do?file=xyz.xls HTTP/1.1
> Host: remote.host.example.com
> User-Agent: insomnia/2023.4.0
> Authorization: Basic [redacted]
> Accept: */*

* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Mark bundle as not supporting multiuse

< HTTP/1.1 200 OK
< Date: Fri, 08 Sep 2023 10:56:07 GMT
< Server: Apache

* TLSv1.2 (IN), TLS header, Supplemental data (23):

< Content-Disposition: attachment; filename =xyz.xls                                                                                                                                                                                                
< Set-Cookie: RPGSPSESSIONID=[redacted];
< Transfer-Encoding: chunked
< Content-Type: application/xls

* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Received 5 B chunk

It has content-disposition: attachment; filename=xyz.xls, but there is no Content-Length header at all, and the response body is empty.

Since the body is empty, obviously, this just returns an empty string:

Http::withBasicAuth('un', 'pw')
  ->get('https://remote.host.example.com/path/to/file.do?file=xyz.xls')
  ->body();

Inspecting the HTTPResponse object returned by the call itself (without ->body()) doesn’t reveal anything that looks like it would give me access to the attachment data.

But given that a browser is able to download the file just fine, there must be something in the response that makes it possible to access the actual data of the file, even if it’s not in the response body. So my questions are:

  1. What is this ‘something’? How does a browser access the data from the response?
  2. Can I access it from within PHP somehow?

Solution

  • and the response body is empty ... How does a browser access the data from the response?

    It doesn't. Your browser is getting a different response than Laravel/Insomnia/Postman. Have a look at the request headers you are sending in your browser (hint: Firefox web developer tools are easier to use for this than Chrome's- the latter doctors the infotmation it presents to you) and try to recreate these in your automated requests.