diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c
index ef340f7..337b361 100644
--- a/src/tool_cb_hdr.c
+++ b/src/tool_cb_hdr.c
@@ -125,6 +125,10 @@ size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
         return failure;
     }
   }
+  else if (heads->config->followlocation && checkprefix("Location:", str)) {
+   outs->stream = NULL;
+   outs->is_opened = FALSE;
+  }
 
   return cb;
 }
diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c
index dfbf95c..2d7e9b0 100644
--- a/src/tool_cb_wrt.c
+++ b/src/tool_cb_wrt.c
@@ -28,9 +28,51 @@
 #include "tool_cfgable.h"
 #include "tool_msgs.h"
 #include "tool_cb_wrt.h"
+#include "tool_operhlp.h"
 
 #include "memdebug.h" /* keep this as LAST include */
 
+bool open_outfile(struct OperationConfig *const config, struct OutStruct *outs,
+ char *const outfile)
+{ if(config->resume_from_current) {
+    /* We're told to continue from where we are now. Get the size
+       of the file as it is now and open it for append instead */
+    struct_stat fileinfo;
+    /* VMS -- Danger, the filesize is only valid for stream files */
+    if(0 == stat(outfile, &fileinfo))
+      /* set offset to current file size: */
+      config->resume_from = fileinfo.st_size;
+    else
+      /* let offset be 0 */
+      config->resume_from = 0;
+  }
+
+  if(config->resume_from_current || config->resume_from) {
+#ifdef __VMS
+    /* open file for output, forcing VMS output format into stream
+       mode which is needed for stat() call above to always work. */
+    FILE *file = fopen(outfile, config->resume_from?"ab":"wb",
+                       "ctx=stm", "rfm=stmlf", "rat=cr", "mrs=0");
+#else
+    /* open file for output: */
+    FILE *file = fopen(outfile, config->resume_from?"ab":"wb");
+#endif
+    if(!file) {
+      helpf(config->global->errors, "Can't open '%s'!\n", outfile);
+      return false;
+    }
+    outs->fopened = TRUE;
+    outs->stream = file;
+    outs->init = config->resume_from;
+  }
+  else {
+    outs->stream = NULL; /* open when needed */
+  }
+  outs->filename = outfile;
+  outs->s_isreg = TRUE;
+  return true;
+}
+
 /*
 ** callback for CURLOPT_WRITEFUNCTION
 */
@@ -97,13 +139,26 @@ size_t tool_write_cb(void *buffer, size_t sz, size_t nmemb, void *userdata)
 #endif
 
   if(!outs->stream) {
-    FILE *file;
+    // handle redirections
+    long redirects = 0;
+    curl_easy_getinfo(config->easy, CURLINFO_REDIRECT_COUNT, &redirects);
+    if(redirects > 0) {
+      char *location;
+      curl_easy_getinfo(config->easy, CURLINFO_EFFECTIVE_URL, &location);
+      if(get_url_file_name(&outs->filename, location)) return failure;
+      printf (stderr, "file name atfer redirections: %s\n", outs->filename);
+    }
 
     if(!outs->filename || !*outs->filename) {
       warnf(config, "Remote filename has no length!\n");
       return failure;
     }
 
+    // handle resumption
+    if(!open_outfile(config, outs, outs->filename)) return failure;
+  }
+  if(!outs->stream) {
+    FILE *file;
     if(outs->is_cd_filename) {
       /* don't overwrite existing files */
       file = fopen(outs->filename, "rb");
diff --git a/src/tool_operate.c b/src/tool_operate.c
index fd2fd6d..ebe656d 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -543,7 +543,9 @@ static CURLcode operate_do(struct GlobalConfig *global,
             res = get_url_file_name(&outfile, this_url);
             if(res)
               goto show_error;
-            if((!outfile || !*outfile) && !config->content_disposition) {
+            /* filename information might only be avialable on response */
+            if(!*outfile && !config->content_disposition &&
+               !config->followlocation) {
               helpf(global->errors, "Remote file name has no length!\n");
               res = CURLE_WRITE_ERROR;
               goto quit_urls;
@@ -584,48 +586,17 @@ static CURLcode operate_do(struct GlobalConfig *global,
           }
 
           if((urlnode->flags & GETOUT_USEREMOTE)
-             && config->content_disposition) {
+             && (config->content_disposition || config->followlocation)) {
             /* Our header callback MIGHT set the filename */
             DEBUGASSERT(!outs.filename);
           }
 
-          if(config->resume_from_current) {
-            /* We're told to continue from where we are now. Get the size
-               of the file as it is now and open it for append instead */
-            struct_stat fileinfo;
-            /* VMS -- Danger, the filesize is only valid for stream files */
-            if(0 == stat(outfile, &fileinfo))
-              /* set offset to current file size: */
-              config->resume_from = fileinfo.st_size;
-            else
-              /* let offset be 0 */
-              config->resume_from = 0;
-          }
-
-          if(config->resume_from) {
-#ifdef __VMS
-            /* open file for output, forcing VMS output format into stream
-               mode which is needed for stat() call above to always work. */
-            FILE *file = fopen(outfile, config->resume_from?"ab":"wb",
-                               "ctx=stm", "rfm=stmlf", "rat=cr", "mrs=0");
-#else
-            /* open file for output: */
-            FILE *file = fopen(outfile, config->resume_from?"ab":"wb");
-#endif
-            if(!file) {
-              helpf(global->errors, "Can't open '%s'!\n", outfile);
-              res = CURLE_WRITE_ERROR;
-              goto quit_urls;
-            }
-            outs.fopened = TRUE;
-            outs.stream = file;
-            outs.init = config->resume_from;
-          }
-          else {
-            outs.stream = NULL; /* open when needed */
+          // If output filename is fixed, open it already here
+          if(outfile && !config->content_disposition &&
+             !config->followlocation && !open_outfile(config, &outs, outfile))
+          { res = CURLE_WRITE_ERROR;
+            goto quit_urls;
           }
-          outs.filename = outfile;
-          outs.s_isreg = TRUE;
         }
 
         if(uploadfile && !stdin_upload(uploadfile)) {

