How to POST to url to download content

I’m trying to emulate using ROOT something a colleague has written in MATLAB. There is an sql db behind a firewall that we need to access through a php interface (I found out after wasting a lot of time trying to connect). The MATLAB code is as simple as:

I’m struggling as I look through tutorials, scavenge Root Talk, and scour Google to find a method that can do the same in ROOT. I ended up finding the ReadRemote method define in ($ROOTSYS)/test/rhtml/rhtml.cxx that might get me there. I was surprised to see a web browser built in ROOT, but that tells me that it can be done!

[code]static char *ReadRemote(const char *url)
{
// Read (open) remote files.

static char *buf = 0;
TUrl fUrl(url);

TString msg = "GET ";
msg += fUrl.GetProtocol();
msg += “://”;
msg += fUrl.GetHost();
msg += “:”;
msg += fUrl.GetPort();
msg += “/”;
msg += fUrl.GetFile();
msg += “\r\n”;

TString uri(url);
if (!uri.BeginsWith(“http://”))
return 0;
TSocket s(fUrl.GetHost(), fUrl.GetPort());
if (!s.IsValid())
return 0;
if (s.SendRaw(msg.Data(), msg.Length()) == -1)
return 0;
Int_t size = 1024*1024;
buf = (char *)calloc(size, sizeof(char));
if (s.RecvRaw(buf, size) == -1) {
free(buf);
return 0;
}
return buf;
[/code]

Is there a simpler way that I am completely missing? Can the methods in rhtml.cxx get me there? Thanks a lot for your help.

Ignore this box. Posted below.

I’m still trying to interface with a php frontend for a mysql database in ROOT. To start off with, I tried to get this php interface to play nice with wget and curl first because I’m more familiar with them. The following command works:

The results are:

[code] database1

database2[/code]

That’s good. If I leave out the --post-data then I get the result:

[code]Warning: mysql_connect() [function.mysql-connect]: Access denied for user 'admin'@'localhost' (using password: NO) in /log/log_query_matlab.php on line 6
i'm dead! Access denied for user 'admin'@'localhost' (using password: NO) 
Warning: mysql_query() [function.mysql-query]: Access denied for user 'admin'@'localhost' (using password: NO) in /log/log_query_matlab.php on line 29

Warning: mysql_query() [function.mysql-query]: A link to the server could not be established in /log/log_query_matlab.php on line 29[/code]

I have access to the php script (read only), but the error itself isn’t too important. What matters it that using ROOT, I use the function called as socket.SendRaw(message, message.Length()) (socket is a TSocket and this was found in rhtml) and this gives me the same “error” as wget without the post data switch if my “message” is

This may be in vain, but does someone knows a way I should format the “message” that includes something that is equivalent to the --post-data switch. Or, is there a standard way to format POST requests in a single line (I’ve seen multi-line stuff (jmarshall.com/easy/http/#postmethod). Is that right?) Sorry I’m clueless!

PS. The mysql query is show databases but the space has been replaced with spazio, Italian for space. The author of the db and php interface requires it (and various replacements for symbols), but has anyone seen this before? Trying to troubleshoot that was terrible!

Hi,

try the following as POST message:

   cont char *postdata = "hostname=localhost:3306&un=joeuser&pw=psswd&myquery=show_spazio_databases;";

   TString msg = "POST "; 
   msg += fUrl.GetProtocol(); 
   msg += "://"; 
   msg += fUrl.GetHost(); 
   msg += ":"; 
   msg += fUrl.GetPort(); 
   msg += "/"; 
   msg += fUrl.GetFile(); 
   msg += " HTTP/1.1";
   msg += "\r\n";
   msg += "Host: ";
   msg += fUrl.GetHost();
   msg += "\r\n";
   msg += "Content-Type: application/x-www-form-urlencoded";
   msg += "\r\n";
   msg += "Content-Length: ";
   msg += strlen(postdata);
   msg += "\r\n\r\n";
   msg += postdata;
   msg += "\r\n";

I’ll try to add a generic URL read method to TWebFile so this can be done with all proper error checking, authentication, proxy, etc.

Cheers, Fons.

Thank you Fons! I tested your msg and the response back was

[code]HTTP/1.1 200 OK
Date: Thu, 08 Apr 2010 19:59:46 GMT
Server: Apache/1.3.41 (Darwin) mod_jk/1.2.6 DAV/1.0.3 mod_ssl/2.8.31 OpenSSL/0.9.7l PHP/5.2.3 mod_perl/1.29
Cache-Control: max-age=60
Expires: Thu, 08 Apr 2010 20:00:46 GMT
X-Powered-By: PHP/5.2.3
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

c
lug

test

0

[/code]

The databases available are lug and test, so there’s a lot of parsing to be done, but it most definitely worked! I wasn’t specifying the Host twice, and I was missing some \r\n. Great thanks.

Is there, by chance, an easy way you would know of to parse out the header that is sent back and leave only the query results?