CloudFront => Rails で直結する場合は X-Forwarded-Proto ではなく X-Forwarded-SSL ヘッダを付けると良い

Rails + AWSで雑にhttps を立てたいと思い

CloudFront(https) => EC2(Railsアプリ/http)

という構成でアプリを作ると、 GET 以外のリクエストを投げるとこんなエラーが出る

```
HTTP Origin header (https://xxx.cloudfront.net) didn't match request.base_url (http://xxx.cloudfront.net)
```

ApplicationController で適当にリクエストヘッダーを出力してあーでもないこーでもないとこねくり回してみたのだが・・・
```
class ApplicationController < ActionController::Base
  before_action :env_log

  private

  def env_log
    request.headers.sort.reject { |k, _| k.to_s.include?('.') }.each { |k, v| logger.info "#{k}:#{v}" }
  end
 end
```

自前でリバースプロキシをする時は、 X-Forward-Proto に https を設定するのが定石だが、CloudFront で動かしてみるとどうも X-Forward-Proto だけがうまく設定されない
![Notification_Center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10613/f81e0c0e-a1a4-4a72-f666-29b2fcc20043.png)

例えば
- ヘッダー名: Hoge
- 値: Piyo

みたいな設定は動くけど、X-Forward-Proto だけが消去される

CloudFront には CloudFront-Forwarded-Proto という独自ヘッダーがあるらしく、
ビヘイビア側の設定で、Cloudfront-Forwarded-Protoを飛ばすように設定すると、そこにはhttpsが入ってくる。

Rack Middleware でCloudFront-Forwarded-Proto を X-Forward-Proto に置換するというのも見つけたけど、
https://aknep.hatenablog.com/entry/2017/09/17/230405

アプリを書き換えるのは嫌だなーと思っていたところ
https://mikamisan.hatenablog.com/entry/2017/09/28/230215

こちらで、Railsは X-Forwarded-SSLというフラグを見ているという記事を発見した
![Notification_Center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10613/ea26a951-096a-af6d-d121-1d22eba3e350.png)

ソース:
https://github.com/rack/rack/blob/rack-1.5/lib/rack/request.rb#L73

ということで、X-Forward-Protoの設定は諦めて、X-Forwarded-SSL:on という設定を利用したら上手に動作した。

しかし、X-Forward-Proto がなぜ勝手に消されるのかは不明。

以下CloudFormation

```
Parameters:
  EnvironmentName:
    Description: An environment name that will be prefixed to resource names
    Type: String
  VPC:
    Type: AWS::EC2::VPC::Id
    Description: Choose which VPC the security groups should be deployed to

  DefaultTTL:
    Description: The default cache time in seconds
    Type: Number
    Default: 86400 # 24hrs
  MaxTTL:
    Description: The maximum cache time in seconds
    Type: Number
    Default: 604800 # 168hrs
  MinTTL:
    Description: The minimum cache time in seconds
    Type: Number
    Default: 60 # 1 minute

  ErrorCacheTTL:
    Description: The Error cache time in seconds
    Type: Number
    Default: 60 # 1 minute

  EndpointName:
    Description: ELB Ref
    Type: String
    Default: ''

  TargetOriginId:
    Type: String
    Description: target id
    Default: 's3-bucket'

  DefaultCachePolicyId:
    Description: Cache Policy Id. (Default policy is ManagedCachingDisabled)
    Type: String
    Default: '4135ea2d-6df8-44a3-9df3-4b5a84be39ad'
    AllowedPattern: '[-\.a-z0-9]*'
    # ManagedCachingOptimized https://docs.amazonaws.cn/en_us/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html

  DefaultOriginRequestPolicyId:
    Description: Origin request Policy Id. (Default policy is AllViewer)
    Type: String
    Default: '216adef6-5c7f-47e4-b989-5492eafa07d3'
    AllowedPattern: '[-\.a-z0-9]*'


Resources:
  Distribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        DefaultCacheBehavior:
          TargetOriginId: WebSiteOrigin
          AllowedMethods: [GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE]
          OriginRequestPolicyId: !Ref DefaultOriginRequestPolicyId
          CachePolicyId: !Ref DefaultCachePolicyId
          ViewerProtocolPolicy: allow-all
        Enabled: true
        Origins:
          - DomainName: !Ref EndpointName
            Id: WebSiteOrigin
            CustomOriginConfig:
              OriginProtocolPolicy: 'http-only'
              OriginKeepaliveTimeout: 60
            OriginCustomHeaders:
              - HeaderName: "X-Forwarded-SSL"
                HeaderValue: "on"

Outputs:
  CloudFrontEndpoint:
    Description: address for the cloudfront
    Value: !GetAtt Distribution.DomainName

```