@GET
  @Path("/{taskId}/read")
  public MesosFileChunkObject read(
      @PathParam("taskId") String taskId,
      @QueryParam("path") String qPath,
      @QueryParam("offset") Optional<Long> offset,
      @QueryParam("length") Optional<Long> length) {
    final String path = getDefaultPath(taskId, qPath);
    final SingularityTaskHistory history = checkHistory(taskId);

    final String slaveHostname = history.getTask().getOffer().getHostname();
    final String fullPath = new File(history.getDirectory().get(), path).toString();

    try {
      final Optional<MesosFileChunkObject> maybeChunk =
          sandboxManager.read(slaveHostname, fullPath, offset, length);

      if (!maybeChunk.isPresent()) {
        throw WebExceptions.notFound("File %s does not exist for task ID %s", fullPath, taskId);
      }

      return maybeChunk.get();
    } catch (SlaveNotFoundException snfe) {
      throw WebExceptions.notFound(
          "Slave @ %s was not found, it is probably offline", slaveHostname);
    }
  }
  private SingularityTaskHistory checkHistory(String taskId) {
    final SingularityTaskId taskIdObj = getTaskIdObject(taskId);
    final SingularityTaskHistory taskHistory = getTaskHistory(taskIdObj);

    if (!taskHistory.getDirectory().isPresent()) {
      logSupport.checkDirectory(taskIdObj);

      throw WebExceptions.badRequest(
          "Task %s does not have a directory yet - check again soon (enqueued request to refetch)",
          taskId);
    }

    return taskHistory;
  }
  @GET
  @Path("/{taskId}/browse")
  public Collection<MesosFileObject> browse(
      @PathParam("taskId") String taskId, @QueryParam("path") String qPath) {
    final String path = getDefaultPath(taskId, qPath);
    final SingularityTaskHistory history = checkHistory(taskId);

    final String slaveHostname = history.getTask().getOffer().getHostname();
    final String fullPath = new File(history.getDirectory().get(), path).toString();

    try {
      return sandboxManager.browse(slaveHostname, fullPath);
    } catch (SlaveNotFoundException snfe) {
      throw WebExceptions.notFound(
          "Slave @ %s was not found, it is probably offline", slaveHostname);
    }
  }
  @GET
  @Path("/{taskId}/download")
  public Response download(@PathParam("taskId") String taskId, @QueryParam("path") String path) {
    final SingularityTaskHistory history = checkHistory(taskId);

    final String slaveHostname = history.getTask().getOffer().getHostname();
    final String fullPath = new File(history.getDirectory().get(), path).toString();

    try {
      final URI downloadUri =
          new URI(
              "http",
              null,
              slaveHostname,
              5051,
              "/files/download.json",
              String.format("path=%s", fullPath),
              null);

      return Response.temporaryRedirect(downloadUri).build();
    } catch (URISyntaxException e) {
      throw Throwables.propagate(e);
    }
  }