### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

I'm configuring the S3 bucket to have a lifecycle, everything works fine, but when I get the object, the header `Expiration` is not showing

### Expected Behavior

According to the documentation, if the bucket have a `lifecycle configuration` enabled, the header `expiration` should appear in the response

Executing the command
```bash
$ awslocal s3api get-object help
```

We get the documentation of `get-object` command and in the `OUTPUT` section we have:
>Expiration -> (string)
>          If the object expiration is configured (see PUT  Bucket  lifecycle),
>          the  response  includes this header. It includes the expiry-date and
>          rule-id key-value pairs providing object expiration information. The
>          value of the rule-id is URL-encoded.

### How are you starting LocalStack?

With a docker-compose file

### Steps To Reproduce

#### Created the bucket-lifecycle.json
```json
{
  "Rules": [
    {
      "ID": "My Rule ID",
      "Status": "Enabled",
      "Expiration": {
        "Days": 1
      },
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 1
      }
    }
  ]
}
```

####  Command for create the lifecycle configuration on a existing bucket
```bash
$ awslocal s3api put-bucket-lifecycle-configuration --bucket my-bucket --lifecycle-configuration file://bucket-lifecycle.json
```

#### Validate the configuration
```bash
$ awslocal s3api get-bucket-lifecycle-configuration --bucket my-bucket

output:
{
    "Rules": [
        {
            "Expiration": {
                "Days": 1
            },
            "ID": "My Rule ID",
            "Status": "Enabled",
            "NoncurrentVersionExpiration": {
                "NoncurrentDays": 1
            }
        }
    ]
}
```

#### Uploaded an object:
```bash
$ awslocal s3api put-object --bucket my-bucket --key teste.json --body bucket-lifecycle.json  --content-type application/json

output:
{
    "ETag": "\"eb702ecb4e41b09ca62934217d5f13af\""
}
```

#### Fetch the object
```bash
$ awslocal s3api get-object --bucket my-bucket --key teste.json bucket-lifecycle.json 

output:
{
    "AcceptRanges": "bytes",
    "LastModified": "2022-08-11T13:39:11+00:00",
    "ContentLength": 287,
    "ETag": "\"eb702ecb4e41b09ca62934217d5f13af\"",
    "VersionId": "null",
    "ContentLanguage": "en-US",
    "ContentType": "application/json",
    "Metadata": {}
}
```

### Environment

```markdown
- OS: MacOS Monterey
- LocalStack: 1.0.3
```


### Anything else?

_No response_
"""
    This class will take a source stream, and return only a range of it based on the parameters start_byte and end_byte
    """
    def __init__(self, base_stream: IO[bytes], start_byte: int, end_byte: int):
        super().__init__()
        self._base_stream = base_stream
        self._pos = start_byte
        self._length = end_byte - start_byte + 1
    def read(self, s: int = -1) -> bytes | None:
        self._base_stream.seek(self._pos)
        if not s or s < 0:
            amount = self._length
        else:
            amount = min(self._length, s)
        data = self._base_stream.read(amount)
        if not data:
            return b""
        read_amount = len(data)
        self._length -= read_amount
        self._pos += read_amount
        return data
class StreamedFakeKey(s3_models.FakeKey):
    """
    We are overriding the `FakeKey` object from moto to allow streaming input and output instead of loading its full
    value into memory. Most of the changes are related to checksum validation, as we would pass the entire value to the
    checksum before, and we now do it in a chunked manner.
    """
    def __init__(self, name: str, value: IO[bytes], *args, **kwargs):