質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Amazon CloudFront

Amazon CloudFrontは、AWSの高速且つ高パフォーマンスなコンテンツ配信(CDN) サービス。容量の大きいコンテンツをキャッシュさせてWebサーバの負荷を軽減し、サーバダウンの防止など安定した配信が可能になります。

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

HTTPヘッダー

Hypertext Transfer Protocol(HTTP)の中のHTTPヘッダフィールドはHTTPの要求やレスポンスの機能しているパラメーターが含まれます。その要求もしくはレスポンスライン(メッセージの最初の一行)でメッセージヘッダを作ります。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

1430閲覧

Lambdaプロキシ統合にてダウンロードしたPDFが壊れてしまう

plasticgrammer

総合スコア629

Amazon CloudFront

Amazon CloudFrontは、AWSの高速且つ高パフォーマンスなコンテンツ配信(CDN) サービス。容量の大きいコンテンツをキャッシュさせてWebサーバの負荷を軽減し、サーバダウンの防止など安定した配信が可能になります。

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

HTTPヘッダー

Hypertext Transfer Protocol(HTTP)の中のHTTPヘッダフィールドはHTTPの要求やレスポンスの機能しているパラメーターが含まれます。その要求もしくはレスポンスライン(メッセージの最初の一行)でメッセージヘッダを作ります。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

0クリップ

投稿2022/08/29 06:21

編集2022/09/05 08:46

前提

AWSのAPIGatewary+Lambdaを使用してPDFファイルのダウンロード機能を実装しています。

  • APIGatewaryとLambdaは、Lambdaプロキシ統合にて連携
  • APIGatewayの設定にある「バイナリメディアタイプ」に application/pdf を追加
  • CloudFrontを使用

発生している問題・エラーメッセージ

クライアントのWebシステムから対象APIGatewayのURLにてダウンロードを実行した際、作成されるPDFファイルが壊れていると言われ開けません。

APIGatewayの設定にある「バイナリメディアタイプ」を */* とすることで、正常なダウンロードとなることは確認できました。
但し、これだと他APIで行っているJSON受信がおかしくなってしまうので問題があります。

<追記>
CloudFrontを経由しなければ、問題は発生しませんでした。

該当のソースコード

javascript

1 2exports.handler = async (event) => { 3 try { 4 const contentType = "application/pdf" 5 const buffer = "<ここにはPuppeteerでPDFを作成した結果の文字列が設定される>" 6 7 const base64 = buffer.toString("base64") 8 return { 9 "statusCode": 200, 10 "headers":{ 11 "Access-Control-Allow-Origin": "*", 12 "Access-Control-Expose-Headers" : "Content-Disposition", 13 "Content-Length": Buffer.byteLength(base64), 14 "Content-Type": contentType, 15 "Content-Disposition": "attachment; filename=download.pdf" 16 }, 17 "isBase64Encoded": true, 18 "body": base64 19 } 20 21 } catch (error) { 22 console.log(error) 23 throw error 24 25 } 26 27}

試したこと

  • 前述の通り「バイナリメディアタイプ」を */* とすることで、正常なダウンロードができた
  • Lambda側の「Content-type」とAPIGatewayの「バイナリメディアタイプ」を application/octet-stream としたがダメだった
  • CloudFrontのビヘイビア設定にて、ダウンロードのURLについてのみ設定を色々変えてみたが上手くいく設定をみつけられなかった

解決したいこと

指定したメディアタイプ(PDF)のみ上手く処理されるようにしたいのですが、原因と対策がわからず困っております。

<追記>
CloudFrontの設定で何か不足・対策が必要なのかもしれません。
何かご存知の方はコメントください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

以下の二つを実施して解決しますか?

  1. クライアントからAPI Gatewayをリクエストする時、リクエストヘッダーにAccept:application/pdfを指定

  2. API Gatewayの該当のPathに以下の設定を入れる

・HTTPのステータスを追加
・200のレスポンス本文→コンテンツタイプを以下に設定
application/pdf

投稿2022/08/29 12:20

編集2022/08/29 12:21
tamanegine

総合スコア177

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

plasticgrammer

2022/08/30 07:44

回答ありがとうございます。 レスポンスのコンテンツタイプを指定する際に『モデル』を選択する必要があるようなのですが、どのようなモデルを作成しておけば良いのかわかりますでしょうか。
plasticgrammer

2022/08/30 07:47

追記です。 リクエストヘッダーへのAccept:application/pdfの追加だけではうまくいきませんでした。
tamanegine

2022/08/30 08:09

モデルに関してはemptyを選択して見てください
plasticgrammer

2022/08/30 09:21

試してみましたが、同様にpdfが壊れているエラーとなってしまいました。 APIのデプロイも忘れずにできていると思います。
plasticgrammer

2022/09/02 18:36

質問へ条件を追加しました。 CloudFrontの設定で何か不足・対策が必要なのかもしれません。 何か想定される原因がありましたらコメントください。
tamanegine

2022/09/04 06:52

すみません返信が遅くなりました API Gatewayの前にCloudfrontを挟んでいる状態でしょうか? その場合リクエストヘッダーのAcceptをOriginに転送するかCloudfrontがヘッダーをセットしてoriginに転送するようにしていますか? また念の為ですが、Lambdaのペイロードサイズが6MBまでですがPDFファイルはbase64にした状態で6MBを超えていないでしょうか? base64にするとおよそ133%容量が増加します https://developer.mozilla.org/ja/docs/Glossary/Base64
plasticgrammer

2022/09/08 05:07

回答を参考にCloudFrontにて「Legacy cache settings」の「ヘッダーを追加」にてAcceptを追加したところ、上手く動くようになりました。ご回答ありがとうございました。 何度か試行したなかで、すべてのヘッダーを許可するように 「Cache policy and origin request policy (recommended)」のほうで、「オリジンリクエストポリシー」にAllViewer を設定してもダメでした。 これは理解が間違っているのか、上手くいくはずなのかどちらなのでしょうか。 こちらについても何か情報がありましたらコメント頂けると助かります。
tamanegine

2022/09/09 00:20

無事上手く行って良かったです。 > 「Cache policy and origin request policy (recommended)」のほうで、「オリジンリクエストポリシー」にAllViewer を設定 こちらで動くかと思いますが ・キャッシュポリシーにより、オリジンに転送されずキャッシュに残っている壊れたレスポンスを返した ・Cloudfrontの設定反映が終わっていないときに確認した(およそ5分かかります) が考えられると思います
plasticgrammer

2022/09/09 04:56

コメントありがとうございました。 追加で調べていくと、オリジンリクエストポリシーではAuthorizeは転送されないという記載がありました。 確かに「Cache policy and origin request policy (recommended)」だと、壊れているというよりはリクエストを受け付けない挙動だったように思えます。 ここら辺をもう一度理解し直して、チャレンジしてみます。サポートありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問