2012-02-28 15 views
2

私は、単にトークンをPOSTバックする自動サブスクリプションAPIを構築しようとしています。私はSinatraでこれを非常に簡単に行うことができます(POSTされたJSONをAWSからレンダリングする) - Expressでは苦労しているようです。私は1000Xの組み合わせを試しましたが、それはちょうど私が行方不明だと思っています。AWS SNS webserviceサブスクリプション - 明示的な問題、sinatraの例

# application.rb 

require 'rubygems' 
require 'sinatra' 
require 'json' 

set :port, 8081 

post '/webservice/cloudwatch' do 
    content_type :json 
    puts "Body: " + request.body.read 
end 

記録します:ここで

- -> /webservice/cloudwatch 
Body: { 
    "Type" : "SubscriptionConfirmation", 
    "MessageId" : "OMIT", 
    "Token" : "OMIT", 
    "TopicArn" : "OMIT", 
    "Message" : "OMIT", 
    "SubscribeURL" : "OMIT", 
    "Timestamp" : "2012-02-28T21:28:02.082Z", 
    "SignatureVersion" : "1", 
    "Signature" : "OMIT", 
    "SigningCertURL" : "OMIT" 
} 

をExpressのWebサーバである:

var express, app, stache; 
express = require("express"), app = express.createServer(); 
app.configure(function() { 
    app.use(express.methodOverride()); 
    app.use(express.bodyParser()); 
    app.use(app.router); 
    app.set("view options", { 
    layout: false 
    }); 
    app.use(express.errorHandler({ 
    dumpExceptions: true, 
    showStack: true 
    })); 
}); 
app.post("/webservice/cloudwatch", function (request, response) { 
    request.accepts('application/json'); 
    console.log("post body: " + JSON.stringify(request.params)); 
    console.log("post body: " + JSON.stringify(request.body.read)); 
}); 
app.listen(8081); 

ログに記録します。

post body: [] 
post body: undefined 
をここで

はシナトラのWebサーバであります

助けてください!

+0

代わりのrequest.body.read' 'に' console.log'をやっrequest.body' 'に' console.dir'をやってみてください:へ

var rawbody = function(req, res, next) { var data = ''; req.setEncoding('utf8'); req.on('data', function(chunk) { data += chunk; }); req.on('end', function() { req.rawBody = data; next(); }); }; app.use(rawbody); app.use(express.bodyParser()); 

おかげでログインrequest.rawbodyをお試しくださいそれに含まれる属性を確認してください。 – Marshall

+0

console.dir(request.body);このログ{} –

+0

console.dir(request.body.read);このログは未定義です –

答えて

2

ウェブサービスのテストにはどのリクエストを使用していますか?こう:

curl -H "Content-Type: application/json" -d '{"Type":"SubscriptionConfirmation","MessageId":"OMIT","Token":"OMIT","TopicArn":"OMIT","Message":"OMIT","SubscribeURL":"OMIT","Timestamp":"2012-02-28T21:28:02.082Z","SignatureVersion":"1","Signature":"OMIT","SigningCertURL":"OMIT"}' http://localhost:8081/webservice/cloudwatch 

(アプリケーション/ JSONに設定されているコンテンツタイプに気づく)とあなたのconsole.logconsole.log(request.body);にを変更すると、あなたに期待される結果を与える必要があります。 bodyParserメソッドは、request.bodyを正しく設定するためにcontent-typeを知る必要があります。

2

amazonがエンドポイントにhttp投稿要求を送信するとき、コンテンツタイプは指定されません。これは、その回答に基づいて、既知の問題です。

一方、私がテストしてきた非常にハックリな回避策があります。 expressプラグインのbodyParser.jsファイルを変更しました。具体的には、必要に応じてコンテンツタイプがapplication/jsonであることを強制することができるように、mime関数にifチェックを追加しました。ここで

は修正MIME機能である:

function mime(req) { 
    if(req.headers['x-amz-sns-message-type'] == 'SubscriptionConfirmation' && !req.headers.hasOwnProperty['content-type']) { 
     req.headers['content-type'] = 'application/json'; 
    } 

    var str = req.headers['content-type'] || ''; 
    return str.split(';')[0]; 
} 
0

は、あなたの特急サーバーに以下を追加します(bodyParserがrawbody後に来ることを確認してください)。 Expressjs raw body

関連する問題