docs: def upload_file(
          self,
          filename,
          upload_as=None,
          blocksize=None,
          callback=None,
          information_callback=None,
          allow_timeout=False,
      ):
          """Uploads a file with given filename to this room.
          You may specify upload_as to change the name it is uploaded as.
          You can also specify a blocksize and a callback if you wish.
          Returns the file's id on success and None on failure."""
  
          with delayed_close(
              filename if hasattr(filename, "read") else open(filename, "rb")
          ) as file:
              filename = upload_as or os.path.split(filename)[1]
              try:
                  file.seek(0, 2)
                  if file.tell() > self.config.max_file:
                      raise ValueError(
                          f"File must be at most {self.config.max_file >> 30} GB"
                      )
              finally:
                  try:
                      file.seek(0)
                  except Exception:
                      pass
  
              files = Data(
                  {"file": {"name": filename, "value": file}},
                  blocksize=blocksize,
                  callback=callback,
              )
  
              headers = {"Origin": BASE_URL}
              headers.update(files.headers)
  
              while True:
                  key, server, file_id = self._generate_upload_key(
                      allow_timeout=allow_timeout
                  )
                  info = dict(
                      key=key,
                      server=server,
                      file_id=file_id,
                      room=self.room_id,
                      filename=filename,
                      len=files.len,
                      resumecount=0,
                  )
                  if information_callback:
                      if information_callback(info) is False:
                          continue
                  break
  
              params = {"room": self.room_id, "key": key, "filename": filename}
  
              if self.key:
                  params["roomKey"] = self.key
              if self.password:
                  params["password"] = self.password
  
              while True:
                  try:
                      post = self.conn.post(
                          f"https://{server}/upload",
                          params=params,
                          data=files,
                          headers=headers,
                      )
                      post.raise_for_status()
                      break
  
                  except requests.exceptions.ConnectionError as ex:
                      if "aborted" not in repr(ex):  # ye, that's nasty but "compatible"
                          raise
                      try:
                          resume = self.conn.get(
                              f"https://{server}/rest/uploadStatus",
                              params={"key": key, "c": 1},
                          ).text
                          resume = from_json(resume)
                          resume = resume["receivedBytes"]
                          if resume <= 0:
                              raise ConnectionError("Cannot resume")
                          file.seek(resume)
                          files = Data(
                              {"file": {"name": filename, "value": file}},
                              blocksize=blocksize,
                              callback=callback,
                              logical_offset=resume,
                          )
                          headers.update(files.headers)
                          params["startAt"] = resume
                          info["resumecount"] += 1
                          if information_callback:
                              information_callback(info)
                      except requests.exceptions.ConnectionError as iex:
                          # ye, that's nasty but "compatible"
                          if "aborted" not in repr(iex):
                              raise
                          continue  # another day, another try
              return file_id