title: Why does Apache/WSGI map HEAD to GET? How to speed up HEAD in Flask?
body: <p>Here's a Flask app that can be run either from the command-line or via Apache/WSGI:</p>
  
  <pre class="lang-python prettyprint-override"><code>import flask
  app = flask.Flask(__name__)
  
  LENGTH = 1000000                # one million
  
  @app.route('/', methods=['HEAD'])
  def head():
      return 'x' * LENGTH         # response body isn't actually sent
  
  @app.route('/', methods=['GET'])
  def get():
      import random
      return ''.join(str(random.randint(0,9)) for x in range(LENGTH))
  
  if __name__ == '__main__':
      app.run()                   # from command-line
  else:
      application = app           # via Apache and WSGI
  </code></pre>
  
  <p>I.e., this app returns a million random digits.  The GET request takes a non-trivial amount of time, but a HEAD request should be able to return almost immediately.  This is of course an illustrative example; the real application would involve large responses that are slow to generate for a GET request, but that also have pre-determined size that could be quickly queried by a HEAD request.  (Another scenario: I'm trying to redirect requests to pre-signed Amazon S3 URLs, which must be signed differently for HEAD and GET methods.)</p>
  
  <p>Question #1) When I run the Flask app from the command-line, a HEAD request activates the <code>head</code> function, as expected; but when I run this via Apache/WSGI, it activates the <code>get</code> function.   Why is this, and how can I work around it to get my desired behavior?</p>
  
  <p>Question #2) instead of creating a dummy response (allocating a bunch of memory) for the HEAD request, why can't I return <code>app.make_response('', 200, {'Content-Length':LENGTH})</code>?</p>
  
  <p>My guess is that these are caused by a well-intentioned attempt to ensure that a HEAD request should always be consistent with the corresponding GET. So:</p>
  
  <p>Guess #1) Either Apache or WSGI is internally rewriting HEAD to GET.</p>
  
  <p>Guess #2) Flask doesn't trust me to set the Content-Length header manually, and rewrites it with the actual length of the response body... even for a HEAD request where this is in fact supposed to be empty.</p>
  
  <p>Am I misunderstanding something?  Any advice on how I can enable faster handling of HEAD requests, ideally without having to slowly generate a large response body that is only used to set the Content-Length header?</p>