Подписка на веб-сервис AWS SNS - экспресс-выпуск, пример sinatra - PullRequest
2 голосов
/ 29 февраля 2012

Я просто пытаюсь создать API автоматической подписки, который отправляет токен обратно.Я могу сделать это очень легко в Sinatra (рендеринг POSTed JSON из AWS) - похоже, у него были трудности в Express;Я уверен, что это просто глупость, которую я пропускаю, хотя я пробовал 1000X комбинаций.

Вот веб-сервер 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:

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

Пожалуйста, помогите!

Ответы [ 3 ]

2 голосов
/ 25 мая 2012

Когда amazon отправляет запрос http post вашей конечной точке, он не указывает тип контента.Это известная проблема для них, основанная на их ответах.

Тем временем есть очень хакерский обходной путь, который я тестировал.Я изменил файл bodyParser.js в экспресс-плагине.В частности, я добавил проверку if в функцию mime, чтобы заставить ее притворяться, что при необходимости тип содержимого application/json.

Вот модифицированная функция 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];
}
2 голосов
/ 09 марта 2012

Какой запрос вы используете для проверки вашего веб-сервиса?Выполнение:

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

(обратите внимание на тип контента, установленный на application / json) и изменение значения console.log на console.log(request.body); должно дать ожидаемые результаты.Метод bodyParser должен знать тип содержимого, чтобы правильно заполнить request.body.

0 голосов
/ 17 января 2014

Добавьте следующее на ваш экспресс-сервер (убедитесь, что bodyParser идет после rawbody).Попробуйте зарегистрировать request.rawbody

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());

Благодаря: Expressjs raw body

...