2012-12-10 5 views
0

J'ai le code Sinatra suivant:Mystère dans Ruby sinatra

post '/bucket' do 
    # determine if this call is coming from filling out web form 
    is_html = request.content_type.to_s.downcase.eql?('application/x-www-form-urlencoded') 

    # If this is a curl call, then get the params differently 
    unless is_html 
     params = JSON.parse(request.env["rack.input"].read) 
    end 

    p params[:name] 
end 

Si j'appelle cela en utilisant Curl, params a des valeurs, mais quand on l'appelle via un formulaire Web, puis params est nil et params[:name] n'a rien . J'ai passé plusieurs heures à comprendre pourquoi cela arrivait et à demander de l'aide à d'autres personnes, mais personne ne pouvait vraiment savoir ce qui se passait.

Une chose à noter est, si je commente cette ligne:

params = JSON.parse(request.env["rack.input"].read) 

alors params a la valeur correcte pour l'affichage « formulaire web ».

En fait, le but est d'obtenir la valeur params si ce code est appelé par appel CURL, donc j'utilisé:

params = JSON.parse(request.env["rack.input"].read) 

mais il foiré l'affichage formulaire web. Quelqu'un peut-il résoudre ce mystère?

+0

Il est possible que ce ne soit pas un cas de forme Curl vs. page Web, mais plutôt un cas de 'application/x-www-form-urlencoded' vs.' multipart/form-data'. – L2G

+0

Le 'content_type' pour une requête Curl' POST', et la requête d'un navigateur utilisant le formulaire, est 'application/x-www-form-urlencoded'. –

Répondre

2

Personnellement, je le ferais différemment, en définissant une valeur cachée sous la forme, quelque chose comme:

<input type="hidden" name="webform" value="true"> 

utiliser ensuite comme:

if (params['webform']) 
    # this is a request from the form 
else 
    # this is a request from Curl 
end 

Si vous le voyez, vous savez la demande provenait de votre formulaire Web. Si params['webform'] n'existe pas, cela ne vient pas de Curl.

J'ai sauvé à un fichier et il a couru avec Ruby:

require 'sinatra' 

get '/bucket' do 
    params[:name] 
end 

Appeler le script en cours d'exécution à l'aide http://localhost:4567/bucket?name=foo affiche:

foo 

dans le navigateur.

Si je modifie la source comme:

require 'sinatra' 

post '/bucket' do 
    params[:name] 
end 

redémarrer et charger un fichier HTML simple:

<html> 
    <body> 
    <form name="form" method="post" action="http://localhost:4567/bucket"> 
     <input type="hidden" name="webform" value="true"></input> 
     <input type="input" name="name"></input> 
     <input type="submit"></input> 
    </form> 
    </body> 
</html> 

et entrée foobar et le soumettre, je vois:

foobar 

dans la fenêtre du navigateur

Si je change le script:

require 'sinatra' 

post '/bucket' do 
    if (params[:webform]) 
    'webform is set' 
    else 
    'webform is not set' 
    end 
end 

et redémarrez Sinatra et soumettre à nouveau la forme, je vois:

webform is set 

Si je l'appelle à l'aide Curl:

curl --data "name=foo" http://127.0.0.1:4567/bucket 

Je vois cela sur la ligne de commande en tant que réponse de Curl:

webform is not set 

Si je change le script:

require 'sinatra' 

post '/bucket' do 
    if (params[:webform]) 
    'webform is set' 
    else 
    params[:name] 
    end 
end 

redémarrer le script, et l'appeler avec la commande Curl à nouveau, je vois:

foo 

sur la ligne de commande.

+0

Merci Tin Man, je suppose que vous avez mal compris la question. Déterminer d'où vient l'appel n'est pas le problème. Il s'agit d'obtenir des params dans les deux cas. – JVK

+0

Je n'ai pas mal compris la question du tout. Je comprends mal pourquoi vous faites le long chemin pour déterminer la source de votre demande. Je n'ai jamais eu de problème pour obtenir des 'params', donc vous devez montrer plus de code que vous utilisez pour configurer votre formulaire et votre DSL. –

+0

Tin man, avez-vous essayé d'appeler le même fichier par CURL et dans l'autre partie essayer params d'impression [: nom] – JVK