'Uploads a file to the GRR server using a direct HTTP transfer.'

def UploadFile(self, file_fd, upload_token, max_bytes=None, network_bytes_limit=None, session_id=None, progress_callback=None):

    def FileGenerator(fd):
        'A    Generator    of    file    content.'
        while 1:
            data = fd.Read(self.UPLOAD_BUFFER_SIZE)
            if (not data):
                break
            if progress_callback:
                progress_callback()
            (yield data)
            l = len(data)
            if session_id:
                self.ChargeBytesToSession(session_id, l, limit=network_bytes_limit)
    gzip_fd = uploads.GzipWrapper(file_fd, byte_limit=max_bytes)
    server_certificate = rdf_crypto.RDFX509Cert(self.client.server_certificate)
    fd = uploads.EncryptStream(server_certificate.GetPublicKey(), config.CONFIG['Client.private_key'], gzip_fd)
    response = self.http_manager.OpenServerEndpoint(u'/upload', data=FileGenerator(fd), headers={'x-grr-upload-token': base64.b64encode(upload_token.SerializeToString())}, method='POST')
    if (response.code != 200):
        raise IOError(('Unable    to    upload    file    (http    code    %d)' % response.code))
    return rdf_client.UploadedFile(bytes_uploaded=gzip_fd.total_read, file_id=response.data, hash=gzip_fd.HashObject())
