changeset 17651:43b9181340fb

separate object creation from http actions in url_transfer class * url-transfer.h, url-transfer.cc: New functions for http GET and POST actions. Don't perform action in URL constructor. Keep track of FTP vs. HTTP object type. * urlwrite.cc: Update to match.
author John W. Eaton <jwe@octave.org>
date Mon, 07 Oct 2013 23:15:06 -0400
parents 4b65355a31f2
children e5932e528721
files libinterp/corefcn/urlwrite.cc liboctave/util/url-transfer.cc liboctave/util/url-transfer.h
diffstat 3 files changed, 99 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/urlwrite.cc
+++ b/libinterp/corefcn/urlwrite.cc
@@ -410,7 +410,9 @@
 
   frame.add_fcn (delete_file, filename);
 
-  url_transfer curl = url_transfer (url, method, param, ofile);
+  url_transfer curl = url_transfer (url, ofile);
+
+  curl.http_action (param, method);
 
   ofile.close ();
 
@@ -535,7 +537,9 @@
 
   std::ostringstream buf;
 
-  url_transfer curl = url_transfer (url, method, param, buf);
+  url_transfer curl = url_transfer (url, buf);
+
+  curl.http_action (param, method);
 
   if (curl.good ())
     {
--- a/liboctave/util/url-transfer.cc
+++ b/liboctave/util/url-transfer.cc
@@ -45,7 +45,8 @@
 #include <curl/easy.h>
 #endif
 
-void base_url_transfer::delete_file (const std::string& file)
+void
+base_url_transfer::delete_file (const std::string& file)
 {
   octave_unlink (file);
 }
@@ -281,9 +282,9 @@
       errmsg = "can not create curl object";
   }
 
