1

Ruby on Rails アプリケーションから YouTube のビデオを削除しようとしています。YouTube API docs の次の手順に従っています。

DELETE /feeds/api/users/default/uploads/VIDEO_ID HTTP/1.1
Host: gdata.youtube.com
Content-Type: application/atom+xml
Authorization: Bearer ACCESS_TOKEN
GData-Version: 2
X-GData-Key: key=DEVELOPER_KEY

RubyのNet::HTTPクラスに詳しくないのですが、どうやってもリクエストがうまくいかないようです。YouTube から動画を削除することに関する他の多くの StackOverflow の質問を注意深く調べましたが、この特定の問題に対処するものは見つかりませんでした。ユーザー名、動画 ID、アクセス トークン、開発者キーを置き換えたコードを以下に示します。

url = URI.parse("https://gdata.youtube.com/feeds/api/users/[USER_NAME]/uploads/[VIDEO_ID]")
post_args = { 'Host' => 'gdata.youtube.com', 'GData-Version' => '2', 'Content-Type' => 'application/atom+xml', 'Authorization' => "Bearer [ACCESS_TOKEN]", 'X-GData-Key' => 'key=[DEVELOPER_KEY]' }
req = Net::HTTP::Delete.new(url.path)
req.set_form_data(post_args)

httpreq = Net::HTTP.new(url.host, url.port)
httpreq.use_ssl = true

resp = httpreq.start {|http| http.request(req) }

応答を確認すると、YouTube からエラー 400 (Bad Request) が返されます。応答は、単に「あなたのクライアントは不正な形式または違法な要求を発行しました。それが私たちが知っているすべてです」と言っています。

私が行っている要求に何か問題がありますか? テンプレートと何度も照合しましたが、問題はありません。動画のアップロードなどの他のリクエストを問題なく行うことができるため、アクセス トークンと開発者キーが機能していることはわかっています。

HTTP リクエストからのデバッグ出力を出力しました。

<- "DELETE /feeds/api/users/[USER_NAME]/uploads/[VIDEO_ID] HTTP/1.1\r\nAccept: */*\r\nUser-Agent: Ruby\r\nContent-Type: application/x-www-form-urlencoded\r\nHost: gdata.youtube.com\r\nContent-Length: 275\r\n\r\n"
<- "Host=gdata.youtube.com&GData-Version=2&Content-Type=application%2Fatom%2Bxml&Authorization=Bearer+[ACCESS_TOKEN]&X-GData-Key=key%3D[DEVELOPER_KEY]"

考えられる問題として唯一確認できたのは、リクエストの最初の行で、「Content-Type」が「application/x-www-form-urlencoded」に設定されていることです。繰り返しますが、HTTP リクエストの専門家ではないので、最初の行で設定された Content-Type と、2 行目に表示される "application/atom+xml" として明示的に設定された Content-Type の違いがわかりません。リクエストの行。ただし、掘り下げた後、set_form_dataメソッドがコンテンツタイプを自動的に「application/x-www-form-urlencoded」に設定することがわかったので、コードに次の行を追加してみました。

req.content_type = 'application/atom+xml'

行の直後

req.set_form_data(post_args)

これを行うと、リクエストに対応する変更が表示されます。

<- "DELETE /feeds/api/users/[USER_ID]/uploads/[VIDEO_ID] HTTP/1.1\r\nAccept: */*\r\nUser-Agent: Ruby\r\nContent-Type: application/atom+xml\r\nHost: gdata.youtube.com\r\nContent-Length: 275\r\n\r\n"
<- "Host=gdata.youtube.com&GData-Version=2&Content-Type=application%2Fatom%2Bxml&Authorization=Bearer+[ACCESS_TOKEN]&X-GData-Key=key%3D[DEVELOPER_KEY]"

ただし、YouTube からはまったく同じ応答が得られます。エラー 400、不正な要求です。ここで一体何が起こっているのですか??

4

1 に答える 1

0

もちろん、質問してから 10 分後に答えがわかりました。HTTP ヘッダー フィールドとフォーム引数の違いがわかりませんでしたが、Ruby のドキュメントNet::HTTPや YouTube API のどこにも説明されていないので、それほど悪いとは思いません。私が混乱した理由は、ビデオをアップロードするために、Authorization や Content-Type などのすべての値をフォーム データとして提供できるため、私の質問からの上記のアプローチがうまく機能するためです。ビデオを削除するには、これらの値をフォーム データではなく、ヘッダーの一部として提供する必要があります。少なくとも、それが今の私の理解です。

とにかく、誰かがこの問題に遭遇した場合に備えて、これで解決しました:

req = Net::HTTP::Delete.new(url.path)
req['GData-Version'] = '2'       # this syntax sets header fields & values
req['Authorization'] = "..."
req['X-GData-Key'] = "..."

req.content_type = 'application/atom+xml'

httpreq = Net::HTTP.new(url.host, url.port)
httpreq.use_ssl = true

resp = httpreq.start {|http| http.request(req) }

ドキュメントの作成者からの 1 つの説明文で 2 時間の無駄な時間を節約できた別のケース。ニッケルがあれば…

于 2013-02-27T20:28:11.620 に答える