title: how to determine the filename of content downloaded with HTTP in Python?
body: <p>I download a file using the <code>get</code> function of Python <a href="http://docs.python-requests.org" rel="nofollow noreferrer"><code>requests</code></a> library. For storing the file, I'd like to determine the filename the way a web browser would for its 'save' or 'save as ...' dialog.</p>
  <p>Easy, right? I can just <a href="https://stackoverflow.com/questions/31804799/how-to-get-pdf-filename-with-python-requests/31805472#31805472">get it from the <code>Content-Disposition</code></a> HTTP header, accessible on the response object:</p>
  <pre><code>import re
  d = r.headers['content-disposition']
  fname = re.findall(&quot;filename=(.+)&quot;, d)
  </code></pre>
  <p>But looking more closely at this topic, it isn't <em>that</em> easy:</p>
  <p>According to <a href="https://www.rfc-editor.org/rfc/rfc6266#section-4.3" rel="nofollow noreferrer">RFC 6266 section 4.3</a>, and the grammar in the <a href="https://www.rfc-editor.org/rfc/rfc6266#section-4.1" rel="nofollow noreferrer">section 4.1</a>, the value can be an unquoted token (e.g. <code>the_report.pdf</code>) or a quoted string that can also contain whitespace (e.g. <code>&quot;the report.pdf&quot;</code>) and escape sequences. Further,</p>
  <blockquote>
  <p>when both &quot;filename&quot; and &quot;filename*&quot; are present in a single header field value, [we] SHOULD pick &quot;filename*&quot; and ignore &quot;filename&quot;.</p>
  </blockquote>
  <p>The value of <code>filename*</code>, though, is <a href="https://www.rfc-editor.org/rfc/rfc5987#section-3.2.1" rel="nofollow noreferrer">yet a bit more complicated</a> than the one of <code>filename</code>.</p>
  <p>Also, the RFC seems to allow for additional whitespace around the <code>=</code>.</p>
  <p>Thus, for the <a href="https://www.rfc-editor.org/rfc/rfc6266#section-5" rel="nofollow noreferrer">examples listed in the RFC</a>, I'd want the following results:</p>
  
  <ul>
  <li>
  <pre class="lang-none prettyprint-override"><code>  Content-Disposition: Attachment; filename=example.html
  </code></pre>
  filename: <code>example.html</code></li>
  <li>
  <pre class="lang-none prettyprint-override"><code>  Content-Disposition: INLINE; FILENAME= &quot;an example.html&quot;
  </code></pre>
  filename: <code>an example.html</code></li>
  <li>
  <pre class="lang-none prettyprint-override"><code>  Content-Disposition: attachment;
                         filename*= UTF-8''%e2%82%ac%20rates
  </code></pre>
  filename: <code>€ rates</code></li>
  <li>
  <pre class="lang-none prettyprint-override"><code>  Content-Disposition: attachment;
                         filename=&quot;EURO rates&quot;;
                         filename*=utf-8''%e2%82%ac%20rates
  </code></pre>
  filename: <code>€ rates</code> here, too (not <code>EURO rates</code>, as <code>filename*</code> takes precedence)</li>
  </ul>
  <p>Now, I could easily adapt the regular expression to account for variable whitespace around the <code>=</code>, but having it handle all the other variations, too, would get rather unwieldy. (With the quoting and escaping, I'm not even sure RegEx can cover all the cases. Maybe they can, as there is no brace-nesting involved.)</p>
  <p>So <strong>do I have to implement a full-blown parser, or can I determine filename according to RFC 6266 by some few calls to a HTTP library</strong> (maybe <code>requests</code> itself)? As RFC 6266 is part of the HTTP standard, I could imagine that some libraries specialized on HTTP already cover this. (So I've <a href="https://softwarerecs.stackexchange.com/questions/31836/python-library-to-get-filename-of-content-downloaded-with-http">also asked on Software Recommendations SE</a>.)</p>