-  curl_transfer (const std::string& host_arg, const std::string& user_arg,
+  curl_transfer (const std::string& host, const std::string& user_arg,
                  const std::string& passwd, std::ostream& os)
-    : base_url_transfer (host_arg, user_arg, passwd, os),
+    : base_url_transfer (host, user_arg, passwd, os),
       curl (curl_easy_init ()), errnum ()
   {
     if (curl)
@@ -296,17 +297,15 @@
 
     init (user_arg, passwd, std::cin, os);
 
-    std::string url ("ftp://" + host_arg);
+    std::string url ("ftp://" + host);
     SETOPT (CURLOPT_URL, url.c_str ());
 
-    // Setup the link, with no transfer.
+    // Set up the link, with no transfer.
     perform ();
   }
 
-  curl_transfer (const std::string& url, const std::string& method,
-                 const Array<std::string>& param, std::ostream& os)
-    : base_url_transfer (url, method, param, os),
-      curl (curl_easy_init ()), errnum ()
+  curl_transfer (const std::string& url, std::ostream& os)
+    : base_url_transfer (url, os), curl (curl_easy_init ()), errnum ()
   {
     if (curl)
       valid = true;
@@ -321,28 +320,10 @@
     SETOPT (CURLOPT_NOBODY, 0);
 
     // Restore the default HTTP request method to GET after setting
-    // NOBODY to true and back to false.  This is needed for backward
-    // compatibility with versions of libcurl < 7.18.2.
+    // NOBODY to true (in the init method) and back to false (above).
+    // This is needed for backward compatibility with versions of
+    // libcurl < 7.18.2.
     SETOPT (CURLOPT_HTTPGET, 1);
-
-    // Don't need to store the parameters here as we can't change
-    // the URL after the object is created
-    std::string query_string = form_query_string (param);
-
-    if (method == "get")
-      {
-        query_string = url + "?" + query_string;
-        SETOPT (CURLOPT_URL, query_string.c_str ());
-      }
-    else if (method == "post")
-      {
-        SETOPT (CURLOPT_URL, url.c_str ());
-        SETOPT (CURLOPT_POSTFIELDS, query_string.c_str ());
-      }
-    else
-      SETOPT (CURLOPT_URL, url.c_str ());
-
-    perform ();
   }
 
   ~curl_transfer (void)
@@ -441,7 +422,7 @@
 
   void put (const std::string& file, std::istream& is)
   {
-    std::string url = "ftp://" + host + "/" + file;
+    std::string url = "ftp://" + host_or_url + "/" + file;
     SETOPT (CURLOPT_URL, url.c_str ());
     SETOPT (CURLOPT_UPLOAD, 1);
     SETOPT (CURLOPT_NOBODY, 0);
@@ -454,13 +435,13 @@
     set_istream (old_is);
     SETOPT (CURLOPT_NOBODY, 1);
     SETOPT (CURLOPT_UPLOAD, 0);
-    url = "ftp://" + host;
+    url = "ftp://" + host_or_url;
     SETOPT (CURLOPT_URL, url.c_str ());
   }
 
   void get (const std::string& file, std::ostream& os)
   {
-    std::string url = "ftp://" + host + "/" + file;
+    std::string url = "ftp://" + host_or_url + "/" + file;
     SETOPT (CURLOPT_URL, url.c_str ());
     SETOPT (CURLOPT_NOBODY, 0);
     std::ostream& old_os = set_ostream (os);
@@ -471,13 +452,13 @@
 
     set_ostream (old_os);
     SETOPT (CURLOPT_NOBODY, 1);
-    url = "ftp://" + host;
+    url = "ftp://" + host_or_url;
     SETOPT (CURLOPT_URL, url.c_str ());
   }
 
   void dir (void)
   {
-    std::string url = "ftp://" + host + "/";
+    std::string url = "ftp://" + host_or_url + "/";
     SETOPT (CURLOPT_URL, url.c_str ());
     SETOPT (CURLOPT_NOBODY, 0);
 
@@ -486,7 +467,7 @@
       return;
 
     SETOPT (CURLOPT_NOBODY, 1);
-    url = "ftp://" + host;
+    url = "ftp://" + host_or_url;
     SETOPT (CURLOPT_URL, url.c_str ());
   }
 
@@ -495,7 +476,7 @@
     string_vector retval;
 
     std::ostringstream buf;
-    std::string url = "ftp://" + host + "/";
+    std::string url = "ftp://" + host_or_url + "/";
     SETOPTR (CURLOPT_WRITEDATA, static_cast<void*> (&buf));
     SETOPTR (CURLOPT_URL, url.c_str ());
     SETOPTR (CURLOPT_DIRLISTONLY, 1);
@@ -506,7 +487,7 @@
       return retval;
 
     SETOPTR (CURLOPT_NOBODY, 1);
-    url = "ftp://" + host;
+    url = "ftp://" + host_or_url;
     SETOPTR (CURLOPT_WRITEDATA, static_cast<void*> (curr_ostream));
     SETOPTR (CURLOPT_DIRLISTONLY, 0);
     SETOPTR (CURLOPT_URL, url.c_str ());
@@ -543,7 +524,7 @@
   {
     std::string path = pwd ();
 
-    std::string url = "ftp://" + host + "/" + path + "/" + filename;
+    std::string url = "ftp://" + host_or_url + "/" + path + "/" + filename;
     SETOPT (CURLOPT_URL, url.c_str ());
     SETOPT (CURLOPT_FILETIME, 1);
     SETOPT (CURLOPT_HEADERFUNCTION, throw_away);
@@ -575,7 +556,7 @@
     SETOPT (CURLOPT_WRITEFUNCTION, write_data);
     SETOPT (CURLOPT_HEADERFUNCTION, 0);
     SETOPT (CURLOPT_FILETIME, 0);
-    url = "ftp://" + host;
+    url = "ftp://" + host_or_url;
     SETOPT (CURLOPT_URL, url.c_str ());
 
     // The MDTM command seems to reset the path to the root with the
@@ -619,6 +600,44 @@
     return retval;
   }
 
+  void http_get (const Array<std::string>& param)
+  {
+    std::string url = host_or_url;
+
+    std::string query_string = form_query_string (param);
+
+    if (! query_string.empty ())
+      url += "?" + query_string;
+
+    SETOPT (CURLOPT_URL, url.c_str ());
+
+    perform ();
+  }
+
+  void http_post (const Array<std::string>& param)
+  {
+    SETOPT (CURLOPT_URL, host_or_url.c_str ());
+
+    std::string query_string = form_query_string (param);
+
+    SETOPT (CURLOPT_POSTFIELDS, query_string.c_str ());
+
+    perform ();
+  }
+
+  void http_action (const Array<std::string>& param, const std::string& action)
+  {
+    if (action.empty () || action == "get")
+      http_get (param);
+    else if (action == "post")
+      http_post (param);
+    else
+      {
+        ok = false;
+        errmsg = "curl_transfer: unknown http action";
+      }
+  }
+
 private:
 
   CURL *curl;
@@ -758,9 +777,8 @@
 #endif
 }
 
-url_transfer::url_transfer (const std::string& url, const std::string& method,
-                            const Array<std::string>& param, std::ostream& os)
-  : rep (new REP_CLASS (url, method, param, os))
+url_transfer::url_transfer (const std::string& url, std::ostream& os)
+  : rep (new REP_CLASS (url, os))
 {
 #if !defined (HAVE_CURL)
   disabled_error ();
--- a/liboctave/util/url-transfer.h
+++ b/liboctave/util/url-transfer.h
@@ -47,24 +47,23 @@
   friend class url_transfer;
 
   base_url_transfer (void)
-    : count (1), host (), userpwd (), valid (false), ascii_mode (false),
-      ok (true), errmsg (), curr_istream (&std::cin), curr_ostream (&std::cout)
+    : count (1), host_or_url (), userpwd (), valid (false), ftp (false),
+      ascii_mode (false), ok (true), errmsg (),
+      curr_istream (&std::cin), curr_ostream (&std::cout)
   { }
 
-  base_url_transfer (const std::string& host_arg,
+  base_url_transfer (const std::string& host,
                      const std::string& /* user_arg */,
                      const std::string& /* passwd */,
                      std::ostream& os)
-    : count (1), host (host_arg), userpwd (), valid (false),
+    : count (1), host_or_url (host), userpwd (), valid (false), ftp (true),
       ascii_mode (false), ok (true), errmsg (), curr_istream (&std::cin),
       curr_ostream (&os) { }
 
-  base_url_transfer (const std::string& /* url */,
-                     const std::string& /* method */,
-                     const Array<std::string>& /* param */,
-                     std::ostream& os)
-    : count (1), host (), userpwd (), valid (false), ascii_mode (false),
-      ok (true), errmsg (), curr_istream (&std::cin), curr_ostream (&os) { }
+  base_url_transfer (const std::string& url, std::ostream& os)
+    : count (1), host_or_url (url), userpwd (), valid (false), ftp (false),
+      ascii_mode (false), ok (true), errmsg (),
+      curr_istream (&std::cin), curr_ostream (&os) { }
 
   virtual ~base_url_transfer (void) { }
 
@@ -128,12 +127,23 @@
 
   virtual std::string pwd (void) { return std::string (); }
 
+  virtual void http_get (const Array<std::string>& /* param */) { }
+
+  virtual void http_post (const Array<std::string>& /* param */) { }
+
+  virtual void http_action (const Array<std::string>& /* param */,
+                            const std::string& /* action */) { }
+
 protected:
 
+  // Reference count.
   octave_refcount<size_t> count;
-  std::string host;
+
+  // Host for ftp transfers or full URL for http requests.
+  std::string host_or_url;
   std::string userpwd;
   bool valid;
+  bool ftp;
   bool ascii_mode;
   bool ok;
   std::string errmsg;
@@ -158,8 +168,7 @@
   url_transfer (const std::string& host, const std::string& user,
                 const std::string& passwd, std::ostream& os);
 
-  url_transfer (const std::string& url, const std::string& method,
-                const Array<std::string>& param, std::ostream& os);
+  url_transfer (const std::string& url, std::ostream& os);
 
   url_transfer (const url_transfer& h) : rep (h.rep)
   {
@@ -257,6 +266,16 @@
 
   std::string pwd (void) { return rep->pwd (); }
 
+  void http_get (const Array<std::string>& param) { rep->http_get (param); }
+
+  void http_post (const Array<std::string>& param) { rep->http_post (param); }
+
+  void http_action (const Array<std::string>& param,
+                    const std::string& action)
+  {
+    rep->http_action (param, action);
+  }
+
 private:
 
   base_url_transfer *rep;