export function queueStorageContextMiddleware()

in src/queue/middlewares/queueStorageContext.middleware.ts [35:161]


export function queueStorageContextMiddleware(
  req: Request,
  res: Response,
  next: NextFunction,
  skipApiVersionCheck?: boolean,
  disableProductStyleUrl?: boolean
): void {
  // Set server header in every Azurite response
  res.setHeader(HeaderConstants.SERVER, `Azurite-Queue/${VERSION}`);

  const requestID = uuid();

  if (!skipApiVersionCheck) {
    const apiVersion = req.header(HeaderConstants.X_MS_VERSION);
    if (apiVersion !== undefined) {
      checkApiVersion(apiVersion, ValidAPIVersions, requestID);
    }
  }

  const queueContext = new QueueStorageContext(
    res.locals,
    DEFAULT_QUEUE_CONTEXT_PATH
  );
  queueContext.startTime = new Date();

  queueContext.xMsRequestID = requestID;

  logger.info(
    `QueueStorageContextMiddleware: RequestMethod=${req.method} RequestURL=${
      req.protocol
    }://${req.hostname}${req.url} RequestHeaders:${JSON.stringify(
      req.headers
    )} ClientIP=${req.ip} Protocol=${req.protocol} HTTPVersion=${
      req.httpVersion
    }`,
    requestID
  );

  const [
    account,
    queue,
    message,
    messageId,
    isSecondary
  ] = extractStoragePartsFromPath(req.hostname, req.path, disableProductStyleUrl);

  queueContext.account = account;
  queueContext.queue = queue;
  queueContext.message = message;
  queueContext.messageId = messageId;
  queueContext.isSecondary = isSecondary;

  // Emulator's URL pattern is like http://hostname[:port]/account/queue/messages
  // (or, alternatively, http[s]://account.localhost[:port]/queue/messages)
  // Create a router to exclude account name from req.path, as url path in swagger doesn't include account
  // Exclude account name from req.path for dispatchMiddleware
  queueContext.dispatchPattern =
    queue !== undefined
      ? message !== undefined
        ? messageId !== undefined
          ? `/queue/messages/messageId`
          : `/queue/messages`
        : `/queue`
      : "/";

  // The value of queue may be "" in some cases, e.g. list queue with .../accountname/?comp=list...
  if (
    req.query &&
    (req.query.restype === "service" || req.query.comp === "list")
  ) {
    queueContext.dispatchPattern = "/";
  }

  queueContext.authenticationPath = req.path;
  if (isSecondary) {
    const pos = queueContext.authenticationPath.search(SECONDARY_SUFFIX);
    if (pos !== -1)
    {
      queueContext.authenticationPath =
      queueContext.authenticationPath.substr(0, pos) +
      queueContext.authenticationPath.substr(pos + SECONDARY_SUFFIX.length);
    }
  }

  if (account === undefined) {
    const handlerError = StorageErrorFactory.getInvalidQueryParameterValue(
      requestID
    );

    logger.error(
      `QueueStorageContextMiddleware: QueueStorageContextMiddleware: ${handlerError.message}`,
      requestID
    );

    return next(handlerError);
  }

  // If it is not and account operations, then the queue name should be validated.
  if (queueContext.dispatchPattern !== "/" && queue !== undefined) {
    const nameValidateStatus = isValidName(queue);

    if (nameValidateStatus === nameValidateCode.invalidUri) {
      const handlerError = StorageErrorFactory.getInvalidUri(requestID, {
        UriPath: `/${queue}`
      });
      return next(handlerError);
    }

    if (nameValidateStatus === nameValidateCode.outOfRange) {
      const handlerError = StorageErrorFactory.getOutOfRangeName(requestID);
      return next(handlerError);
    }

    if (nameValidateStatus === nameValidateCode.invalidName) {
      const handlerError = StorageErrorFactory.getInvalidResourceName(
        requestID
      );
      return next(handlerError);
    }
  }

  logger.info(
    `QueueStorageContextMiddleware: Account=${account} Queue=${queue} Message=${message} MessageId=${messageId}`,
    requestID
  );
  next();
}