title: How to read parameters of Azure function HTTP request and respond with a file from blob storage?
body: <p>I'm building an Azure Function app and have had some issues trying to proxy requests (for data capture purposes) and still respond with the requested files. Essentially what I'm trying to accomplish is:</p>
  
  <ol>
  <li>Client requests file via GET parameter on an Azure Function endpoint (not its blob storage location)</li>
  <li>Function logs some metadata to table storage (e.g. IP address, timestamp, file name, etc.)</li>
  <li>Function locates the desired file in blob storage and forwards it to the client as if Step 2 didn't occur</li>
  </ol>
  
  <p>I've tried an approach using Q (outlined <a href="https://medium.com/@hosarsiph.valle/download-files-with-azure-functions-node-js-35d4f8d08cb8" rel="nofollow noreferrer">here</a>) with no luck, and I haven't been able to narrow the issue down (beyond standard 500 errors).</p>
  
  <p>The tutorial above basically goes as follows:</p>
  
  <pre><code>const rawFile = await q.nfcall(fs.readFile, blobUrl);
  
  const fileBuffer = Buffer.from(rawFile, ‘base64’);
  
  context.res = {
     status: 202,
     body: fileBuffer,
     headers: {
        "Content-Disposition": "attachment; examplefile.mp3;"
     }
  };
  
  context.done();
  </code></pre>
  
  <p>I've hit a bit of a wall and I'm struggling to find a solution to what I thought would be a common problem (i.e. simply logging download metadata to a table). I'm new to Azure and so far I'm finding things a bit tedious... Is there a simple way of doing this?</p>
  
  <p><strong>Edit:</strong> Based on the response I get from <code>context.bindings.myFile.length</code> I <em>think</em> I've been able to retrieve a file from blob storage, but I haven't yet been able to send it back in the response. I've tried the following:</p>
  
  <pre><code>context.res = {
      status: 202,
      body: context.bindings.myFile,
      headers: {
          'Content-Type': 'audio/mpeg',
          'Content-Disposition': 'attachment;filename=' + fileName,
          'Content-Length': context.bindings.myFile.length
      }
  };
  </code></pre>
  
  <p><strong>Edit 2:</strong> I think this is pretty much solved - I overlooked the <code>methods</code> and <code>route</code> in the HTTP input part of the answer below. Looks like I'm able to dynamically retrieve blobs based on the <code>GET</code> request and use them as inputs, and I've been able to get them sent back to the client as well. My HTTP response now looks like this:</p>
  
  <pre><code>context.res = {
      status: 200,
      headers: {
          'Content-Length': context.bindings.myFile.length,
          'Content-Type': 'audio/mpeg'
      },
      body: context.bindings.myFile,
      isRaw: true
  };
  </code></pre>