in src/blob/handlers/PageBlobHandler.ts [51:165]
public async create(
contentLength: number,
blobContentLength: number,
options: Models.PageBlobCreateOptionalParams,
context: Context
): Promise<Models.PageBlobCreateResponse> {
const blobCtx = new BlobStorageContext(context);
const accountName = blobCtx.account!;
const containerName = blobCtx.container!;
const blobName = blobCtx.blob!;
const date = blobCtx.startTime!;
if (options.tier !== undefined) {
throw StorageErrorFactory.getAccessTierNotSupportedForBlobType(
context.contextId!
);
}
if (contentLength !== 0) {
throw StorageErrorFactory.getInvalidOperation(
blobCtx.contextId!,
"Content-Length must be 0 for Create Page Blob request."
);
}
if (blobContentLength % 512 !== 0) {
throw StorageErrorFactory.getInvalidOperation(
blobCtx.contextId!,
"x-ms-content-length must be aligned to a 512-byte boundary."
);
}
options.blobHTTPHeaders = options.blobHTTPHeaders || {};
const contentType =
options.blobHTTPHeaders.blobContentType ||
context.request!.getHeader("content-type") ||
"application/octet-stream";
// const accessTierInferred = options.pageBlobAccessTier === undefined;
// Check Blob size match tier
// if (
// !accessTierInferred &&
// blobContentLength > PageBlobAccessTierThreshold.get(tier)!
// ) {
// throw StorageErrorFactory.getBlobBlobTierInadequateForContentLength(
// blobCtx.contextID!
// );
// }
// Preserve metadata key case
const metadata = convertRawHeadersToMetadata(
blobCtx.request!.getRawHeaders(), context.contextId!
);
const etag = newEtag();
const blob: BlobModel = {
deleted: false,
metadata,
accountName,
containerName,
name: blobName,
properties: {
creationTime: date,
lastModified: date,
etag,
contentLength: blobContentLength,
contentType,
contentEncoding: options.blobHTTPHeaders.blobContentEncoding,
contentLanguage: options.blobHTTPHeaders.blobContentLanguage,
contentMD5: options.blobHTTPHeaders.blobContentMD5,
contentDisposition: options.blobHTTPHeaders.blobContentDisposition,
cacheControl: options.blobHTTPHeaders.blobCacheControl,
blobSequenceNumber: options.blobSequenceNumber
? options.blobSequenceNumber
: 0,
blobType: Models.BlobType.PageBlob,
leaseStatus: Models.LeaseStatusType.Unlocked,
leaseState: Models.LeaseStateType.Available,
serverEncrypted: true
// TODO: May support setting this part for a premium storage account.
// accessTier: accessTierInferred
// ? ((options.pageBlobAccessTier as any) as Models.AccessTier)
// : Models.AccessTier.P4, // TODO: Infer tier from size
// accessTierInferred
},
snapshot: "",
isCommitted: true,
pageRangesInOrder: [],
blobTags: options.blobTagsString === undefined ? undefined : getTagsFromString(options.blobTagsString, context.contextId!),
};
// TODO: What's happens when create page blob right before commit block list? Or should we lock
// Should we check if there is an uncommitted blob?
await this.metadataStore.createBlob(
context,
blob,
options.leaseAccessConditions,
options.modifiedAccessConditions
);
const response: Models.PageBlobCreateResponse = {
statusCode: 201,
eTag: etag,
lastModified: blob.properties.lastModified,
contentMD5: blob.properties.contentMD5,
requestId: context.contextId,
version: BLOB_API_VERSION,
date,
isServerEncrypted: true,
clientRequestId: options.requestId
};
return response;
}