{"action":"created","issue":{"url":"https://api.github.com/repos/cfengine/core/issues/2152","labels_url":"https://api.github.com/repos/cfengine/core/issues/2152/labels{/name}","comments_url":"https://api.github.com/repos/cfengine/core/issues/2152/comments","events_url":"https://api.github.com/repos/cfengine/core/issues/2152/events","html_url":"https://github.com/cfengine/core/pull/2152","id":64824534,"number":2152,"title":"Redmine#1815: libcurl integration, curl() function","user":{"login":"tzz","id":67764,"avatar_url":"https://avatars.githubusercontent.com/u/67764?v=3","gravatar_id":"","url":"https://api.github.com/users/tzz","html_url":"https://github.com/tzz","followers_url":"https://api.github.com/users/tzz/followers","following_url":"https://api.github.com/users/tzz/following{/other_user}","gists_url":"https://api.github.com/users/tzz/gists{/gist_id}","starred_url":"https://api.github.com/users/tzz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tzz/subscriptions","organizations_url":"https://api.github.com/users/tzz/orgs","repos_url":"https://api.github.com/users/tzz/repos","events_url":"https://api.github.com/users/tzz/events{/privacy}","received_events_url":"https://api.github.com/users/tzz/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"kacfengine","id":4037094,"avatar_url":"https://avatars.githubusercontent.com/u/4037094?v=3","gravatar_id":"","url":"https://api.github.com/users/kacfengine","html_url":"https://github.com/kacfengine","followers_url":"https://api.github.com/users/kacfengine/followers","following_url":"https://api.github.com/users/kacfengine/following{/other_user}","gists_url":"https://api.github.com/users/kacfengine/gists{/gist_id}","starred_url":"https://api.github.com/users/kacfengine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kacfengine/subscriptions","organizations_url":"https://api.github.com/users/kacfengine/orgs","repos_url":"https://api.github.com/users/kacfengine/repos","events_url":"https://api.github.com/users/kacfengine/events{/privacy}","received_events_url":"https://api.github.com/users/kacfengine/received_events","type":"User","site_admin":false},"milestone":null,"comments":10,"created_at":"2015-03-27T18:31:37Z","updated_at":"2015-04-23T07:44:24Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/cfengine/core/pulls/2152","html_url":"https://github.com/cfengine/core/pull/2152","diff_url":"https://github.com/cfengine/core/pull/2152.diff","patch_url":"https://github.com/cfengine/core/pull/2152.patch"},"body":"This implements the function `curl(URL, OPTIONS)`.\r\n\r\nUsage:\r\n```\r\nbundle agent main\r\n{\r\n  vars:\r\n      \"options_str\" string => '\r\n{\r\n  \"cfengine.max_content\": 512,\r\n  \"curl.verbose\": 0,\r\n  \"curl.headers\": [ \"Foo: bar\" ]\r\n}';\r\n      \"options\" data => parsejson($(options_str));\r\n      \"url\" string => \"http://cfengine.com\";\r\n      \"res\" data => curl($(url), options);\r\n      \"out\" string => format(\"%S\", res);\r\n\r\n      \"url2\" string => \"http://nosuchcfenginehost.com\";\r\n      \"res2\" data => curl($(url2), options);\r\n      \"out2\" string => format(\"%S\", res2);\r\n\r\n  reports:\r\n      \"$(this.bundle): from $(url) with options $(options_str) we got $(out)\";\r\n      \"$(this.bundle): from $(url2) with options $(options_str) we got $(out2)\";\r\n}\r\n```\r\n\r\noutput:\r\n\r\n```console\r\nR: main: from http://cfengine.com with options \r\n{\r\n  \"cfengine.max_content\": 512,\r\n  \"curl.verbose\": 0,\r\n  \"curl.headers\": [ \"Foo: bar\" ]\r\n} we got {\"returncode\":200,\"rc\":0,\"success\":true,\"content\":\"\\n<!DOCTYPE html>\\n<!--[if lt IE 7]>\\n<html class=\\\"no-js lt-ie9 lt-ie8 lt-ie7\\\" lang=\\\"en-US\\\" prefix=\\\"og: http://ogp.me/ns#\\\"> <![endif]-->\\n<!--[if IE 7]>\\n<html class=\\\"no-js lt-ie9 lt-ie8\\\" lang=\\\"en-US\\\" prefix=\\\"og: http://ogp.me/ns#\\\"> <![endif]-->\\n<!--[if IE 8]>\\n<html class=\\\"no-js lt-ie9\\\" lang=\\\"en-US\\\" prefix=\\\"og: http://ogp.me/ns#\\\"> <![endif]-->\\n<!--[if gt IE 8]><!-->\\n<html class=\\\"no-js\\\" lang=\\\"en-US\\\" prefix=\\\"og: http://ogp.me/ns#\\\"> <!--<![endif]-->\\n<head>\\n\\n    \\n    <meta charset=\\\"utf-8\\\">\\n\\n    <title>\\n        CFEng\",\"headers\":\"HTTP/1.1 200 OK\\r\\nDate: Fri, 27 Mar 2015 18:13:01 GMT\\r\\nServer: Apache\\r\\nX-Powered-By: PHP/5.3.3\\r\\nX-Pingback: http://cfengine.com/xmlrpc.php\\r\\nConnection: close\\r\\nTransfer-Encoding: chunked\\r\\nContent-Type: text/html; charset=UTF-8\\r\\n\\r\\n\"}\r\n\r\nR: main: from http://nosuchcfenginehost.com with options \r\n{\r\n  \"cfengine.max_content\": 512,\r\n  \"curl.verbose\": 0,\r\n  \"curl.headers\": [ \"Foo: bar\" ]\r\n} we got {\"returncode\":0,\"rc\":6,\"success\":false,\"content\":\"\",\"headers\":\"\"}\r\n```\r\n\r\nThere are several things to note:\r\n\r\n* the options are mostly simple string keys, except for the headers.  When they begin with `curl` they are passed straight on.  When they begin with `cfengine` they control CFEngine's behavior.\r\n* caching is implemented with a simple global cache. The normal caching won't work for this function.  The cache uses the URL plus the JSON dump of the options as a key.\r\n* we never clean up the global resources on exit.  That should happen on agent exit, I think.  But then the initialization should happen on startup too?\r\n* right now it uses signals in `SIGALRM` but we can turn that off\r\n* default timeout is 3 seconds which is pretty short\r\n* the headers are returned as a big string but could be an array... I can't think of a use for that right now.\r\n* no `PUT` and `POST`, no SSL right now\r\n* it could support writing to a file but currently doesn't, and wouldn't be a probe if it did"},"comment":{"url":"https://api.github.com/repos/cfengine/core/issues/comments/95478915","html_url":"https://github.com/cfengine/core/pull/2152#issuecomment-95478915","issue_url":"https://api.github.com/repos/cfengine/core/issues/2152","id":95478915,"user":{"login":"kacfengine","id":4037094,"avatar_url":"https://avatars.githubusercontent.com/u/4037094?v=3","gravatar_id":"","url":"https://api.github.com/users/kacfengine","html_url":"https://github.com/kacfengine","followers_url":"https://api.github.com/users/kacfengine/followers","following_url":"https://api.github.com/users/kacfengine/following{/other_user}","gists_url":"https://api.github.com/users/kacfengine/gists{/gist_id}","starred_url":"https://api.github.com/users/kacfengine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kacfengine/subscriptions","organizations_url":"https://api.github.com/users/kacfengine/orgs","repos_url":"https://api.github.com/users/kacfengine/repos","events_url":"https://api.github.com/users/kacfengine/events{/privacy}","received_events_url":"https://api.github.com/users/kacfengine/received_events","type":"User","site_admin":false},"created_at":"2015-04-23T07:44:24Z","updated_at":"2015-04-23T07:44:24Z","body":"Alright, you've got some good points. But incorporating this into the package as a dependency is a bit of work and we've already got a tight schedule, so this will only be considered as a \"community can compile it themselves\" kind of thing for 3.7. Then we can create a ticket to get the dependency in for 3.8.\r\n\r\nI agree with @estenberg about the renaming, though I would use an underscore, ``http_get``."}}