私は本当にいくつかの洞察を得るという奇妙な問題を抱えています。さまざまなファイルをダウンロードするためのコードがあります。一部のファイルは「chunked」の値を持つ「transfer-encoding」ヘッダーを返しますが、これが問題の原因であると確信しています。
ここが本当に奇妙になるところです。Motorolla Droidを3gでダウンロードすると、すべてのバイトが読み取られる前にダウンロードが終了するため、このエンコーディングのファイルは正しくダウンロードされません。そのため、ファイルが破損しています。ただし、WiFiを使用しているまったく同じ電話では、同じファイルをダウンロードしても問題ありません。
これはサーバーの問題のように聞こえますか?アンドロイドの問題?3gの問題?私のコードの問題?
応答ヘッダーを読み取るために使用しているコードは次のとおりです。
private void readResponseHeaders(HttpResponse response) throws StopRequest {
Header header = response.getFirstHeader("Content-Disposition");
if (header != null) {
mInfo.mInnerState.mHeaderContentDisposition = header.getValue();
}
header = response.getFirstHeader("Content-Location");
if (header != null) {
mInfo.mInnerState.mHeaderContentLocation = header.getValue();
}
if (mInfo.mMimeType == null) {
header = response.getFirstHeader("Content-Type");
if (header != null) {
mInfo.mMimeType = sanitizeMimeType(header.getValue());
}
}
header = response.getFirstHeader("ETag");
if (header != null) {
mInfo.mInnerState.mHeaderETag = header.getValue();
}
String headerTransferEncoding = null;
header = response.getFirstHeader("Transfer-Encoding");
if (header != null) {
headerTransferEncoding = header.getValue();
}
if (headerTransferEncoding == null) {
header = response.getFirstHeader("Content-Length");
if (header != null) {
mInfo.mInnerState.mHeaderContentLength = header.getValue();
mInfo.mTotalBytes = Long.parseLong(mInfo.mInnerState.mHeaderContentLength);
if (!mFileManager.hasSufficientSpace(mInfo.mTotalBytes, mBasePath)){
throw new StopRequest(ServiceDownloadConstants.STATUS_INSUFFICIENT_SPACE_ERROR, "Not Enough Space");
}
}
} else {
// Ignore content-length with transfer-encoding - 2616 4.4 3
if (ServiceDownloadConstants.LOGVV) {
Log.v(ServiceDownloadConstants.TAG,
"ignoring content-length because of xfer-encoding");
}
}
if (ServiceDownloadConstants.LOGVV) {
Log.v(ServiceDownloadConstants.TAG, "Content-Disposition: " + mInfo.mInnerState.mHeaderContentDisposition);
Log.v(ServiceDownloadConstants.TAG, "Content-Length: " + mInfo.mInnerState.mHeaderContentLength);
Log.v(ServiceDownloadConstants.TAG, "Content-Location: " + mInfo.mInnerState.mHeaderContentLocation);
Log.v(ServiceDownloadConstants.TAG, "Content-Type: " + mInfo.mMimeType);
Log.v(ServiceDownloadConstants.TAG, "ETag: " + mInfo.mInnerState.mHeaderETag);
Log.v(ServiceDownloadConstants.TAG, "Transfer-Encoding: " + headerTransferEncoding);
}
boolean noSizeInfo = mInfo.mInnerState.mHeaderContentLength == null
&& (headerTransferEncoding == null
|| !headerTransferEncoding.equalsIgnoreCase("chunked"));
if (!mInfo.mNoIntegrity && noSizeInfo) {
throw new StopRequest(ServiceDownloadConstants.STATUS_HTTP_DATA_ERROR,
"can't know size of download, giving up");
}
}
データの転送に使用しているコードは次のとおりです。
private void transferData(byte[] data, InputStream entityStream) throws StopRequest {
for (;;) {
int bytesRead = readFromResponse( data, entityStream);
if (bytesRead == -1) {
// success, end of stream already reached
handleEndOfStream();
return;
}
writeDataToDestination(data, bytesRead);
mInfo.mInnerState.mBytesSoFar += bytesRead;
/** Update SHA1 if needed **/
if( mInfo.mEnclosure.getHash() != null && mSha1 != null ){
mSha1.update( data, 0, bytesRead );
}
if (ServiceDownloadConstants.LOGVV) {
Log.v(ServiceDownloadConstants.TAG, "downloaded " + mInfo.mInnerState.mBytesSoFar + " for "
+ mInfo.mEnclosure.getUrl());
}
checkPausedOrCanceled();
}
}
編集 さらにデバッグすると、「transfer-encoding」ヘッダーが送信されていない場合でもまったく同じ結果が得られたため、私の問題はWifiで機能し、3gでは機能しないのと同じくらい一般的であるように思われます。