Using flutter_downloader with flutter_inappwebview - Response with redirection code

Viewed 620

My Flutter app allows user to access a webpage which requires authentication via Flutter InAppWebView. The webpage allows authenticated user to download a PDF file so I handle the download using the FlutterDownloader in the onDownloadStart event of InAppWebView.

When I try to download the file after logging onto the webpage, the app downloads the Index page of the website instead of the PDF file. Checking the debug logs reveals that the URL was redirected to the login URL:

D/DownloadWorker(15942): Open connection to [PDF URL]
D/DownloadWorker(15942): Response with redirection code
D/DownloadWorker(15942): Location = [Index path]
D/DownloadWorker(15942): New url: [Index page URL]
D/DownloadWorker(15942): Open connection to [Index page URL]
D/DownloadWorker(15942): Headers = {"authorization": "Basic [Auth-token]","connection": "keep-alive"}
D/DownloadWorker(15942): Content-Type = text/html; charset=utf-8
D/DownloadWorker(15942): Content-Length = -1
D/DownloadWorker(15942): Charset = UTF-8
D/DownloadWorker(15942): Content-Disposition = null
D/DownloadWorker(15942): fileName = Index
D/DownloadWorker(15942): Update notification: {notificationId: 22, title: Index, status: 2, progress: -409600}
D/DownloadWorker(15942): There's no application that can open the file /storage/emulated/0/Download/Index (16)
D/DownloadWorker(15942): Update too frequently!!!!, but it is the final update, we should sleep a second to ensure the update call can be processed
D/DownloadWorker(15942): Update notification: {notificationId: 22, title: Index, status: 3, progress: 100}
D/DownloadWorker(15942): File downloaded
I/WM-WorkerWrapper(15942): Worker result SUCCESS for Work [ id=8e03335b-c319-445e-8622-d22bacf34568, tags={ flutter_download_task, vn.hunghd.flutterdownloader.DownloadWorker } ]

I tried saving the cookies and downloading the file using http package but it still get's redirected. I need to allow user to download the PDF file from the current webview.

Any suggestion to resolve the issue would be appreciated.

Thank you.

1 Answers

I've finally found the solution after several tries. The DownloadWorker is redirected to the login page because although the user is authenticated in the InAppWebView, the flutter downloader seems to run in a separate context so the user is not authenticated.

To maintain the user session, I created a variable:

  // Store cookies to save user session for download
  String cookiesString = '';

Then, I created the updateCookies function that retrieves the cookies from the CookieManager and update the cookiesString variable:

  Future<void> updateCookies(Uri url) async {
    List<Cookie> cookies = await CookieManager().getCookies(url: url);
    cookiesString = '';
    for (Cookie cookie in cookies) {
      cookiesString += '${cookie.name}=${cookie.value};';
    }
    print(cookiesString);
  }

Then, I call updateCookies in the onLoadStop event listener of InAppWebView:

onLoadStop: (controller, url) async {
    pullToRefreshController.endRefreshing();

    if (url != null) {
        await updateCookies(url);
    }

    setState(() {
        this.url = url.toString();
        urlController.text = this.url;
    });
},

Finally, I pass the cookies to the headers of FlutterDownloader in the onDownloadStart event listener:

                  await FlutterDownloader.enqueue(
                    headers: {
                      HttpHeaders.authorizationHeader: 'Basic ' +
                          authToken,
                      HttpHeaders.connectionHeader: 'keep-alive',
                      HttpHeaders.cookieHeader: cookiesString,
                    },
Related