header('Content-Range'), 'bytes %d-%d/%d') ?: []; $this->merge([ 'range_start' => $parsed[0] ?? null, 'range_end' => $parsed[1] ?? null, 'total_size' => $parsed[2] ?? null, 'file_name' => strtolower(rawurldecode((string) $this->header('X-File-Name', 'upload'))), ]); } /** * @return array> */ public function rules(): array { $allowedSuffixes = collect([MediaType::Image, MediaType::Video, MediaType::Document]) ->flatMap(fn (MediaType $type) => $type->extensions()) ->map(fn (string $ext) => '.'.$ext) ->all(); return [ 'range_start' => ['required', 'integer', 'min:0'], 'range_end' => ['required', 'integer', 'gte:range_start'], 'total_size' => ['required', 'integer', 'min:1', 'max:'.MediaType::Video->maxSizeInBytes()], 'file_name' => ['required', 'string', 'ends_with:'.implode(',', $allowedSuffixes)], ]; } /** * @return array */ public function messages(): array { return [ 'range_start.required' => 'Invalid Content-Range header', 'range_end.required' => 'Invalid Content-Range header', 'total_size.required' => 'Invalid Content-Range header', 'total_size.max' => 'File size exceeds the maximum allowed ('.MediaType::Video->maxSizeInMb().' MB).', 'file_name.ends_with' => 'File type not supported.', ]; } }