💎

Ruby で URI と Addressable::URI は必ず片方だけ使用するルールがいい

に公開

始めに

Rubyでウェブ開発をしているとURLを扱う場面が必ず出てきます。URLを扱う際には標準ライブラリのURIクラスと、Addressable::URIという標準ライブラリでは満たせなかった仕様を満たすためのgemが存在します。このURIクラスとAddressable::URIを混ぜて使用するとエラーになるケースがあるのでAddressable::URIが依存関係に含まれている場合、CodeRabbitやGitHub Copilot等のAIコードレビューのルールに追加することで、プロジェクトでは混在しないルールで運用しましょう。

この記事で伝えたかった内容は以上です。以下はURIAddressable::URIの違いを記載します。

環境

  • Ruby
    • 3.3.5
  • Addressable
    • 2.8.7

まとめ

  • URIRFC3986準拠
  • Addressable::URIRFC3986RFC3987RFC6570に準拠
  • URIのほうがメモリ消費やURLのパース速度が早いらしい

URIとAddressable::URI

URI

RFC3986に準拠しています。

ASCII文字のみ対応しているため、日本語等がURLに含まれているとエラーになります。その他にも、次のような文字が含まれているとエラーになります。

  • Unicode文字
    • 日本語
  • 特殊文字
    • 角括弧[]
    • 商標記号™

今回、この内容でブログを書こうと思ったのは、次のファイルアップロードをする際にURIで検証したらparseできずにエラーになったことが原因でした。

edit[1].png

また、シンプルな分、メモリ消費やURLのパース速度が早い特徴があるようです(未検証)。

Addressable::URI

RFC3986RFC3987RFC6570に準拠しています。
  
一般的に使用されるURLの仕様を満たしています。

RFCの簡潔な内容は次の通りです

  • RFC3986
    • URIの基本的な構文と構成要素を定義した仕様
  • RFC3987
    • 非ASCII文字(Unicode文字)をURIに含める方法を定義した仕様
  • RFC6570
    • URIテンプレート(変数を含むURI)の構文と処理ルールを定義した仕様

ソースコード

なし

終わりに

セキュリティのためパストラバーサル攻撃等を防ぐためにバリデーションを加えるようにしましたが、その時にURIクラスを使用していたせいで不要なバリデーションがかかってしまっていました。特にレビュー時にはURLのチェックルールだけ気にしていて、parse部分に関しては自前実装せずにライブラリを経由していたので疑問を持っていませんでした。

今となってはURIAddressable::URIを混在しないようにするルールはAIレビューで事前にチェックできるようになって、非常に便利な世の中になったことを感じます。

Discussion