Content-Length 分隔的消息体过早结束

Posted

技术标签:

【中文标题】Content-Length 分隔的消息体过早结束【英文标题】:Premature end of Content-Length delimited message body 【发布时间】:2020-09-14 16:35:15 【问题描述】:

我调试了代码,我得到的错误是在obj.close() 语句之后。我只需要 S3 对象的最后修改日期。

AmazonS3 s3 = AmazonS3ClientBuilder
              .standard()
              .withCredentials(new DefaultAWSCredentialsProviderChain())
              .withRegion(Regions.US_EAST_1)
              .build();
    S3Object obj = null;
    try 
        obj = s3.getObject("bucketName","abc/1.txt");
    
        obj.getObjectContent();
        Date date = obj.getObjectMetadata().getLastModified();
    
       System.out.println(date);
    finally 
        if(obj!=null) 
            obj.close();
           
    

错误:

org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 12; received: 0
    at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:180)
    at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:200)
    at org.apache.http.impl.io.ContentLengthInputStream.close(ContentLengthInputStream.java:103)
    at org.apache.http.impl.execchain.ResponseEntityProxy.streamClosed(ResponseEntityProxy.java:140)
    at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:228)
    at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:174)
    at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
    at com.amazonaws.event.ProgressInputStream.close(ProgressInputStream.java:211)
    at com.amazonaws.util.IOUtils.closeQuietly(IOUtils.java:70)
    at com.amazonaws.services.s3.internal.S3AbortableInputStream.close(S3AbortableInputStream.java:185)
    at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
    at com.amazonaws.services.s3.model.S3ObjectInputStream.close(S3ObjectInputStream.java:136)
    at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
    at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
    at com.amazonaws.event.ProgressInputStream.close(ProgressInputStream.java:211)
    at java.base/java.io.FilterInputStream.close(FilterInputStream.java:180)
    at com.amazonaws.internal.SdkFilterInputStream.close(SdkFilterInputStream.java:99)
    at com.amazonaws.services.s3.model.S3ObjectInputStream.close(S3ObjectInputStream.java:136)
    at com.amazonaws.services.s3.model.S3Object.close(S3Object.java:225)

【问题讨论】:

这也是我日志的一部分:[main] WARN com.amazonaws.services.s3.internal.S3AbortableInputStream - 并非所有字节都从 S3ObjectInputStream 中读取,因此中止 HTTP 连接。这很可能是一个错误,并可能导致次优行为。仅通过远程 GET 请求您需要的字节,或在使用后排空输入流。 21:25:38.161 [main] 调试 org.apache.http.impl.execchain.MainClientExec - 取消请求执行 这种情况有时会发生还是总是会发生?你当时有网络连接吗? 它总是会发生,是的,网络连接在那里 文件有多大? 其实很小,大约 12 个字节 【参考方案1】:

发生这种情况是因为您调用了s3.getObject(),但没有读取它检索到的内容。 SDK 假定如果您检索到对象数据,您就会使用它。

如果您只关心对象元数据,您应该直接在AmazonS3 客户端对象上调用getObjectMetadata()

【讨论】:

我尝试在 AmazonS3 客户端上直接调用 getObjectMetadata,但由于无法关闭此对象,我想我得到了以下错误日志 !原因:com.amazonaws.SdkClientException:无法执行 HTTP 请求:超时等待来自池的连接!在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleRetryableException(AmazonHttpClient.java:1207) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1153) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704) !在 com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686) !在 com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550) !在 com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530) !在 com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5062) !在 com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5008) !在 com.amazonaws.services.s3.AmazonS3Client.getObjectMetadata(AmazonS3Client.java:1338) !在 com.amazonaws.services.s3.AmazonS3Client.getObjectMetadata(AmazonS3Client.java:1312) !在 com.amazonaws.services.s3.AmazonS3Client.doesObjectExist(AmazonS3Client.java:1393) 重启服务器后问题已经消失。直接调用 getObjecMetadata("bucketName, "key") 似乎至少目前有效

以上是关于Content-Length 分隔的消息体过早结束的主要内容,如果未能解决你的问题,请参考以下文章

安装 ObjectAid 时出现 Eclipse 错误

HTTP/1.1 客户端如何知道在存在“Connection: keep-alive”头字段但没有“Content-Length”的情况下消息在哪里结束?

C ++逗号分隔的输入数组代码过早退出

为啥 CMake 在 Qt Creator 中过早结束?

Android ProgressDialog 过早结束

解析云代码过早结束?