def put_incremental_operations(
        operations, batch_job_url, total_content_length = 0,
        is_last_request = false)
      @api.utils_reporter.batch_job_utils_used()
      headers = DEFAULT_HEADERS
      soap_operations = generate_soap_operations(operations)
      request_body = soap_operations.join
      is_first_request = (total_content_length == 0)

      if is_first_request
        request_body = (UPLOAD_XML_PREFIX % [@version]) + request_body
      end
      if is_last_request
        request_body += UPLOAD_XML_SUFFIX
      end

      request_body = add_padding(request_body)
      content_length = request_body.bytesize

      headers['Content-Length'] = content_length

      lower_bound = total_content_length
      upper_bound = total_content_length + content_length - 1
      total_bytes = is_last_request ? upper_bound + 1 : '*'
      content_range =
          "bytes %d-%d/%s" % [lower_bound, upper_bound, total_bytes]

      headers['Content-Range'] = content_range

      log_request(batch_job_url, headers, request_body)

      # The HTTPI library fails to handle the response when uploading
      # incremental requests. We're not interested in the response, so just
      # ignore the error.
      begin
        AdsCommon::Http.put_response(
            batch_job_url, request_body, @api.config, headers)
      rescue ArgumentError
      end

      total_content_length += content_length
      return total_content_length
    end
def put_incremental_operations(
        operations, batch_job_url, total_content_length = 0,
        is_last_request = false)
      @api.utils_reporter.batch_job_utils_used()
      headers = DEFAULT_HEADERS
      soap_operations = generate_soap_operations(operations)
      request_body = soap_operations.join
      is_first_request = (total_content_length == 0)

      if is_first_request
        request_body = (UPLOAD_XML_PREFIX % [@version]) + request_body
      end
      if is_last_request
        request_body += UPLOAD_XML_SUFFIX
      end

      request_body = add_padding(request_body)
      content_length = request_body.bytesize

      headers['Content-Length'] = content_length

      lower_bound = total_content_length
      upper_bound = total_content_length + content_length - 1
      total_bytes = is_last_request ? upper_bound + 1 : '*'
      content_range =
          "bytes %d-%d/%s" % [lower_bound, upper_bound, total_bytes]

      headers['Content-Range'] = content_range

      log_request(batch_job_url, headers, request_body)

      # The HTTPI library fails to handle the response when uploading
      # incremental requests. We're not interested in the response, so just
      # ignore the error.
      begin
        AdsCommon::Http.put_response(
            batch_job_url, request_body, @api.config, headers)
      rescue ArgumentError
      end

      total_content_length += content_length
      return total_content_length
    end
Puts the provided operations to the provided URL, allowing
 for incremental followup puts.

 Args:
 - soap_operations: An array including SOAP operations provided by
   generate_soap_operations
 - batch_job_url: The UploadURL provided by BatchJobService
 - total_content_length: The total number of bytes already uploaded
   incrementally. Set this to 0 the first time you call the method.
 - is_last_request: Whether or not this set of uploads will conclude the
   full request.

 Returns:
 - total content length, including what was just uploaded. Pass this back
   into this method on subsequent calls.