'Handles the upload of a file.'

def HandleUpload(self, encoding_header, encoded_upload_token, data_generator):

    if (encoding_header != 'chunked'):
        raise IOError('Only    chunked    uploads    are    allowed.')
    if (not encoded_upload_token):
        raise IOError('Upload    token    not    provided')
    upload_token = rdf_client.UploadToken.FromSerializedString(encoded_upload_token.decode('base64'))
    if (not upload_token.hmac):
        raise IOError('HMAC    not    provided')
    if (not upload_token.encrypted_policy):
        raise IOError('Policy    not    provided')
    if (not upload_token.iv):
        raise IOError('IV    not    provided')
    upload_token.VerifyHMAC()
    policy = rdf_client.UploadPolicy.FromEncryptedPolicy(upload_token.encrypted_policy, upload_token.iv)
    if (rdfvalue.RDFDatetime.Now() > policy.expires):
        raise IOError('Client    upload    policy    is    too    old.')
    upload_store = file_store.UploadFileStore.GetPlugin(config.CONFIG['Frontend.upload_store'])()
    filestore_fd = upload_store.CreateFileStoreFile()
    out_fd = uploads.GunzipWrapper(filestore_fd)
    with uploads.DecryptStream(config.CONFIG['PrivateKeys.server_key'], self._GetClientPublicKey(policy.client_id), out_fd) as decrypt_fd:
        for data in data_generator:
            decrypt_fd.write(data)
    return filestore_fd.Finalize()
