makeResponse method

Future<void> makeResponse(
  1. HttpResponse res
)

Writes the response to the wire and closes the underlying HttpResponse.

Callers must await this: the returned future completes once the response has been flushed and the connection closed.

Implementation

Future<void> makeResponse(HttpResponse res) async {
  // Answered already, by REQUEST_TIMEOUT: nothing more goes out.
  final scope = currentRequestScope;
  if (scope != null && scope.abandoned) return;
  final pending = scope?.runBeforeResponse();
  if (pending != null) await pending;
  res.statusCode = httpStatusCode;
  if (headers.isNotEmpty) {
    headers.forEach((key, value) {
      res.headers.set(key, value);
    });
  }
  switch (responseType) {
    case ResponseType.json:
      res.headers.contentType = ContentType.json;
      List<int> bytes;
      try {
        bytes = _jsonUtf8.convert(data);
      } catch (e, stack) {
        // Nothing is written yet, so the status can still say it failed.
        Logger.log('$e\n$stack', type: Logger.ERROR);
        res.statusCode = HttpStatus.internalServerError;
        bytes = _jsonUtf8.convert({
          'message': env<bool>('APP_DEBUG', false)
              ? e.toString()
              : 'Internal Server Error',
        });
      }
      res.headers.contentLength = bytes.length;
      res.add(bytes);
      await res.close();
      break;
    case ResponseType.html:
      res.headers.contentType = ContentType.html;
      if (data is String) {
        final bytes = _utf8.convert(data);
        res.headers.contentLength = bytes.length;
        res.add(bytes);
      } else {
        res.write(data);
      }
      await res.close();
      break;
    case ResponseType.sse:
      await sseHandler(res);
      break;
    case ResponseType.streamFile:
      StreamFile? stream = StreamFile(
        fileName: data['fileName'],
        bytes: data['bytes'],
      ).call();
      if (stream == null) {
        res.headers.contentType = ContentType.json;
        res.write(jsonEncode({"message": "File not found"}));
        await res.close();
        break;
      }
      res.headers.contentType = stream.contentType;
      res.headers.contentLength = stream.length;
      res.add(stream.bytes);
      await res.close();
      break;
    case ResponseType.download:
      StreamFile? stream = StreamFile(
        fileName: data['fileName'],
        bytes: data['bytes'],
      ).call();
      if (stream == null) {
        res.headers.contentType = ContentType.json;
        res.write(jsonEncode({"message": "File not found"}));
        await res.close();
        break;
      }
      res.headers.contentType = stream.contentType;
      res.headers.contentLength = stream.length;
      res.headers.add("Content-Disposition", stream.contentDisposition);
      res.add(stream.bytes);
      await res.close();
      break;
    case ResponseType.redirect:
      res.headers.set(HttpHeaders.locationHeader, data);
      await res.close();
      break;
    case ResponseType.none:
      if (data != null) res.write(data);
      await res.close();
      break;
  }
}