static bool init_downstream_request(JSContext *cx, HandleObject request) {
  MOZ_ASSERT(Request::request_handle(request).handle == INVALID_HANDLE);

  RequestHandle request_handle = {INVALID_HANDLE};
  BodyHandle body_handle = {INVALID_HANDLE};
  if (!HANDLE_RESULT(cx, xqd_req_body_downstream_get(&request_handle, &body_handle)))
    return false;

  JS::SetReservedSlot(request, Request::Slots::Request, JS::Int32Value(request_handle.handle));
  JS::SetReservedSlot(request, Request::Slots::Body, JS::Int32Value(body_handle.handle));

  // Set the method.
  OwnedHostCallBuffer buffer;
  size_t num_written = 0;
  if (!HANDLE_RESULT(cx, xqd_req_method_get(request_handle, buffer.get(), HOSTCALL_BUFFER_LEN,
                                            &num_written))) {
    return false;
  }

  bool is_get = strncmp(buffer.get(), "GET", num_written) == 0;
  if (!is_get) {
    RootedString method(cx, JS_NewStringCopyN(cx, buffer.get(), num_written));
    if (!method) {
      return false;
    }

    JS::SetReservedSlot(request, Request::Slots::Method, JS::StringValue(method));
  }

  // Set whether we have a body depending on the method.
  // TODO: verify if that's right. I.e. whether we should treat all requests
  // that are not GET or HEAD as having a body, which might just be 0-length.
  // It's not entirely clear what else we even could do here though.
  if (!(is_get || strncmp(buffer.get(), "HEAD", num_written) == 0)) {
    JS::SetReservedSlot(request, Request::Slots::HasBody, JS::TrueValue());
  }

  size_t bytes_read;
  UniqueChars buf(
      read_from_handle_all<xqd_req_uri_get, RequestHandle>(cx, request_handle, &bytes_read, false));
  if (!buf)
    return false;

  RootedString url(cx, JS_NewStringCopyN(cx, buf.get(), bytes_read));
  if (!url)
    return false;
  JS::SetReservedSlot(request, Request::Slots::URL, JS::StringValue(url));

  // Set the URL for `globalThis.location` to the client request's URL.
  RootedObject url_instance(cx, JS_NewObjectWithGivenProto(cx, &URL::class_, URL::proto_obj));
  if (!url_instance)
    return false;

  SpecString spec((uint8_t *)buf.release(), bytes_read, bytes_read);
  builtins::WorkerLocation::url = URL::create(cx, url_instance, spec);
  if (!builtins::WorkerLocation::url) {
    return false;
  }

  // Set `fastly.baseURL` to the origin of the client request's URL.
  // Note that this only happens if baseURL hasn't already been set to another
  // value explicitly.
  if (!builtins::Fastly::baseURL.get()) {
    RootedObject url_instance(cx, JS_NewObjectWithGivenProto(cx, &URL::class_, URL::proto_obj));
    if (!url_instance)
      return false;

    builtins::Fastly::baseURL =
        URL::create(cx, url_instance, URL::origin(cx, builtins::WorkerLocation::url));
    if (!builtins::Fastly::baseURL)
      return false;
  }

  return true;
}
static bool init_downstream_request(JSContext *cx, HandleObject request) {
  MOZ_ASSERT(Request::request_handle(request).handle == INVALID_HANDLE);

  RequestHandle request_handle = {INVALID_HANDLE};
  BodyHandle body_handle = {INVALID_HANDLE};
  if (!HANDLE_RESULT(cx, xqd_req_body_downstream_get(&request_handle, &body_handle)))
    return false;

  JS::SetReservedSlot(request, Request::Slots::Request, JS::Int32Value(request_handle.handle));
  JS::SetReservedSlot(request, Request::Slots::Body, JS::Int32Value(body_handle.handle));

   
  OwnedHostCallBuffer buffer;
  size_t num_written = 0;
  if (!HANDLE_RESULT(cx, xqd_req_method_get(request_handle, buffer.get(), HOSTCALL_BUFFER_LEN,
                                            &num_written))) {
    return false;
  }

  bool is_get = strncmp(buffer.get(), "GET", num_written) == 0;
  if (!is_get) {
    RootedString method(cx, JS_NewStringCopyN(cx, buffer.get(), num_written));
    if (!method) {
      return false;
    }

    JS::SetReservedSlot(request, Request::Slots::Method, JS::StringValue(method));
  }

   
   
   
   
  if (!(is_get || strncmp(buffer.get(), "HEAD", num_written) == 0)) {
    JS::SetReservedSlot(request, Request::Slots::HasBody, JS::TrueValue());
  }

  size_t bytes_read;
  UniqueChars buf(
      read_from_handle_all<xqd_req_uri_get, RequestHandle>(cx, request_handle, &bytes_read, false));
  if (!buf)
    return false;

  RootedString url(cx, JS_NewStringCopyN(cx, buf.get(), bytes_read));
  if (!url)
    return false;
  JS::SetReservedSlot(request, Request::Slots::URL, JS::StringValue(url));

   
  RootedObject url_instance(cx, JS_NewObjectWithGivenProto(cx, &URL::class_, URL::proto_obj));
  if (!url_instance)
    return false;

  SpecString spec((uint8_t *)buf.release(), bytes_read, bytes_read);
  builtins::WorkerLocation::url = URL::create(cx, url_instance, spec);
  if (!builtins::WorkerLocation::url) {
    return false;
  }

   
   
   
  if (!builtins::Fastly::baseURL.get()) {
    RootedObject url_instance(cx, JS_NewObjectWithGivenProto(cx, &URL::class_, URL::proto_obj));
    if (!url_instance)
      return false;

    builtins::Fastly::baseURL =
        URL::create(cx, url_instance, URL::origin(cx, builtins::WorkerLocation::url));
    if (!builtins::Fastly::baseURL)
      return false;
  }

  return true;
}