aboutsummaryrefslogtreecommitdiff
path: root/libbutl/curl.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-05-01 16:08:43 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-05-01 16:59:24 +0300
commit61377c582e0f2675baa5f5e6e30a35d1a4164b33 (patch)
tree11cdca992834d7f7f197f72856712fbcb3020e3d /libbutl/curl.cxx
parent442c1a6790e52baa0c081f310d4d9e9b6f1ff638 (diff)
Add hxx extension for headers and lib prefix for library dir
Diffstat (limited to 'libbutl/curl.cxx')
-rw-r--r--libbutl/curl.cxx166
1 files changed, 166 insertions, 0 deletions
diff --git a/libbutl/curl.cxx b/libbutl/curl.cxx
new file mode 100644
index 0000000..daa1fd3
--- /dev/null
+++ b/libbutl/curl.cxx
@@ -0,0 +1,166 @@
+// file : libbutl/curl.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <libbutl/curl.hxx>
+
+#include <utility> // move(), forward()
+#include <exception> // invalid_argument
+
+#include <libbutl/utility.hxx> // casecmp()
+
+using namespace std;
+
+namespace butl
+{
+ int curl::
+ map_in (nullfd_t, method_proto mp, io_data& d)
+ {
+ switch (mp)
+ {
+ case ftp_put:
+ throw invalid_argument ("no input specified for PUT method");
+ case http_post:
+ throw invalid_argument ("no input specified for POST method");
+ case ftp_get:
+ case http_get:
+ {
+ d.pipe.in = fdnull (); // /dev/null
+ return d.pipe.in.get ();
+ }
+ }
+
+ return -1;
+ }
+
+ int curl::
+ map_in (const path& f, method_proto mp, io_data& d)
+ {
+ switch (mp)
+ {
+ case ftp_put:
+ case http_post:
+ {
+ if (mp == ftp_put)
+ {
+ d.options.push_back ("--upload-file");
+ d.options.push_back (f.string ().c_str ());
+ }
+ else
+ {
+ d.storage = '@' + f.string ();
+
+ d.options.push_back ("--data-binary");
+ d.options.push_back (d.storage.c_str ());
+ }
+
+ if (f.string () == "-")
+ {
+ d.pipe = fdopen_pipe (fdopen_mode::binary);
+ out.open (move (d.pipe.out));
+ }
+ else
+ d.pipe.in = fdnull (); // /dev/null
+
+ return d.pipe.in.get ();
+ }
+ case ftp_get:
+ case http_get:
+ {
+ throw invalid_argument ("file input specified for GET method");
+ }
+ }
+
+ return -1;
+ }
+
+ int curl::
+ map_out (nullfd_t, method_proto mp, io_data& d)
+ {
+ switch (mp)
+ {
+ case ftp_get:
+ case http_get:
+ throw invalid_argument ("no output specified for GET method");
+ case ftp_put:
+ case http_post: // May or may not produce output.
+ {
+ d.pipe.out = fdnull ();
+ return d.pipe.out.get (); // /dev/null
+ }
+ }
+
+ return -1;
+ }
+
+ int curl::
+ map_out (const path& f, method_proto mp, io_data& d)
+ {
+ switch (mp)
+ {
+ case ftp_get:
+ case http_get:
+ case http_post:
+ {
+ if (f.string () == "-")
+ {
+ // Note: no need for any options, curl writes to stdout by default.
+ //
+ d.pipe = fdopen_pipe (fdopen_mode::binary);
+ in.open (move (d.pipe.in));
+ }
+ else
+ {
+ d.options.push_back ("-o");
+ d.options.push_back (f.string ().c_str ());
+ d.pipe.out = fdnull (); // /dev/null
+ }
+
+ return d.pipe.out.get ();
+ }
+ case ftp_put:
+ {
+ throw invalid_argument ("file output specified for PUT method");
+ }
+ }
+
+ return -1;
+ }
+
+ curl::method_proto curl::
+ translate (method_type m, const string& u, method_proto_options& o)
+ {
+ size_t n (u.find ("://"));
+
+ if (n == string::npos)
+ throw invalid_argument ("no protocol in URL");
+
+ if (casecmp (u, "ftp", n) == 0 ||
+ casecmp (u, "tftp", n) == 0)
+ {
+ switch (m)
+ {
+ case method_type::get: return method_proto::ftp_get;
+ case method_type::put: return method_proto::ftp_put;
+ case method_type::post:
+ throw invalid_argument ("POST method with FTP protocol");
+ }
+ }
+ else if (casecmp (u, "http", n) == 0 ||
+ casecmp (u, "https", n) == 0)
+ {
+ o.push_back ("--fail"); // Fail on HTTP errors (e.g., 404).
+ o.push_back ("--location"); // Follow redirects.
+
+ switch (m)
+ {
+ case method_type::get: return method_proto::http_get;
+ case method_type::post: return method_proto::http_post;
+ case method_type::put:
+ throw invalid_argument ("PUT method with HTTP protocol");
+ }
+ }
+
+ throw invalid_argument ("unsupported protocol");
+ }
+}