下面列出了org.apache.http.HttpStatus#SC_PARTIAL_CONTENT 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static long getStreamLength(HttpURLConnection connection,
Map<String, List<String>> headers) throws IOException {
String cl = connection.getHeaderField(HttpHeaders.CONTENT_LENGTH);
if (cl == null) {
// Try to get the content length by parsing the content range
// because HftpFileSystem does not return the content length
// if the content is partial.
if (connection.getResponseCode() == HttpStatus.SC_PARTIAL_CONTENT) {
cl = connection.getHeaderField(HttpHeaders.CONTENT_RANGE);
return getLengthFromRange(cl);
} else {
throw new IOException(HttpHeaders.CONTENT_LENGTH + " is missing: "
+ headers);
}
}
return Long.parseLong(cl);
}
private static long getStreamLength(HttpURLConnection connection,
Map<String, List<String>> headers) throws IOException {
String cl = connection.getHeaderField(HttpHeaders.CONTENT_LENGTH);
if (cl == null) {
// Try to get the content length by parsing the content range
// because HftpFileSystem does not return the content length
// if the content is partial.
if (connection.getResponseCode() == HttpStatus.SC_PARTIAL_CONTENT) {
cl = connection.getHeaderField(HttpHeaders.CONTENT_RANGE);
return getLengthFromRange(cl);
} else {
throw new IOException(HttpHeaders.CONTENT_LENGTH + " is missing: "
+ headers);
}
}
return Long.parseLong(cl);
}
boolean isIncompleteResponse(HttpResponse resp, Resource resource) {
int status = resp.getStatusLine().getStatusCode();
if (status != HttpStatus.SC_OK
&& status != HttpStatus.SC_PARTIAL_CONTENT) {
return false;
}
Header hdr = resp.getFirstHeader("Content-Length");
if (hdr == null)
return false;
int contentLength;
try {
contentLength = Integer.parseInt(hdr.getValue());
} catch (NumberFormatException nfe) {
return false;
}
return (resource.length() < contentLength);
}
@Override
public InputStream read(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
try {
final StoregateApiClient client = session.getClient();
final HttpUriRequest request = new HttpGet(String.format("%s/v4/download/files/%s?stream=true", client.getBasePath(),
fileid.getFileid(file, new DisabledListProgressListener())));
if(status.isAppend()) {
final HttpRange range = HttpRange.withStatus(status);
final String header;
if(-1 == range.getEnd()) {
header = String.format("bytes=%d-", range.getStart());
}
else {
header = String.format("bytes=%d-%d", range.getStart(), range.getEnd());
}
if(log.isDebugEnabled()) {
log.debug(String.format("Add range header %s for file %s", header, file));
}
request.addHeader(new BasicHeader(HttpHeaders.RANGE, header));
// Disable compression
request.addHeader(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "identity"));
}
final HttpResponse response = client.getClient().execute(request);
switch(response.getStatusLine().getStatusCode()) {
case HttpStatus.SC_OK:
case HttpStatus.SC_PARTIAL_CONTENT:
return new HttpMethodReleaseInputStream(response);
default:
throw new DefaultHttpResponseExceptionMappingService().map(new HttpResponseException(
response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()));
}
}
catch(IOException e) {
throw new DefaultIOExceptionMappingService().map("Download {0} failed", e, file);
}
}
@Override
public InputStream read(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
try {
final SDSApiClient client = session.getClient();
final HttpUriRequest request = new HttpGet(String.format("%s/v4/nodes/files/%s/downloads", client.getBasePath(),
nodeid.getFileid(file, new DisabledListProgressListener())));
request.addHeader("X-Sds-Auth-Token", StringUtils.EMPTY);
if(status.isAppend()) {
final HttpRange range = HttpRange.withStatus(status);
final String header;
if(-1 == range.getEnd()) {
header = String.format("bytes=%d-", range.getStart());
}
else {
header = String.format("bytes=%d-%d", range.getStart(), range.getEnd());
}
if(log.isDebugEnabled()) {
log.debug(String.format("Add range header %s for file %s", header, file));
}
request.addHeader(new BasicHeader(HttpHeaders.RANGE, header));
// Disable compression
request.addHeader(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "identity"));
}
final HttpResponse response = client.getClient().execute(request);
switch(response.getStatusLine().getStatusCode()) {
case HttpStatus.SC_OK:
case HttpStatus.SC_PARTIAL_CONTENT:
return new HttpMethodReleaseInputStream(response);
default:
throw new DefaultHttpResponseExceptionMappingService().map("Download {0} failed", new HttpResponseException(
response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()), file);
}
}
catch(IOException e) {
throw new DefaultIOExceptionMappingService().map("Download {0} failed", e, file);
}
}
private InputStream read(final HttpUriRequest request, final Path file, final TransferStatus status) throws BackgroundException {
request.addHeader(HTTP.CONTENT_TYPE, MEDIA_TYPE);
if(status.isAppend()) {
final HttpRange range = HttpRange.withStatus(status);
final String header;
if(-1 == range.getEnd()) {
header = String.format("bytes=%d-", range.getStart());
}
else {
header = String.format("bytes=%d-%d", range.getStart(), range.getEnd());
}
if(log.isDebugEnabled()) {
log.debug(String.format("Add range header %s for file %s", header, file));
}
request.addHeader(new BasicHeader(HttpHeaders.RANGE, header));
// Disable compression
request.addHeader(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "identity"));
}
final HttpClient client = session.getHttpClient();
try {
final HttpResponse response = client.execute(request);
switch(response.getStatusLine().getStatusCode()) {
case HttpStatus.SC_OK:
case HttpStatus.SC_PARTIAL_CONTENT:
return new HttpMethodReleaseInputStream(response);
default:
throw new DefaultHttpResponseExceptionMappingService().map(
new HttpResponseException(response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()));
}
}
catch(IOException e) {
throw new DriveExceptionMappingService().map("Download {0} failed", e, file);
}
}
private InputStream getInputStreamFromHttpRequest(long startPos, long endPos) throws
GalaxyFDSClientException, IOException {
HttpUriRequest request = objectDownloader.prepareRequest(uri, versionId, startPos, endPos);
HttpResponse response = objectDownloader.executeRequest(request);
HttpEntity httpEntity = response.getEntity();
int statusCode = 0;
try {
statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_PARTIAL_CONTENT) {
if (this.uploadTime != objectDownloader.getUploadTime(response.getAllHeaders())) {
httpEntity.getContent().close();
throw new IOException("The object has been modified");
}
return httpEntity.getContent();
} else {
String errorMsg = fdsHttpClient.formatErrorMsg("get object with uri [" + uri.toString()
+ "] versionId [" + versionId + "]",
response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg, statusCode);
}
} finally {
if (!(statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_PARTIAL_CONTENT)) {
fdsHttpClient.closeResponseEntity(response);
}
}
}
/**
* Prepares to do a partial/resume download.
*
* @param archive The archive we're trying to download.
* @param tmpFile The destination file to download (e.g. something.zip)
* @param propsFile A properties file generated by the last partial download (e.g. .zip.inf)
* @return Null in case we should perform a full download, or a set of headers
* to resume a partial download.
*/
private Header[] preparePartialDownload(Archive archive, File tmpFile, File propsFile) {
// We need both the destination file and its properties to do a resume.
if (mFileOp.isFile(tmpFile) && mFileOp.isFile(propsFile)) {
// The caller already checked the case were the destination file has the
// right size _and_ checksum, so we know at this point one of them is wrong
// here.
// We can obviously only resume a file if its size is smaller than expected.
if (mFileOp.length(tmpFile) < archive.getSize()) {
Properties props = mFileOp.loadProperties(propsFile);
List<Header> headers = new ArrayList<Header>(2);
headers.add(new BasicHeader(HttpHeaders.RANGE,
String.format("bytes=%d-", mFileOp.length(tmpFile))));
// Don't use the properties if there's not at least a 200 or 206 code from
// the last download.
int status = 0;
try {
status = Integer.parseInt(props.getProperty(PROP_STATUS_CODE));
} catch (Exception ignore) {}
if (status == HttpStatus.SC_OK || status == HttpStatus.SC_PARTIAL_CONTENT) {
// Do we have an ETag and/or a Last-Modified?
String etag = props.getProperty(HttpHeaders.ETAG);
String lastMod = props.getProperty(HttpHeaders.LAST_MODIFIED);
if (etag != null && etag.length() > 0) {
headers.add(new BasicHeader(HttpHeaders.IF_MATCH, etag));
} else if (lastMod != null && lastMod.length() > 0) {
headers.add(new BasicHeader(HttpHeaders.IF_MATCH, lastMod));
}
return headers.toArray(new Header[headers.size()]);
}
}
}
// Existing file is either of different size or content.
// Remove the existing file and request a full download.
mFileOp.deleteFileOrFolder(tmpFile);
mFileOp.deleteFileOrFolder(propsFile);
return null;
}
@Override
public InputStream read(final Path file, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException {
try {
if(0L == status.getLength()) {
return new NullInputStream(0L);
}
final StringBuilder uri = new StringBuilder(String.format("%sstorage/v1/b/%s/o/%s?alt=media",
session.getClient().getRootUrl(), containerService.getContainer(file).getName(),
GoogleStorageUriEncoder.encode(containerService.getKey(file))));
if(StringUtils.isNotBlank(file.attributes().getVersionId())) {
uri.append(String.format("?generation=%s", file.attributes().getVersionId()));
}
final HttpUriRequest request = new HttpGet(uri.toString());
request.addHeader(HTTP.CONTENT_TYPE, MEDIA_TYPE);
if(status.isAppend()) {
final HttpRange range = HttpRange.withStatus(status);
final String header;
if(-1 == range.getEnd()) {
header = String.format("bytes=%d-", range.getStart());
}
else {
header = String.format("bytes=%d-%d", range.getStart(), range.getEnd());
}
if(log.isDebugEnabled()) {
log.debug(String.format("Add range header %s for file %s", header, file));
}
request.addHeader(new BasicHeader(HttpHeaders.RANGE, header));
// Disable compression
request.addHeader(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "identity"));
}
final HttpClient client = session.getHttpClient();
final HttpResponse response = client.execute(request);
switch(response.getStatusLine().getStatusCode()) {
case HttpStatus.SC_OK:
case HttpStatus.SC_PARTIAL_CONTENT:
return new HttpMethodReleaseInputStream(response);
default:
throw new DefaultHttpResponseExceptionMappingService().map(
new HttpResponseException(response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()));
}
}
catch(IOException e) {
throw new GoogleStorageExceptionMappingService().map("Download {0} failed", e, file);
}
}
/**
* Prepares to do a partial/resume download.
*
* @param archive The archive we're trying to download.
* @param tmpFile The destination file to download (e.g. something.zip)
* @param propsFile A properties file generated by the last partial download (e.g. .zip.inf)
* @return Null in case we should perform a full download, or a set of headers
* to resume a partial download.
*/
private Header[] preparePartialDownload(Archive archive, File tmpFile, File propsFile) {
// We need both the destination file and its properties to do a resume.
if (mFileOp.isFile(tmpFile) && mFileOp.isFile(propsFile)) {
// The caller already checked the case were the destination file has the
// right size _and_ checksum, so we know at this point one of them is wrong
// here.
// We can obviously only resume a file if its size is smaller than expected.
if (mFileOp.length(tmpFile) < archive.getSize()) {
Properties props = mFileOp.loadProperties(propsFile);
List<Header> headers = new ArrayList<Header>(2);
headers.add(new BasicHeader(HttpHeaders.RANGE,
String.format("bytes=%d-", mFileOp.length(tmpFile))));
// Don't use the properties if there's not at least a 200 or 206 code from
// the last download.
int status = 0;
try {
status = Integer.parseInt(props.getProperty(PROP_STATUS_CODE));
} catch (Exception ignore) {}
if (status == HttpStatus.SC_OK || status == HttpStatus.SC_PARTIAL_CONTENT) {
// Do we have an ETag and/or a Last-Modified?
String etag = props.getProperty(HttpHeaders.ETAG);
String lastMod = props.getProperty(HttpHeaders.LAST_MODIFIED);
if (etag != null && !etag.isEmpty()) {
headers.add(new BasicHeader(HttpHeaders.IF_MATCH, etag));
} else if (lastMod != null && !lastMod.isEmpty()) {
headers.add(new BasicHeader(HttpHeaders.IF_MATCH, lastMod));
}
return headers.toArray(new Header[headers.size()]);
}
}
}
// Existing file is either of different size or content.
// Remove the existing file and request a full download.
mFileOp.deleteFileOrFolder(tmpFile);
mFileOp.deleteFileOrFolder(propsFile);
return null;
}
/**
* @param statusCode The status code of a response.
* @return True if this status code indicates a success with a response body
*/
public static boolean isSuccessWithContent(int statusCode) {
return statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_PARTIAL_CONTENT ||
statusCode == HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION;
}
private int computeStatus(int status) {
switch (status) {
case HttpStatus.SC_FORBIDDEN:
case HttpStatus.SC_METHOD_NOT_ALLOWED:
case HttpStatus.SC_BAD_REQUEST:
case HttpStatus.SC_UNAUTHORIZED:
case HttpStatus.SC_PAYMENT_REQUIRED:
case HttpStatus.SC_NOT_FOUND:
case HttpStatus.SC_NOT_ACCEPTABLE:
case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
case HttpStatus.SC_REQUEST_TIMEOUT:
case HttpStatus.SC_CONFLICT:
case HttpStatus.SC_GONE:
case HttpStatus.SC_LENGTH_REQUIRED:
case HttpStatus.SC_PRECONDITION_FAILED:
case HttpStatus.SC_REQUEST_TOO_LONG:
case HttpStatus.SC_REQUEST_URI_TOO_LONG:
case HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE:
case HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE:
case HttpStatus.SC_EXPECTATION_FAILED:
case HttpStatus.SC_INSUFFICIENT_SPACE_ON_RESOURCE:
case HttpStatus.SC_METHOD_FAILURE:
case HttpStatus.SC_UNPROCESSABLE_ENTITY:
case HttpStatus.SC_LOCKED:
case HttpStatus.SC_FAILED_DEPENDENCY:
case HttpStatus.SC_INTERNAL_SERVER_ERROR:
case HttpStatus.SC_NOT_IMPLEMENTED:
case HttpStatus.SC_BAD_GATEWAY:
case HttpStatus.SC_SERVICE_UNAVAILABLE:
case HttpStatus.SC_GATEWAY_TIMEOUT:
case HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED:
case HttpStatus.SC_INSUFFICIENT_STORAGE:
return 0;
case HttpStatus.SC_CONTINUE:
case HttpStatus.SC_SWITCHING_PROTOCOLS:
case HttpStatus.SC_PROCESSING:
case HttpStatus.SC_OK:
case HttpStatus.SC_CREATED:
case HttpStatus.SC_ACCEPTED:
case HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION:
case HttpStatus.SC_NO_CONTENT:
case HttpStatus.SC_RESET_CONTENT:
case HttpStatus.SC_PARTIAL_CONTENT:
case HttpStatus.SC_MULTI_STATUS:
case HttpStatus.SC_MULTIPLE_CHOICES:
case HttpStatus.SC_MOVED_PERMANENTLY:
case HttpStatus.SC_MOVED_TEMPORARILY:
case HttpStatus.SC_SEE_OTHER:
case HttpStatus.SC_NOT_MODIFIED:
case HttpStatus.SC_USE_PROXY:
case HttpStatus.SC_TEMPORARY_REDIRECT:
return 1;
default :
return 1;
}
}
private FDSObjectInputStream(FDSHttpClient fdsHttpClient, GalaxyFDSClient fdsClient,
HttpEntity httpEntity, URI uri, String bucketName, String objectName, String versionId,
long pos, long uploadTime) throws GalaxyFDSClientException, IOException {
this.fdsClient = fdsClient;
this.bucketName = bucketName;
this.objectName = objectName;
this.versionId = versionId;
this.pos = pos;
this.startTime = System.currentTimeMillis();
FDSClientConfiguration fdsConfig = fdsClient.getFdsConfig();
this.downloadBandwidth = fdsConfig.getDownloadBandwidth();
this.maxRetry = fdsConfig.getRetryCount();
FDSObjectDownloader objectDownloader = new FDSObjectDownloader(fdsHttpClient);
if (httpEntity != null) {
wrappedStream = httpEntity.getContent();
if (uploadTime > 0) {
this.uploadTime = uploadTime;
}
return;
}
if (!fdsConfig.isEnablePreRead()) {
httpUriRequest = objectDownloader.prepareRequest(uri, versionId, pos, -1);
} else {
httpUriRequest = objectDownloader.prepareRequest(uri, versionId, pos, pos +
fdsConfig.getPreReadPartSize() - 1);
}
HttpResponse response = objectDownloader.executeRequest(httpUriRequest);
HttpEntity entity = response.getEntity();
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_PARTIAL_CONTENT) {
LinkedListMultimap<String, String> headers =
fdsHttpClient.headerArray2MultiValuedMap(response.getAllHeaders());
metadata = FDSObjectMetadata.parseObjectMetadata(headers);
summary = new FDSObjectSummary();
summary.setBucketName(this.bucketName);
summary.setObjectName(this.objectName);
summary.setSize(objectDownloader.getObjectSize(response.getAllHeaders(), entity));
summary.setUploadTime(metadata.getLastModified().getTime());
this.uploadTime = summary.getUploadTime();
} else {
String errorMsg = fdsHttpClient.formatErrorMsg("get object [" + objectName + "] with"
+ " versionId [" + versionId + "] from bucket [" + bucketName + "]",
response);
LOG.error(errorMsg);
throw new GalaxyFDSClientException(errorMsg, statusCode);
}
} finally {
if (summary == null) {
fdsHttpClient.closeResponseEntity(response);
}
}
if (!fdsConfig.isEnablePreRead()) {
this.wrappedStream = entity.getContent();
} else {
this.wrappedStream = new PreReadInputStream(fdsConfig, entity.getContent(),
fdsHttpClient, objectDownloader, uri, versionId, this.pos, summary.getSize(),
this.uploadTime);
}
}
/**
* Determines if an HttpResponse can be cached.
*
* @param httpMethod
* What type of request was this, a GET, PUT, other?
* @param response
* The origin response
* @return <code>true</code> if response is cacheable
*/
public boolean isResponseCacheable(String httpMethod, HttpResponse response) {
boolean cacheable = false;
if (!HeaderConstants.GET_METHOD.equals(httpMethod)) {
log.debug("Response was not cacheable.");
return false;
}
switch (response.getStatusLine().getStatusCode()) {
case HttpStatus.SC_OK:
case HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION:
case HttpStatus.SC_MULTIPLE_CHOICES:
case HttpStatus.SC_MOVED_PERMANENTLY:
case HttpStatus.SC_GONE:
// these response codes MAY be cached
cacheable = true;
log.debug("Response was cacheable");
break;
case HttpStatus.SC_PARTIAL_CONTENT:
// we don't implement Range requests and hence are not
// allowed to cache partial content
log.debug("Response was not cacheable (Partial Content)");
return cacheable;
default:
// If the status code is not one of the recognized
// available codes in HttpStatus Don't Cache
log.debug("Response was not cacheable (Unknown Status code)");
return cacheable;
}
Header contentLength = response.getFirstHeader(HTTP.CONTENT_LEN);
if (contentLength != null) {
int contentLengthValue = Integer.parseInt(contentLength.getValue());
if (contentLengthValue > this.maxObjectSizeBytes)
return false;
}
Header[] ageHeaders = response.getHeaders(HeaderConstants.AGE);
if (ageHeaders.length > 1)
return false;
Header[] expiresHeaders = response.getHeaders(HeaderConstants.EXPIRES);
if (expiresHeaders.length > 1)
return false;
Header[] dateHeaders = response.getHeaders(HTTP.DATE_HEADER);
if (dateHeaders.length != 1)
return false;
try {
DateUtils.parseDate(dateHeaders[0].getValue());
} catch (DateParseException dpe) {
return false;
}
for (Header varyHdr : response.getHeaders(HeaderConstants.VARY)) {
for (HeaderElement elem : varyHdr.getElements()) {
if ("*".equals(elem.getName())) {
return false;
}
}
}
if (isExplicitlyNonCacheable(response))
return false;
return (cacheable || isExplicitlyCacheable(response));
}