Веб-сервер Rook анализирует содержимое постполей в имени списка

Я хочу отправить xml Строка к моему Rook веб сервер. Но когда я использую POST метод Rook::Request класс для разбора POST Полезная нагрузка моего запроса, он помещает содержимое в имя возвращаемого списка. Соответствующее значение списка NA, я использую postForm и postfields вариант RCurl пакет для создания моих запросов. Более подробный пример приведен ниже:

Поместите это в файл webserver.R

library(Rook)

s <- Rhttpd$new()

#set up web server app
s$add(
  name="xml_example",
  app=function(env) {
    req <- Request$new(env)

    #parse POST request
    tmp=req$POST()

    #create response
    res <- Rook::Response$new()

    #use dput and capture.output to return text of tmp
    res$write(capture.output(dput(tmp)))
    res$finish()
  }
)

#start web server on port 9000
s$start(port=9000)
#we will start the web server via Rscript and NOT via RStudio
Sys.sleep(.Machine$integer.max)

Следующее может быть выполнено через RStudio (пользователю Windows может потребоваться изменить некоторые команды)

library(RCurl)

#start web server outside of RStudio! Do not forget to kill it later
system("Rscript webserver.R &")

#send POST request
postForm("http://127.0.0.1:9000/custom/xml_example",
         .opts=list(postfields="<request>test</request>",
                    httpheader=c("content-type"="application/xml")))

Это возвращает

#[1] "structure(list(`<request>test</request>` = NA),
#                    .Names = \"<request>test</request>\")"

Как видите, xml Строка помещается в имя списка. Не совсем то, что я ожидал. Помимо извлечения имени списка, чтобы получить xmlКак это можно сделать правильно? Нужно ли устанавливать параметры в Rook или же RCurl?

КСТАТИ:

#do not forget to kill the webserver
system("ps aux|grep webserver.R")
#system("kill yourPIDhere")

1 ответ

Решение

Это оказалось ошибкой / функцией разбора внутри Rook, Возьмите например почтовый запрос

postForm("http://127.0.0.1:9000/custom/xml_example",
         .opts=list(postfields="xml=<request>test</request>",
                    httpheader=c("content-type"="application/xml")))

Это дает результат

#[1] "structure(list(xml = \"<request>test</request>\"), .Names = \"xml\")"

Как видите, Rook синтаксический анализатор предполагает какой-то key=value структура ввода. Это проблематично для xmlс, так как они могут включать определения пространства имен, которые используют = знак (также при определении xml версии и, вероятно, в других случаях).

Во всяком случае, я отвернулся от Rook поскольку это может быть сделано доступным для удаленных машин только с помощью некоторого хака (см. http://jeffreyhorner.tumblr.com/post/33814488298/deploy-rook-apps-part-ii). Этот взлом, кстати, не работает для меня. Я использую plumber пакет сейчас - работает как шарм! ( https://github.com/trestletech/plumber)

Другие вопросы по тегам