Index: /feeds.module
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- /feeds.module	(date 1424116397000)
+++ /feeds.module	(revision )
@@ -614,7 +614,7 @@
   if (isset($node->feeds) && $importer_id = feeds_get_importer_id($node->type)) {
     $source = feeds_source($importer_id, $node->nid);
     // Start import if requested.
-    if (feeds_importer($importer_id)->config['import_on_create'] && !isset($node->feeds['suppress_import'])) {
+    if ($source->hasFetcherSource() && feeds_importer($importer_id)->config['import_on_create'] && !isset($node->feeds['suppress_import'])) {
       $source->startImport();
     }
     // Schedule source and importer.
@@ -630,8 +630,13 @@
   // Source attached to node.
   if (isset($node->feeds) && $importer_id = feeds_get_importer_id($node->type)) {
     $source = feeds_source($importer_id, $node->nid);
+    $had_fetcher_source = $source->hasFetcherSource();
     $source->addConfig($node->feeds);
     $source->save();
+    // Fetcher source was emptied or filled.
+    if ($had_fetcher_source != $source->hasFetcherSource()) {
+      $source->schedule();
+    }
   }
 }

Index: /plugins/FeedsFetcher.inc
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- /plugins/FeedsFetcher.inc	(date 1424116397000)
+++ /plugins/FeedsFetcher.inc	(revision )
@@ -222,4 +222,28 @@
    *   $source, NULL otherwise.
    */
   public function importPeriod(FeedsSource $source) {}
+
+  /**
+   * Override parent::configDefaults().
+   */
+  public function configDefaults() {
+    return array(
+      'source_required' => TRUE,
+    );
+  }
+
+  /**
+   * Override parent::configForm().
+   */
+  public function configForm(&$form_state) {
+    $form = array();
+    // @todo Disable this option on stand-alone importers importer.
+    $form['source_required'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Require feed'),
+      '#description' => t('Ensure a feed source is provided during form submission.'),
+      '#default_value' => $this->config['source_required'],
+    );
+    return $form;
+  }
 }
Index: /plugins/FeedsHTTPFetcher.inc
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- /plugins/FeedsHTTPFetcher.inc	(date 1424116397000)
+++ /plugins/FeedsHTTPFetcher.inc	(revision )
@@ -57,6 +57,9 @@
     if ($this->config['use_pubsubhubbub'] && ($raw = $this->subscriber($source->feed_nid)->receive())) {
       return new FeedsFetcherResult($raw);
     }
+    if (!$source_config['source']) {
+      throw new Exception(t('Source URL is empty.'));
+    }
     $fetcher_result = new FeedsHTTPFetcherResult($source_config['source']);
     // When request_timeout is empty, the global value is used.
     $fetcher_result->setTimeout($this->config['request_timeout']);
@@ -108,14 +111,14 @@
       'use_pubsubhubbub' => FALSE,
       'designated_hub' => '',
       'request_timeout' => NULL,
-    );
+    ) + parent::configDefaults();
   }

   /**
    * Override parent::configForm().
    */
   public function configForm(&$form_state) {
-    $form = array();
+    $form = parent::configForm($form_state);
     $form['auto_detect_feeds'] = array(
       '#type' => 'checkbox',
       '#title' => t('Auto detect feeds'),
@@ -163,7 +166,7 @@
       '#description' => t('Enter a feed URL.'),
       '#default_value' => isset($source_config['source']) ? $source_config['source'] : '',
       '#maxlength' => NULL,
-      '#required' => TRUE,
+      '#required' => $this->config['source_required'],
     );
     return $form;
   }
@@ -173,6 +176,10 @@
    */
   public function sourceFormValidate(&$values) {
     $values['source'] = trim($values['source']);
+    // Skip validating empty source if not required.
+    if (!$values['source'] && !$this->config['source_required']) {
+      return;
+    }

     if (!feeds_valid_url($values['source'], TRUE)) {
       $form_key = 'feeds][' . get_class($this) . '][source';
Index: /includes/FeedsSource.inc
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- /includes/FeedsSource.inc	(date 1424116397000)
+++ /includes/FeedsSource.inc	(revision )
@@ -294,13 +294,15 @@
       'period' => $period,
       'periodic' => TRUE,
     );
+    if (!$this->hasFetcherSource() || $period == FEEDS_SCHEDULE_NEVER && $this->progressImporting() === FEEDS_BATCH_COMPLETE) {
-    if ($period != FEEDS_SCHEDULE_NEVER) {
-      JobScheduler::get('feeds_source_import')->set($job);
-    }
-    else {
-      JobScheduler::get('feeds_source_import')->remove($job);
-    }
-  }
+      if ($period != FEEDS_SCHEDULE_NEVER) {
+        JobScheduler::get('feeds_source_import')->set($job);
+      }
+      else {
+        JobScheduler::get('feeds_source_import')->remove($job);
+      }
+    }
+  }

   /**
    * Schedule background clearing tasks.
@@ -725,5 +727,13 @@
    */
   protected function releaseLock() {
     lock_release("feeds_source_{$this->id}_{$this->feed_nid}");
+  }
+
+  /**
+   * Checks if the fetch source is empty.
+   */
+  public function hasFetcherSource() {
+    $fetcher_source_config = $this->getConfigFor($this->importer->fetcher);
+    return !empty($fetcher_source_config['source']);
   }
 }
Index: /plugins/FeedsFileFetcher.inc
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- /plugins/FeedsFileFetcher.inc	(date 1424116397000)
+++ /plugins/FeedsFileFetcher.inc	(revision )
@@ -152,13 +152,19 @@
         $values['file'] = $file;
       }
       elseif (empty($values['source'])) {
+        if ($this->config['source_required']) {
-        form_set_error('feeds][FeedsFileFetcher][source', t('Please upload a file.'));
-      }
+          form_set_error('feeds][FeedsFileFetcher][source', t('Please upload a file.'));
+        }
+      }
       else {
         // File present from previous upload. Nothing to validate.
       }
     }
     else {
+      // Skip validating empty source if not required.
+      if (!$values['source'] && !$this->config['source_required']) {
+        return;
+      }
       // Check if chosen url scheme is allowed.
       $scheme = file_uri_scheme($values['source']);
       if (!$scheme || !in_array($scheme, $this->config['allowed_schemes'])) {
@@ -216,14 +222,14 @@
       'direct' => FALSE,
       'directory' => $scheme . '://feeds',
       'allowed_schemes' => $schemes,
-    );
+    ) + parent::configDefaults();
   }

   /**
    * Overrides parent::configForm().
    */
   public function configForm(&$form_state) {
-    $form = array();
+    $form = parent::configForm($form_state);
     $form['allowed_extensions'] = array(
       '#type' => 'textfield',
       '#title' => t('Allowed file extensions'),
