def do_post(path, params={})
      login if need_login?

      params = fix_array_of_hashes(params)

      req, res, resource_type, body = nil

      begin
        retry_request do
          @rest_client[path].post(params, headers) do |response, request, result|
            req, res = request, response
            update_cookies(response)
            update_last_request(request, response)

            case response.code
            when 201, 202
              # Create and return the resource
              href = response.headers[:location]
              relative_href = href.split(@api_url)[-1]
              # Return the resource that was just created
              # Determine the resource_type from the href (eg. api/clouds/id).
              # This is based on the assumption that we can determine the resource_type without doing a do_get
              resource_type = get_singular(relative_href.split('/')[-2])
              RightApi::Resource.process(self, resource_type, relative_href)
            when 204
              nil
            when 200..299
              # This is needed for the tags Resource -- which returns a 200 and has a content type
              # therefore, ResourceDetail objects needs to be returned
              if response.code == 200 && response.headers[:content_type].index('rightscale')
                # raise an error if the API is misbehaving and returning an empty response when it shouldn't
                raise EmptyBodyError.new(request, response) if response.body.empty?
                resource_type = get_resource_type(response.headers[:content_type])
                data = JSON.parse(response, :allow_nan => true)
                # Resource_tag is returned after querying tags.by_resource or tags.by_tags.
                # You cannot do a show on a resource_tag, but that is basically what we want to do
                data.map { |obj|
                  RightApi::ResourceDetail.new(self, resource_type, path, obj)
                }
              else
                response.return!(request, result)
              end
            when 301, 302
              update_api_url(response)
              do_post(path, params)
            when 404
              raise UnknownRouteError.new(request, response)
            else
              raise ApiError.new(request, response)
            end
          end
        end
      rescue ApiError => e
        raise wrap(e, :post, path, params, req, res)
      end
    end
def do_post(path, params={})
      login if need_login?

      params = fix_array_of_hashes(params)

      req, res, resource_type, body = nil

      begin
        retry_request do
          @rest_client[path].post(params, headers) do |response, request, result|
            req, res = request, response
            update_cookies(response)
            update_last_request(request, response)

            case response.code
            when 201, 202
              # Create and return the resource
              href = response.headers[:location]
              relative_href = href.split(@api_url)[-1]
              # Return the resource that was just created
              # Determine the resource_type from the href (eg. api/clouds/id).
              # This is based on the assumption that we can determine the resource_type without doing a do_get
              resource_type = get_singular(relative_href.split('/')[-2])
              RightApi::Resource.process(self, resource_type, relative_href)
            when 204
              nil
            when 200..299
              # This is needed for the tags Resource -- which returns a 200 and has a content type
              # therefore, ResourceDetail objects needs to be returned
              if response.code == 200 && response.headers[:content_type].index('rightscale')
                # raise an error if the API is misbehaving and returning an empty response when it shouldn't
                raise EmptyBodyError.new(request, response) if response.body.empty?
                resource_type = get_resource_type(response.headers[:content_type])
                data = JSON.parse(response, :allow_nan => true)
                # Resource_tag is returned after querying tags.by_resource or tags.by_tags.
                # You cannot do a show on a resource_tag, but that is basically what we want to do
                data.map { |obj|
                  RightApi::ResourceDetail.new(self, resource_type, path, obj)
                }
              else
                response.return!(request, result)
              end
            when 301, 302
              update_api_url(response)
              do_post(path, params)
            when 404
              raise UnknownRouteError.new(request, response)
            else
              raise ApiError.new(request, response)
            end
          end
        end
      rescue ApiError => e
        raise wrap(e, :post, path, params, req, res)
      end
    end
Generic post