Я пишу слушатель для обработки сообщений и ответов IPN Paypal.Paypal IPN и интеграция Golang на GAE
Из требования IPN от Paypal слушатель должен опубликовать значения, полученные от Paypal, в том же порядке с новым параметром «cmd = _notify-validate», вставленным в начало списка значений.
Ваш HTTP-прослушиватель HTTP отправляет полное, неизмененное сообщение обратно в PayPal. Примечание: Это сообщение должно содержать те же поля, в том же порядке, что и исходный IPN из PayPal, которому предшествует cmd = _notify-validate. Кроме того, это сообщение должно использовать ту же кодировку, что и оригинал.
Однако переменная Go url.Values реализована в структуре данных карты, порядок выполнения которой не гарантируется при повторении каждого раза.
... Когда итерация над картой с петлей диапазона, порядок итерации не указан и не гарантируется быть одинаковым от одной итерации к следующей»
И когда url.Values закодирован метод вызывается, он будет отсортирован по ключевому
Encode кодирует значения в «URL» закодированы форме ("бар = baz & foo = quux ") отсортировано по ключевым словам.
Слушатель работает на GAE, таким образом, я использую "AppEngine/UrlFetch" 'ы функцию PostForm, которая принимает url.Values в качестве второго параметра
c := appengine.NewContext(r)
client := urlfetch.Client(c)
resp, err := client.PostForm("https://www.sandbox.paypal.com/cgi-bin/webscr", r.Form)
В url.Values является карта, порядок значений на карте не гарантируется. Как я могу передать значения параметров обратно в том же порядке, который получен от Paypal IPN, обратно в Paypal с помощью службы urlfetch GAE?
Это работает, но после io.Copy (& ЬиЙ, r.Body) линия, я попытался запустить r.ParseForm(). У меня не было ошибки, так как у меня есть обработчик ошибок. Тем не менее, я не получил никакой ценности в r.Form. Кажется, что io.Copy что-то сделал для r.Body? И я не могу запустить parseForm() до io.Copy (& buf, r.Body), потому что он каким-то образом изменил тело. Есть ли у вас какие-либо идеи? – Ook
Или мне нужно скопировать r.Body по значению для запуска io.Copy (& buf, r.Body) отдельно? – Ook
Да, извините, что использование тела 'io.Copy' сделает его недоступным для' ParseForm'. (и наоборот). Вы можете заменить тело «TeeReader»: http://golang.org/pkg/io/#TeeReader. Поэтому вместо 'io.Copy', сделайте' r.Body = io.TeeReader (r.Body, & buf) ', а затем вызовите:' r.ParseForm() '. – Caleb