The remote side sends the filename using the Content-Disposition header.
curl 7.21.2 or newer does this automatically if you specify --remote-header-name / -J.
curl -O -J -L $url
The expanded version of the arguments would be:
curl --remote-name --remote-header-name --location $url