Quantcast
Channel: Processing Forum
Viewing all articles
Browse latest Browse all 1768

Re : xml retrieval

$
0
0
OK, after some reverse engineering, trial and error, and sweat, I got it working:
  1. import processing.net.*;
  2.  
  3. Client client;
  4. int step = 0;
  5.  
  6. void setup()
  7. {
  8.   size(200, 200);
  9.   frameRate(5);
  10.   step = 1;
  11. }
  12.  
  13. void draw()
  14. {
  15.   if (step > 0)
  16.   {
  17.     println("------ " + step);
  18.   }
  19.   switch (step)
  20.   {
  21.   case 1:
  22.     client = new Client(this, "www.teamliquid.net", 80);
  23.     client.write("GET /video/streams/?xml=1&filter=live HTTP/1.1\r\n");
  24.     client.write("Host: www.teamliquid.net\r\n");
  25. //    client.write("User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.7) Gecko/2009021906 Firefox/3.0.7\r\n");
  26.     client.write("Accept: text/html,application/xhtml+xml,application/xml\r\n");
  27.     client.write("Accept-Language: en-us,en;q=0.5\r\n");
  28.     client.write("Accept-Encoding: gzip\r\n");
  29.     client.write("Accept-Charset: utf-8;q=0.7,*;q=0.7\r\n");
  30. //    client.write("Keep-Alive: 300\r\n");
  31. //    client.write("Connection: keep-alive\r\n\r\n");
  32.     client.write("\r\n");
  33.     break;
  34.   case 2:
  35.     exit();
  36.   }
  37.   if (step > 0)
  38.   {
  39.     step = -++step; // Next step, and negative to stop treatment until an answer is received
  40.   }
  41.   if (step < 0 && client.available() > 0)
  42.   {
  43.     byte[] dataIn = client.readBytes();
  44.     String textData = new String(dataIn);
  45.     if (textData.contains("text/plain"))
  46.     {
  47.       println(textData); // Likely to be an error message (eg. if omitting to accept gzip data)
  48.     }
  49.     else
  50.     {
  51.       byte[] gzipData = null;
  52.       for (int i = 0; i < dataIn.length - 3; i++)
  53.       {
  54.  //       print(hex(dataIn[i]) + " ");
  55.         if (dataIn[i] == 0x0D && dataIn[i + 1] == 0x0A && dataIn[i + 2] == 0x0D && dataIn[i + 3] == 0x0A) // Start of POST data
  56.         {
  57.           println("Found");
  58.           int len = 0;
  59.           i += 4; // No check on bounds, don't do that in production code! :-)
  60.           while (dataIn[i] != 0x0D)
  61.           {
  62. //            println(i + " " + hex(dataIn[i]));
  63.             len = len * 16 + (dataIn[i] > 57 ? dataIn[i] - 87 : dataIn[i] - 48);
  64. //            println("-> " + hex(len));
  65.             i++;
  66.           }
  67.           println("Length: " + len + " (" + hex(len) + ")");
  68.           i += 2;
  69.           gzipData = new byte[len];
  70.           arrayCopy(dataIn, i, gzipData, 0, len);
  71.           break;
  72.         }
  73.       } 
  74.       //*
  75.       if (gzipData != null)
  76.       {
  77.         try
  78.         {
  79.           XML xml = new XML(new java.util.zip.GZIPInputStream(new java.io.ByteArrayInputStream(gzipData)));
  80.           println(xml);
  81.         }
  82.         catch (Exception e)
  83.         {
  84.           e.printStackTrace();
  85.         }
  86.       }
  87.       else
  88.       {
  89.         println("Gzip data not found!");
  90.         println(textData);
  91.       }
  92.       //*/
  93.     }
  94.     //println(dataIn);
  95.     step = -step;
  96.   }
  97. }
User-agent isn't needed, but the server wants the client to tell it accepts gzipped data (it won't deliver it unzipped, unless the API has a special parameter for that).

The main problem was that if the request is OK, the answer is a standard HTTP one, with binary data inside.
I guessed that the start of the data (after a double CRLF sequence) is the length of the Gzipped data encoded as a hexadecimal number. After that, I just had to copy this data in a buffer and unzip it to feed the XML parser.

Viewing all articles
Browse latest Browse all 1768

Trending Articles