Repository: ansible/ansible-modules-core

Issue:
get_url + file:/// protocol is broken
<!--- Verify first that your issue/request is not already reported in GitHub -->
##### ISSUE TYPE
- Bug Report
##### COMPONENT NAME

get_url module
##### ANSIBLE VERSION

```
$ ansible --version
ansible 2.1.0 (devel de9e70e590) last updated 2016/04/21 10:44:10 (GMT -400)
  lib/ansible/modules/core: (detached HEAD 2256ae0793) last updated 2016/04/21 10:49:47 (GMT -400)
  lib/ansible/modules/extras: (detached HEAD 14c323cc8e) last updated 2016/04/21 10:49:47 (GMT -400)
  config file =
  configured module search path = Default w/o overrides
```
##### CONFIGURATION

NA
##### OS / ENVIRONMENT

ansible from checkout
local connection mode
centos7 VM
##### SUMMARY

get_url doesn't handle the status code of None returned by urllib for the file:// protocol and fails unexpectedly.
##### STEPS TO REPRODUCE

```
- hosts: localhost
  connection: local
  gather_facts: False
  tasks:
    - copy: dest=/tmp/afile.txt content="foobar"
    - get_url: url="file:///tmp/afile.txt" dest=/tmp/afilecopy.txt force=yes
```
##### EXPECTED RESULTS

No task failures.
##### ACTUAL RESULTS

```
$ ansible-playbook -v geturltest.yml
No config file found; using defaults
 [WARNING]: Host file not found: /etc/ansible/hosts

 [WARNING]: provided hosts list is empty, only localhost is available


PLAY [localhost] ***************************************************************

TASK [copy] ********************************************************************
ok: [localhost] => {"changed": false, "checksum": "8843d7f92416211de9ebb963ff4ce28125932878", "dest": "/tmp/afile.txt", "gid": 20, "group": "staff", "mode": "0644", "owner": "jtanner", "path": "/tmp/afile.txt", "size": 6, "state": "file", "uid": 501}

TASK [get_url] *****************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "dest": "/tmp/afilecopy.txt", "failed": true, "msg": "Request failed", "response": "OK (6 bytes)", "state": "absent", "status_code": null, "url": "file:///tmp/afile.txt"}

NO MORE HOSTS LEFT *************************************************************
        to retry, use: --limit @geturltest.retry

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1
```



Discussion:
I'm not positive, but I believe I'm experiencing the same issue on FTP transfers. I see the same symptom of Request failed, response OK (some bytes).

I'm running 2.0.2.0 on Arch:

```
ansible 2.0.2.0
  config file = /data/distributed-http-ops/ansible.cfg
  configured module search path = /usr/share/ansible:./library:../library:../vendor/ansible

Linux 4.5.1-1-ARCH #1 SMP PREEMPT Thu Apr 14 19:19:32 CEST 2016 x86_64 GNU/Linux
```

I realize the fix for the original bug was merged, and I'm on an older version. However, based on looking at the PR, if this is the same problem it won't be resolved by the fix. (The fix only addresses the file:// scheme.)

@jpmens, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/jctanner/ansibullbot/blob/ISSUE_TRIAGE_CLASS/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->


Resolving patch:
diff --git a/network/basics/get_url.py b/network/basics/get_url.py
--- a/network/basics/get_url.py
+++ b/network/basics/get_url.py
@@ -209,7 +209,7 @@ def url_get(module, url, dest, use_proxy, last_mod_time, force, timeout=10, head
         module.exit_json(url=url, dest=dest, changed=False, msg=info.get('msg', ''))
 
     # create a temporary file and copy content to do checksum-based replacement
-    if info['status'] != 200 and not url.startswith('file:/'):
+    if info['status'] != 200 and not url.startswith('file:/') and not (url.startswith('ftp:/') and info.get('msg', '').startswith('OK')):
         module.fail_json(msg="Request failed", status_code=info['status'], response=info['msg'], url=url, dest=dest)
 
     if tmp_dest != '':


Test patch: