class Curl::PostField

Public Class Methods

Curl::PostField.content(name, content) → #<Curl::PostField...> click to toggle source
Curl::PostField.content(name, content, content_type = nil) → #<Curl::PostField...>
Curl::PostField.content(name, content_type = nil) { |field| ... } → #<Curl::PostField...>

Create a new Curl::PostField, supplying the field name, content, and, optionally, Content-type (curl will attempt to determine this if not specified).

The block form allows a block to supply the content for this field, called during the perform. The block should return a ruby string with the field data.

static VALUE ruby_curl_postfield_new_content(int argc, VALUE *argv, VALUE klass) {
  ruby_curl_postfield *rbcpf = ALLOC(ruby_curl_postfield);
 
  // wierdness - we actually require two args, unless a block is provided, but
  // we have to work that out below.
  rb_scan_args(argc, argv, "12&", &rbcpf->name, &rbcpf->content, &rbcpf->content_type, &rbcpf->content_proc);

  // special handling if theres a block, second arg is actually content_type
  if (rbcpf->content_proc != Qnil) {
    if (rbcpf->content != Qnil) {
      // we were given a content-type
      rbcpf->content_type = rbcpf->content;
      rbcpf->content = Qnil;
    } else {
      // default content type      
      rbcpf->content_type = Qnil;
    }
  } else {
    // no block, so make sure content was provided    
    if (rbcpf->content == Qnil) {
      rb_raise(rb_eArgError, "Incorrect number of arguments (expected 2 or 3)");
    }    
  }
      
  /* assoc objects */
  rbcpf->local_file = Qnil;
  rbcpf->remote_file = Qnil;
  rbcpf->buffer_str = Qnil;
 
  return Data_Wrap_Struct(cCurlPostField, curl_postfield_mark, curl_postfield_free, rbcpf);
}
Curl::PostField.file(name, local_file_name) → #<Curl::PostField...> click to toggle source
Curl::PostField.file(name, local_file_name, remote_file_name = local_file_name) → #<Curl::PostField...>
Curl::PostField.file(name, remote_file_name) { |field| ... } → #<Curl::PostField...>

Create a new Curl::PostField for a file upload field, supplying the local filename to read from, and optionally the remote filename (defaults to the local name).

The block form allows a block to supply the content for this field, called during the perform. The block should return a ruby string with the field data.

static VALUE ruby_curl_postfield_new_file(int argc, VALUE *argv, VALUE klass) {
  // TODO needs to handle content-type too
  ruby_curl_postfield *rbcpf = ALLOC(ruby_curl_postfield);

  rb_scan_args(argc, argv, "21&", &rbcpf->name, &rbcpf->local_file, &rbcpf->remote_file, &rbcpf->content_proc);

  // special handling if theres a block, second arg is actually remote name.
  if (rbcpf->content_proc != Qnil) {
    if (rbcpf->local_file != Qnil) {
      // we were given a local file
      if (rbcpf->remote_file == Qnil) {
        // we weren't given a remote, so local is actually remote
        // (correct block call form)
        rbcpf->remote_file = rbcpf->local_file;
      }
 
      // Shouldn't get a local file, so can ignore it.
      rbcpf->local_file = Qnil;
    }
  } else {
    if (rbcpf->remote_file == Qnil) {
      rbcpf->remote_file = rbcpf->local_file;
    }
  }
 
  /* assoc objects */
  rbcpf->content = Qnil;
  rbcpf->content_type = Qnil;
  rbcpf->buffer_str = Qnil;
 
  return Data_Wrap_Struct(cCurlPostField, curl_postfield_mark, curl_postfield_free, rbcpf);
}

Public Instance Methods

content → "content" click to toggle source

Obtain the POST field content for this PostField.

static VALUE ruby_curl_postfield_content_get(VALUE self) {
  CURB_OBJECT_GETTER(ruby_curl_postfield, content);
}
content = "content" → "content" click to toggle source

Set the POST field content for this PostField. Ignored when a content_proc is supplied via either +Curl::PostField.file+ or set_content_proc.

static VALUE ruby_curl_postfield_content_set(VALUE self, VALUE content) {
  CURB_OBJECT_SETTER(ruby_curl_postfield, content);
}
content_type → "content_type" click to toggle source

Get the POST field Content-type for this PostField.

static VALUE ruby_curl_postfield_content_type_get(VALUE self) {
  CURB_OBJECT_GETTER(ruby_curl_postfield, content_type);
}
content_type = "content_type" → "content_type" click to toggle source

Set the POST field Content-type for this PostField.

static VALUE ruby_curl_postfield_content_type_set(VALUE self, VALUE content_type) {
  CURB_OBJECT_SETTER(ruby_curl_postfield, content_type);
}
local_file → "filename" click to toggle source

Get the POST field local filename for this PostField (when performing a file upload).

static VALUE ruby_curl_postfield_local_file_get(VALUE self) {
  CURB_OBJECT_GETTER(ruby_curl_postfield, local_file);
}
local_file = "filename" → "filename" click to toggle source

Set the POST field local filename for this PostField (when performing a file upload). Ignored when a content_proc is supplied via either +Curl::PostField.file+ or set_content_proc.

static VALUE ruby_curl_postfield_local_file_set(VALUE self, VALUE local_file) {
  CURB_OBJECT_SETTER(ruby_curl_postfield, local_file);
}
name → "name" click to toggle source

Obtain the POST field name for this PostField.

static VALUE ruby_curl_postfield_name_get(VALUE self) {
  CURB_OBJECT_GETTER(ruby_curl_postfield, name);
}
name = "name" → "name" click to toggle source

Set the POST field name for this PostField.

static VALUE ruby_curl_postfield_name_set(VALUE self, VALUE name) {
  CURB_OBJECT_SETTER(ruby_curl_postfield, name);
}
local_file → "filename" click to toggle source

Get the POST field remote filename for this PostField (when performing a file upload).

static VALUE ruby_curl_postfield_remote_file_get(VALUE self) {
  CURB_OBJECT_GETTER(ruby_curl_postfield, remote_file);
}
remote_file = "filename" → "filename" click to toggle source

Set the POST field remote filename for this PostField (when performing a file upload). If no remote filename is provided, and no content_proc is supplied, the local filename is used. If no remote filename is specified when a content_proc is used, an exception will be raised during the perform.

static VALUE ruby_curl_postfield_remote_file_set(VALUE self, VALUE remote_file) {
  CURB_OBJECT_SETTER(ruby_curl_postfield, remote_file);
}
set_content_proc { |field| ... } → <old proc> click to toggle source

Set a content proc for this field. This proc will be called during the perform to supply the content for this field, overriding any setting of content or local_file.

static VALUE ruby_curl_postfield_content_proc_set(int argc, VALUE *argv, VALUE self) {
  CURB_HANDLER_PROC_SETTER(ruby_curl_postfield, content_proc);
}
to_s()
Alias for: to_str
to_str → "name=value" click to toggle source
to_s → "name=value"

Obtain a String representation of this PostField in url-encoded format. This is used to construct the post data for non-multipart POSTs.

Only content fields may be converted to strings.

static VALUE ruby_curl_postfield_to_str(VALUE self) {
  // FIXME This is using the deprecated curl_escape func
  ruby_curl_postfield *rbcpf;
  VALUE result = Qnil;
  VALUE name = Qnil;
  char *tmpchrs;
  
  Data_Get_Struct(self, ruby_curl_postfield, rbcpf);

    if (rbcpf->name != Qnil) {
      name = rbcpf->name;
      if (rb_type(name) == T_STRING) {
        name = rbcpf->name;
      } else if (rb_respond_to(name,rb_intern("to_s"))) {
        name = rb_funcall(name, rb_intern("to_s"), 0);
      }
      else {
        name = Qnil; // we can't handle this object
      }
    }
    if (name == Qnil) {
      rb_raise(eCurlErrInvalidPostField, "Cannot convert unnamed field to string %s:%d, make sure your field name responds_to :to_s", __FILE__, __LINE__);
    }

    tmpchrs = curl_escape(StringValuePtr(name), (int)RSTRING_LEN(name));
    
    if (!tmpchrs) {
      rb_raise(eCurlErrInvalidPostField, "Failed to url-encode name `%s'", tmpchrs);
    } else {
      VALUE tmpcontent = Qnil;
      VALUE escd_name = rb_str_new2(tmpchrs);
      curl_free(tmpchrs);
      
      if (rbcpf->content_proc != Qnil) {
        tmpcontent = rb_funcall(rbcpf->content_proc, idCall, 1, self);
      } else if (rbcpf->content != Qnil) {
        tmpcontent = rbcpf->content;
      } else if (rbcpf->local_file != Qnil) {
        tmpcontent = rbcpf->local_file;
      } else if (rbcpf->remote_file != Qnil) {
        tmpcontent = rbcpf->remote_file;
      } else {
        tmpcontent = rb_str_new2("");
      }
      if (TYPE(tmpcontent) != T_STRING) {
        if (rb_respond_to(tmpcontent, rb_intern("to_s"))) {
          tmpcontent = rb_funcall(tmpcontent, rb_intern("to_s"), 0);
        }
        else {
          rb_raise(rb_eRuntimeError, "postfield(%s) is not a string and does not respond_to to_s", RSTRING_PTR(escd_name) );
        }
      }
      //fprintf(stderr, "encoding content: %ld - %s\n", RSTRING_LEN(tmpcontent), RSTRING_PTR(tmpcontent) );
      tmpchrs = curl_escape(RSTRING_PTR(tmpcontent), (int)RSTRING_LEN(tmpcontent));
      if (!tmpchrs) {
        rb_raise(eCurlErrInvalidPostField, "Failed to url-encode content `%s'", tmpchrs);
      } else {
        VALUE escd_content = rb_str_new2(tmpchrs);
        curl_free(tmpchrs);
        
        result = escd_name;
        rb_str_cat(result, "=", 1);
        rb_str_concat(result, escd_content); 
      }
    }
  
  return result;
}
Also aliased as: to_s