# Constructing an (xml) request properly for http post to an api

**URL:** <https://rubytalk.org/t/constructing-an-xml-request-properly-for-http-post-to-an-api/42593>\
**Category:** ruby-talk\
**Created:** [29 November 2007 01:15 UTC](https://rubytalk.org/t/constructing-an-xml-request-properly-for-http-post-to-an-api/42593 "2007-11-29T01:15:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![scootiePuff](https://avatars.discourse-cdn.com/v4/letter/s/e9bcb4/32.png) [@scootiePuff](https://rubytalk.org/u/scootiePuff)\
**Post date:** [29 November 2007 01:15 UTC](https://rubytalk.org/t/constructing-an-xml-request-properly-for-http-post-to-an-api/42593/1 "2007-11-29T01:15:53Z")

</div>

hello,

goal: send a request that includes xml syntax via http post to  
emaillabs' api  
problem: would like help in constructing the (xml) request properly

if one scrolls to the bottom of the emaillabs api overview  
documentation here ([http://www.emaillabs.com/email-marketing/api-](http://www.emaillabs.com/email-marketing/api-)  
faq.html) under 'What is an example of an API command?',

notice the 'type' and 'activity' parameters. these, along with the  
'input' parameter which is the xml 'input from customer' from  
\<dataset\>.. through \</dataset\>, are required according to the api  
reference guide.

i'm using the net/http toolkit to try to post the request to emaillabs  
so that i might receive some xml response back.

question: how would you incorporate the 'type: record', 'activity:  
query-data', and 'input: \<dataset\>...\</dataset\>' parameters all  
together in the (xml) request?

i tried to send everything together, but i suspect that this is not  
correct.  
in a ruby file, let's say i have the following:

#!/usr/bin/env ruby

require 'net/http'  
require 'rexml/document'  
include REXML

target\_url = '[http://www.uptilt.com](http://www.uptilt.com)'  
path = '/API/mailing\_list.html'

http = Net::HTTP.new(target\_url)

xml\_request =\<\<EOF  
Type:record  
Activity:query-data  
Input:  
\<? xml version='1.0' ?\>  
\<DATASET\>  
\<SITE\_ID\>123456789\</SITE\_ID\>  
\<MLID\>987654321\</MLID\>  
\<DATA type='email'\>[someuser@somedomain.com](mailto:someuser@somedomain.com)\</DATA\>  
\</DATASET\>  
EOF

xml\_response = http.post(path, xml\_request)

puts xml\_response.body

(the rexml is for me to parse the xml data once i am able to receive a  
response.)

i get the following when running the ruby file:

\<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"\>  
\<html\>\<head\>  
\<title\>400 Bad Request\</title\>  
\</head\>\<body\>  
\<h1\>Bad Request\</h1\>  
\<p\>Your browser sent a request that this server could not  
understand.\<br /\>  
\</p\>  
\</body\>\</html\>

.. so that i suspect my request isn't constructed properly. i've also  
tried using 'END' in lieu of 'EOF', and double quotes to hold the  
data, but i'm guessing that the type/activity/input are the problem.  
i've also tried to put them in xml tags, but that still produced the  
same 'response'. i've also ensured that the api security settings are  
set up properly, and that i'm contacting the correct url location  
(different from target\_url, path, and in the emaillabs api faq  
example).

how should my (xml) request be constructed? please advise.

---

<div class="post-metadata">

**Author:** ![Jeff](https://avatars.discourse-cdn.com/v4/letter/j/e19b73/32.png) [@Jeff](https://rubytalk.org/u/Jeff)\
**Post date:** [29 November 2007 04:20 UTC](https://rubytalk.org/t/constructing-an-xml-request-properly-for-http-post-to-an-api/42593/2 "2007-11-29T04:20:50Z")

</div>

I think you're creating the xml part ok, it's the previous section  
that should be different. Here's what we do:

# send email via emailLabs  
# the msg parameter is actually the XML fragment that should be sent  
def send\_email(msg, type, activity)  
&nbsp;&nbsp;req = "type=#{type}&activity=#{activity}&input="  
&nbsp;&nbsp;req = req + URI.escape(msg)  
&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;Net::HTTP.start('www.uptilt.com') do |query|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response = query.post("/API/mailing\_list.html", req)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@response = response.body  
&nbsp;&nbsp;&nbsp;end  
rescue  
&nbsp;&nbsp;&nbsp;&nbsp;@error = true  
&nbsp;&nbsp;&nbsp;&nbsp;@error\_msg = "Unable to connect to Email Labs."  
return false  
end

You don't need those @ variables of course, I'm just copying and  
pasting from our code, but hopefully it sheds some light. The main  
difference is we're constructing the first part differently, and  
making sure we escape the xml first.

Jeff  
softiesonrails.com  
essentialrails.com

> **···**
>
> On Nov 28, 7:15 pm, scootiePuff \<elle.on.ra...@gmail.com\> wrote:
> 
> > hello,
> > 
> > goal: send a request that includes xml syntax via http post to  
> > emaillabs' api  
> > problem: would like help in constructing the (xml) request properly

---

<div class="post-metadata">

**Author:** ![scootiePuff](https://avatars.discourse-cdn.com/v4/letter/s/e9bcb4/32.png) [@scootiePuff](https://rubytalk.org/u/scootiePuff)\
**Post date:** [4 December 2007 03:06 UTC](https://rubytalk.org/t/constructing-an-xml-request-properly-for-http-post-to-an-api/42593/3 "2007-12-04T03:06:41Z")

</div>

thanks for responding jeff, and for your feedback.

unfortunately, i kept encountering "syntax error, unexpected $end,  
expecting kEND"  
with variations of the send\_email code.

i tried the following instead, and i'm now able to receive an xml  
response:

#!/usr/bin/env ruby

require 'net/http'  
require 'uri'

type = 'record'  
activity = 'query-data'

xml\_req =\<\<EOF  
\<? xml version='1.0' ?\>  
\<DATASET\>  
\<SITE\_ID\>123456789\</SITE\_ID\>  
\<MLID\>987654321\</MLID\>  
\<DATA type='email'\>user@somedomain.com\</DATA\>  
\</DATASET\>  
EOF

req = "type=#{type}&activity=#{activity}&input="  
req = req + URI.escape(xml\_req)

res = Net::HTTP.start('www.uptilt.com') { |http|  
&nbsp;&nbsp;http.post("/API/mailing\_list.html", req)  
}  
puts res.body

(by the way, it is not an e-mail that i am attempting to send, but  
rather an e-mail address, in order that i might receive statistical  
information via xml that is tied to that e-mail address.)

> **···**
>
> On Nov 28, 8:20 pm, Jeff \<cohen.j...@gmail.com\> wrote:
> 
> > I think you're creating the xml part ok, it's the previous section  
> > that should be different. Here's what we do:
> > 
> > # send email via emailLabs  
> > # the msg parameter is actually the XML fragment that should be sent  
> > def send\_email(msg, type, activity)  
> > &nbsp;&nbsp;req = "type=#{type}&activity=#{activity}&input="  
> > &nbsp;&nbsp;req = req + URI.escape(msg)  
> > &nbsp;&nbsp;begin  
> > &nbsp;&nbsp;&nbsp;&nbsp;Net::HTTP.start('www.uptilt.com') do |query|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response = query.post("/API/mailing\_list.html", req)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@response = response.body  
> > &nbsp;&nbsp;&nbsp;end  
> > rescue  
> > &nbsp;&nbsp;&nbsp;&nbsp;@error = true  
> > &nbsp;&nbsp;&nbsp;&nbsp;@error\_msg = "Unable to connect to Email Labs."  
> > return false  
> > end

---

<div class="post-metadata">

**Author:** ![scootiePuff](https://avatars.discourse-cdn.com/v4/letter/s/e9bcb4/32.png) [@scootiePuff](https://rubytalk.org/u/scootiePuff)\
**Post date:** [4 December 2007 03:44 UTC](https://rubytalk.org/t/constructing-an-xml-request-properly-for-http-post-to-an-api/42593/4 "2007-12-04T03:44:56Z")

</div>

(was Re: constructing an (xml) request properly for http post to an  
api)

THE PROBLEM:  
the rexml tutorial here ([Germane-Software :: Software](http://www.germane-software.com/software/)  
rexml/docs/tutorial.html) suggests that Document.new expects a  
string. my xml\_response is of type Net::HTTPOK, not String. i see  
that i can not easily convert this into a string with  
String.new(xml\_response).

is there currently a (simple) way to convert the Net::HTTPOK object  
into a format (string) useable by REXML::Document, and if so, what  
might that be/what would you suggest?

if i am approaching this problem the wrong way, what might you advise?

SOME BACKGROUND:  
i am having trouble successfully running the rexml/document's .new  
method.

i have the following in my ruby script:

require 'rexml/document'  
include REXML  
.  
.  
.

(i successfully receive an xml response with a Net::HTTP.start call as  
viewable via irb here called 'xml\_response'..)

doc = Document.new(xml\_response)

i am presented with the following error messages:  
irb(main):017:0\> doc = REXML::Document.new(res)  
NameError: undefined local variable or method `source' for  
REXML::SourceFactory:Class  
&nbsp;&nbsp;from /usr/local/lib/ruby/site\_ruby/1.8/rexml/source.rb:20:in  
`create\_from'  
&nbsp;&nbsp;from /usr/local/lib/ruby/site\_ruby/1.8/rexml/parsers/baseparser.rb:  
130:in `stream='  
&nbsp;&nbsp;from /usr/local/lib/ruby/site\_ruby/1.8/rexml/parsers/baseparser.rb:  
107:in `initialize'  
&nbsp;&nbsp;from /usr/local/lib/ruby/site\_ruby/1.8/rexml/parsers/treeparser.rb:  
8:in `new'  
&nbsp;&nbsp;from /usr/local/lib/ruby/site\_ruby/1.8/rexml/parsers/treeparser.rb:  
8:in `initialize'  
&nbsp;&nbsp;from /usr/local/lib/ruby/site\_ruby/1.8/rexml/document.rb:190:in `new'  
&nbsp;&nbsp;from /usr/local/lib/ruby/site\_ruby/1.8/rexml/document.rb:190:in  
`build'  
&nbsp;&nbsp;from /usr/local/lib/ruby/site\_ruby/1.8/rexml/document.rb:45:in  
`initialize'  
&nbsp;&nbsp;from (irb):17:in `new'  
&nbsp;&nbsp;from (irb):17

i am imitating syntax from these posts:  
[http://tinyurl.com/3958n5](http://tinyurl.com/3958n5)  
[http://tinyurl.com/yo3mel](http://tinyurl.com/yo3mel)

the rexml tutorial here ([Germane-Software :: Software](http://www.germane-software.com/software/)  
rexml/docs/tutorial.html) suggests that Document.new expects a  
string. my xml\_response is of type Net::HTTPOK, not String. i see  
that i can not easily convert this into a string with  
String.new(xml\_response).

is there currently a (simple) way to convert the Net::HTTPOK object  
into a format (string) useable by REXML::Document, and if so, what  
might that be/what would you suggest?

if i am approaching this problem the wrong way, what might you advise?

how were the other posts ([http://tinyurl.com/3958n5](http://tinyurl.com/3958n5), [http://tinyurl.com/yo3mel\](http://tinyurl.com/yo3mel%5C))  
able to utilize REXML::Document immediately -- i suspect that their  
Net::HTTP .get and .new calls produced strings?

thank you for your time and help.

> **···**
>
> On Dec 3, 7:06 pm, scootiePuff \<elle.on.ra...@gmail.com\> wrote:
> 
> > thanks for responding jeff, and for your feedback.
> > 
> > unfortunately, i kept encountering "syntax error, unexpected $end,  
> > expecting kEND"  
> > with variations of the send\_email code.
> > 
> > i tried the following instead, and i'm now able to receive an xml  
> > response:
> > 
> > #!/usr/bin/env ruby
> > 
> > require 'net/http'  
> > require 'uri'
> > 
> > type = 'record'  
> > activity = 'query-data'
> > 
> > xml\_req =\<\<EOF  
> > \<? xml version='1.0' ?\>  
> > \<DATASET\>  
> > \<SITE\_ID\>123456789\</SITE\_ID\>  
> > \<MLID\>987654321\</MLID\>  
> > \<DATA type='email'\>u...@somedomain.com\</DATA\>  
> > \</DATASET\>  
> > EOF
> > 
> > req = "type=#{type}&activity=#{activity}&input="  
> > req = req + URI.escape(xml\_req)
> > 
> > res = Net::HTTP.start('www.uptilt.com') { |http|  
> > &nbsp;&nbsp;http.post("/API/mailing\_list.html", req)}
> > 
> > puts res.body
> > 
> > (by the way, it is not an e-mail that i am attempting to send, but  
> > rather an e-mail address, in order that i might receive statistical  
> > information via xml that is tied to that e-mail address.)
> > 
> > On Nov 28, 8:20 pm, Jeff \<cohen.j...@gmail.com\> wrote:
> > 
> > \> I think you're creating the xml part ok, it's the previous section  
> > \> that should be different. Here's what we do:
> > 
> > \> # send email via emailLabs  
> > \> # the msg parameter is actually the XML fragment that should be sent  
> > \> def send\_email(msg, type, activity)  
> > \> req = "type=#{type}&activity=#{activity}&input="  
> > \> req = req + URI.escape(msg)  
> > \> begin  
> > \> Net::HTTP.start('www.uptilt.com') do |query|  
> > \> response = query.post("/API/mailing\_list.html", req)  
> > \> @response = response.body  
> > \> end  
> > \> rescue  
> > \> @error = true  
> > \> @error\_msg = "Unable to connect to Email Labs."  
> > \> return false  
> > \> end
> 
> the initial post, in case is of interest:  
> [http://tinyurl.com/2g5pt8](http://tinyurl.com/2g5pt8)

---

<div class="post-metadata">

**Author:** ![Rilindo\_Foster1](https://avatars.discourse-cdn.com/v4/letter/r/8e8cbc/32.png) [@Rilindo\_Foster1](https://rubytalk.org/u/Rilindo_Foster1)\
**Post date:** [21 August 2009 19:47 UTC](https://rubytalk.org/t/constructing-an-xml-request-properly-for-http-post-to-an-api/42593/5 "2009-08-21T19:47:32Z")

</div>

scootiePuff wrote:

> (was Re: constructing an (xml) request properly for http post to an  
> api)
> 
> is there currently a (simple) way to convert the Net::HTTPOK object  
> into a format (string) useable by REXML::Document, and if so, what  
> might that be/what would you suggest?

Didn't see this ever answered, so for posterity's sake - Assuming that  
resp is Net::HTTPOK object:

doc = Document.new(resp.read\_body)  
doc.write( $stdout, 0 )

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).
