api_dev/src/main/java/com/google/appengine/api/blobstore/dev/ServeBlobFilter.java [149:217]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  private void serveBlob(BlobKey blobKey,
                         boolean hasContentType,
                         HttpServletRequest request,
                         HttpServletResponse response)
      throws IOException {
    if (response.isCommitted()) {
      logger.severe("Asked to send blob " + blobKey + " but response was already committed.");
      return;
    }

    // Data presence in info storage is the primary clue of whether this
    // is a valid blob.
    BlobInfo blobInfo = blobInfoStorage.loadBlobInfo(blobKey);
    if (blobInfo == null) {
      blobInfo = blobInfoStorage.loadGsFileInfo(blobKey);
    }
    if (blobInfo == null) {
      logger.severe("Could not find blob: " + blobKey);
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    // And the blob missing from storage is redundant (although for file
    // storage could happen if the file was deleted).
    if (!getBlobStorage().hasBlob(blobKey)) {
      logger.severe("Blob " + blobKey + " missing. Did you delete the file?");
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    if (!hasContentType) {
      response.setContentType(getContentType(blobKey));
    }

    try {
      calculateContentRange(blobInfo, request, response);

      String contentRange = ((ResponseWrapper)response).getContentRangeHeader();
      long contentLength = blobInfo.getSize();
      long start = 0;
      if (contentRange != null) {
        ByteRange byteRange = ByteRange.parseContentRange(contentRange);
        start = byteRange.getStart();
        contentLength = byteRange.getEnd() - byteRange.getStart() + 1;
        response.setStatus(206);
      }
      response.setHeader("Content-Length", Long.toString(contentLength));

      boolean swallowDueToThrow = true;
      InputStream inStream = getBlobStorage().fetchBlob(blobKey);
      try {
        OutputStream outStream = response.getOutputStream();
        try {
          inStream.skip(start);
          copy(inStream, outStream, contentLength);
          swallowDueToThrow = false;
        } finally {
          Closeables.close(outStream, swallowDueToThrow);
        }
      } finally {
        Closeables.close(inStream, swallowDueToThrow);
      }
    } catch (RangeFormatException ex) {
      // Errors become 416, as in production.
      response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
      return;
    }

  }
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



api_dev/src/main/java/com/google/appengine/api/blobstore/dev/ee10/ServeBlobFilter.java [153:221]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  private void serveBlob(BlobKey blobKey,
                         boolean hasContentType,
                         HttpServletRequest request,
                         HttpServletResponse response)
      throws IOException {
    if (response.isCommitted()) {
      logger.severe("Asked to send blob " + blobKey + " but response was already committed.");
      return;
    }

    // Data presence in info storage is the primary clue of whether this
    // is a valid blob.
    BlobInfo blobInfo = blobInfoStorage.loadBlobInfo(blobKey);
    if (blobInfo == null) {
      blobInfo = blobInfoStorage.loadGsFileInfo(blobKey);
    }
    if (blobInfo == null) {
      logger.severe("Could not find blob: " + blobKey);
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    // And the blob missing from storage is redundant (although for file
    // storage could happen if the file was deleted).
    if (!getBlobStorage().hasBlob(blobKey)) {
      logger.severe("Blob " + blobKey + " missing. Did you delete the file?");
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    if (!hasContentType) {
      response.setContentType(getContentType(blobKey));
    }

    try {
      calculateContentRange(blobInfo, request, response);

      String contentRange = ((ResponseWrapper)response).getContentRangeHeader();
      long contentLength = blobInfo.getSize();
      long start = 0;
      if (contentRange != null) {
        ByteRange byteRange = ByteRange.parseContentRange(contentRange);
        start = byteRange.getStart();
        contentLength = byteRange.getEnd() - byteRange.getStart() + 1;
        response.setStatus(206);
      }
      response.setHeader("Content-Length", Long.toString(contentLength));

      boolean swallowDueToThrow = true;
      InputStream inStream = getBlobStorage().fetchBlob(blobKey);
      try {
        OutputStream outStream = response.getOutputStream();
        try {
          inStream.skip(start);
          copy(inStream, outStream, contentLength);
          swallowDueToThrow = false;
        } finally {
          Closeables.close(outStream, swallowDueToThrow);
        }
      } finally {
        Closeables.close(inStream, swallowDueToThrow);
      }
    } catch (RangeFormatException ex) {
      // Errors become 416, as in production.
      response.setStatus(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
      return;
    }

  }
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



