diff --git a/src/moodle-provider.c b/src/moodle-provider.c
index 3419be731ed7696f4e13f9a069270b5c77d448f1..a370a5a42df284ef1ae45ae6026bed0f22cb73fd 100644
--- a/src/moodle-provider.c
+++ b/src/moodle-provider.c
@@ -202,10 +202,9 @@ moodle_provider_connect (GInputStream **response)
     return MOODLE_ERROR_CONNECTION;
 
   // read request key, needed to auth
-  gchar *uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
+  g_autofree gchar *uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
   if (!sscanf (strstr (uri, "requestkey=")?:"", "requestkey=%32s", request_key))
     g_error ("impossible to read request key\n");
-  g_free (uri);
 
   g_object_unref (msg);
 
@@ -251,12 +250,12 @@ got_course_content_cb (GInputStream       *is,
                        provider_cb         final_cb,
                        gpointer            user_data)
 {
-  gchar *html;
-  gsize  html_size;
+  g_autofree gchar *html = NULL;
+  gsize html_size;
   read_g_input_stream (is, &html, &html_size);
-  if (should_save_to_disk)
-    write_file (filename, html, html_size);
   struct CourseContent content = moodle_parse_course_content (html, html_size, filename);
+  if (should_save_to_disk)
+    write_file (filename, g_steal_pointer (&html), html_size);
   final_cb (user_data, &content);
 }
 
@@ -269,12 +268,12 @@ got_folder_content_cb (GInputStream       *is,
                        provider_cb         final_cb,
                        gpointer            user_data)
 {
-  gchar *html;
+  g_autofree gchar *html = NULL;
   gsize  html_size;
   read_g_input_stream (is, &html, &html_size);
-  if (should_save_to_disk)
-    write_file (filename, html, html_size);
   struct FolderContent content = moodle_parse_folder_content (html, html_size, filename);
+  if (should_save_to_disk)
+    write_file (filename, g_steal_pointer (&html), html_size);
   final_cb (user_data, &content);
 }
 
@@ -290,9 +289,10 @@ enum moodle_error
 moodle_provider_get_courses_sync (courses_cb cb,
                                   gpointer   cb_arg)
 {
-  char *html;
-  size_t html_size;
   g_autofree gchar *filename = get_index_filename ();
+  g_autofree gchar *html = NULL;
+  gsize html_size;
+  struct Courses courses;
 
   if (self.online_mode == MOODLE_MODE_ONLINE) {
 
@@ -304,17 +304,17 @@ moodle_provider_get_courses_sync (courses_cb cb,
       return e;
     }
     read_g_input_stream (index, &html, &html_size);
-    write_file (filename, html, html_size);
+    courses = moodle_parse_course_list (html, html_size, filename);
+    write_file (filename, g_steal_pointer (&html), html_size);
 
   } else { // offline mode
 
     read_file (filename, &html, &html_size);
+    courses = moodle_parse_course_list (html, html_size, filename);
 
   }
 
-  struct Courses c = moodle_parse_course_list (html, html_size, filename);
-  free (html);
-  cb(cb_arg, c);
+  cb(cb_arg, courses);
 
   return MOODLE_ERROR_OK;
 }
diff --git a/src/utils.c b/src/utils.c
index b8f3036ad29a8607517bfe26dfd9027e39ff22a1..7bdaedc048da5fa1100bf5b15cb3b4e15861b886 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -103,22 +103,18 @@ write_file_cb (GObject      *object,
 }
 
 void
-write_file (const char *name, const char *content, size_t size)
+write_file (const char *name, char *content, size_t size)
 {
   g_autoptr (GFile) file = g_file_new_for_uri (name);
-  // if we don't make a copy, it will get free'd by the caller
-  // before we write content to the file. The content should
-  // be "small" (<1MiB): a Moodle web page
-  char *copy = g_strndup (content, size);
   g_file_replace_contents_async (file,
-                                 copy,
+                                 content,
                                  size,
                                  NULL,
                                  FALSE,
                                  G_FILE_CREATE_PRIVATE,
                                  NULL,
                                  write_file_cb,
-                                 copy);
+                                 content);
 }
 
 
diff --git a/src/utils.h b/src/utils.h
index 6af0e77f4eb4fefc034dc5b5cbf2033f7527d9dc..54ff66e2a970bc0d991d0bd19bca070a1f7684e2 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -26,8 +26,9 @@ gchar *get_index_filename (void);
 void
 read_file (const char *name, char **content, size_t *size);
 
+// write_file is responsible for freeing content
 void
-write_file (const char *name, const char *content, size_t size);
+write_file (const char *name, char *content, size_t size);
 
 void
 read_g_input_stream (GInputStream *is, char **content, size_t *size);