0

Using pdftk I generate some dynamic temporary pdf files, which then Django serves to the user.

On a desktop, it works fine - the pdf file opens which then user can save, however on my android phone in all browsers (maybe the same on iOS but don't have and iOS device so can't test), the pdf does not download successfully. It starts the download but then always fails and I can't figure out why.

The following is a snippet of the view and the function which generates the pdf binary data:

def get_pdf():
    fdf = {...}
    t1 = tempfile.NamedTemporaryFile(delete=False)
    t2 = tempfile.NamedTemporaryFile(delete=False)
    t1.file.write(fdf)

    # close temp files for pdftk to work properly
    t1.close()
    t2.close()

    p = Popen('pdftk %s fill_form %s output %s flatten' %
              ('original.pdf', t1.name, t2.name), shell=True)
    p.wait()

    with open(t2.name, 'rb') as fid:
        data = fid.read()

    # delete t1 and t2 since they are temp files

    # at this point the data is the binary of the pdf
    return data


def get_pdf(request):
    pdf = get_pdf()

    response = HttpResponse(pdf, mimetype='application/pdf')
    response['Content-Disposition'] = 'filename=foofile.pdf'
    return response

Any ideas as to why this might be happening?

miki725
  • 27,207
  • 17
  • 105
  • 121
  • 1
    I don't know if it makes a big difference but try to replace response['Content-Disposition'] = 'filename=foofile.pdf' with response['Content-Disposition'] = 'attachment; filename=foofile.pdf' This should start downloading the PDF immediately. Maybe this works better on mobile devices. – Pascal Aug 07 '12 at 00:47
  • 1
    It may also help if you add the Content-Length header to the size of your generated PDF file. – Pascal Aug 07 '12 at 00:51
  • Thanks for your help. Please refer to the answer for to see how I solved it. – miki725 Aug 07 '12 at 22:47

1 Answers1

1

As per @Pascal comment, I added Content-Length and the downloads now work on mobile devices.

However it was not being downloaded with the filename I assign it in the view. Adding attachment fixes this but I don't want the attachment to be present for desktop browsers. Hence the following is my final solution which works.

# I am using the decorator from http://code.google.com/p/minidetector/
@detect_mobile
def event_pdf(request, event_id, variant_id):
    pdf = get_pdf()

    response = HttpResponse(pdf, mimetype='application/pdf')
    response['Content-Disposition'] = '%sfilename=foofile.pdf' %
        request.mobile and 'attachment; ' or ''
    response['Content-Length'] = len(pdf)
    return response
miki725
  • 27,207
  • 17
  • 105
  • 121
  • I just deployed the code on the server with nginx and now the pdfs are no longer downloading. I emulate the request with curl and here response headers I am getting. http://pastebin.com/ypbpVPpe. It seems to respond with the correct headers. Any ideas as to why the downloads might not be going through again? – miki725 Aug 22 '12 at 23:17
  • Do you mean it opens the PDF directly again or does the download not start at all? – Pascal Aug 23 '12 at 00:38
  • does not start at all. but I don't think its a django issue. I am using nginx for the server and even trying to access static file using nginx fails. I created a new question about that: http://stackoverflow.com/questions/12083317/nginx-serve-static-files-over-ssl-on-android – miki725 Aug 23 '12 at 00:47