Short answer: I agree with Eight-Bit Guru. The fact that it works on Linux is probably just luck. (Although I'm sure the Linux networking guys would claim that Windows has it all wrong, but I digress).
I hit a similar issue porting some code from Linux to Windows once. My main thread would send an empty UDP packet to the listening address of the socket blocked on a recvfrom call on another thread. The thread waking up on the blocking recvfrom() call would notice the exit condition and promptly return.
The code on Linux worked. The main thread would call getsockname to get the local listen address of the socket and send a packet to it. And it just kind of worked when the socket was binded on INADDR_ANY (which means "all adapters", but is encoded as 0.0.0.0). Sending to 0.0.0.0 would reach the listening socket.
But this code path bombed on the port to Windows. The fix was to just detect when the listen address was 0.0.0.0 and switch it to send to 127.0.0.1 (localhost). And all was well.
So if fixing the code that generates the URL doesn't work, here's two solutions I thought about:
1. Add a route to the routing table (doesn't work)
Now I got to thinking if it was possible to just add a route to the route table. From the cmd line:
route add 0.0.0.0 MASK 255.255.255.255 10.120.30.194
That actually successfully adds a route to the table...
But alas, it didn't seem to work like I thought it would....
2. Run a proxy server
I think this might work for local debugging. You could run Fiddler along with your code. Implement a script/rule in Fiddler that will convert 0.0.0.0 to 127.0.0.1.
You didn't say what was doing the download. If it's a browser, then something like GreaseMonkey might be your friend.