-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
Bug Report
Capacitor Version
@capacitor/cli: 7.4.2
@capacitor/core: 7.4.2
@capacitor/ios: 7.4.2
@capacitor/android: 7.4.2 (not used in this case)
@capacitor/filesystem: 7.1.2
@capacitor/file-transfer: 1.0.1
@capawesome/capacitor-file-picker: 7.2.0
Platform(s)
iOS 18.5 (physical device tested)
Android not tested for this issue
Current Behavior
Using @capacitor/[email protected]
, this upload call:
await FileTransfer.uploadFile({
chunkedMode: true,
path: filePath,
url: uploadFileUrl,
progress: true,
headers: {
// Needed manually to avoid multipart upload
'Content-Type': 'application/octet-stream',
},
});
Without the Content-Type
header:
- The request defaults to
multipart/form-data; boundary=...
— even thoughchunkedMode: true
is specified. - Laravel fails to detect the uploaded file using
$request->file('file')
,$request->hasFile()
, or$request->allFiles()
. - Laravel’s
$request->getContent()
returns raw stream data, but no usable metadata or file parsing is possible.
With Content-Type: application/octet-stream
:
- Laravel does receive the raw stream via
$request->getContent()
— and we're able to successfully save it to a file manually (e.g., usingStorage::put()
). - However, Laravel does not treat the stream as an uploaded file (i.e., it does not appear in
$request->file()
or$request->hasFile()
). - This behavior differs from standard
multipart/form-data
uploads, where Laravel automatically parses and exposes uploaded files.
Additional Issue:
The progress
event reports:
{ bytes: number, contentLength: -1 }
- This prevents reliable upload progress calculation, even though the file size is known and can be read using
Filesystem.stat()
before upload.
Expected Behavior
- With
chunkedMode: true
, the plugin should default toContent-Type: application/octet-stream
(or at least warn about needing it). - Laravel should receive either a proper file in
$request->file()
or at least be clearly documented that stream handling must be manual. - The
progress.contentLength
should return the actual file size, if known, for accurate progress indicators.
Code Reproduction
iOS Side (Capacitor)
await FileTransfer.uploadFile({
chunkedMode: true,
path: filePath,
url: uploadFileUrl,
progress: true,
headers: {
'Content-Type': 'application/octet-stream',
},
});
Laravel Controller
public function upload(Request $request)
{
$data = [
'method' => $request->method(),
'headers' => $request->headers->all(),
'file' => $request->file('file'),
'has_file' => $request->hasFile('file'),
'all_files' => $request->allFiles(),
'raw_content' => $request->getContent(),
];
return response()->json($data);
}
Other Technical Details
Environment:
- Capacitor Core:
7.4.2
- Plugin:
@capacitor/[email protected]
- Laravel:
12.x
- Nuxt:
3.17.3
- Vue:
3.5.18
- Node.js: [e.g., 20.x]
- Device: iPhone running iOS 18.5
- Backend: Laravel with default file upload handling (no special middleware)
Additional Context
- The default fallback to
multipart/form-data
causes silent file loss unless explicitly overridden. chunkedMode
should imply binary streaming or at least be documented with required headers.- The
-1
value forcontentLength
in progress makes % calculation unreliable. - Other Capacitor plugins and tooling are working as expected.
OS-pedrogustavobilro
Metadata
Metadata
Assignees
Labels
No labels