diff -ruP src/ao.h libshairport.new/src/ao.h
--- a/src/ao.h	2012-05-07 22:26:53.000000000 +0200
+++ b/src/ao.h	2012-05-08 18:46:42.000000000 +0200
@@ -152,5 +152,7 @@
       /* -- Device Setup/Playback/Teardown -- */                                                                                                                                                                 
       int (*ao_append_option)(ao_option **, const char *, const char *);                                                                                                                                         
       void (*ao_free_options)(ao_option *);                                                                                                                                                                      
-      char* (*ao_get_option)(ao_option *, const char* );                                                                                                                                                         
+      char* (*ao_get_option)(ao_option *, const char* );
+      void (*ao_set_metadata)(const char *buffer, unsigned int size);                                                                                                                                                         
+      void (*ao_set_metadata_coverart)(const char *buffer, unsigned int size);
   }; 
diff -ruP src/hairtunes.c src/hairtunes.c
--- a/src/hairtunes.c	2012-05-07 22:26:53.000000000 +0200
+++ b/src/hairtunes.c	2012-05-08 18:45:51.000000000 +0200
@@ -267,6 +267,16 @@
   fix_volume = 65536.0 * volume;
 }
 
+void hairtunes_set_metadata(const char *buffer, unsigned int size)
+{
+  g_ao.ao_set_metadata(buffer, size);
+}
+
+void hairtunes_set_metadata_coverart(const char *buffer, unsigned int size)
+{
+  g_ao.ao_set_metadata_coverart(buffer, size);
+}
+
 void hairtunes_flush(void)
 {
   pthread_mutex_lock(&ab_mutex);
diff -ruP src/hairtunes.h src/hairtunes.h
--- a/src/hairtunes.h	2011-08-21 00:06:21.000000000 +0200
+++ b/src/hairtunes.h	2012-05-08 18:46:00.000000000 +0200
@@ -4,6 +4,8 @@
 int hairtunes_init(char *pAeskey, char *pAesiv, char *pFmtpstr, int pCtrlPort, int pTimingPort,
          int pDataPort, char *pRtpHost, char*pPipeName, char *pLibaoDriver, char *pLibaoDeviceName, char *pLibaoDeviceId);
 void hairtunes_setvolume(float vol);
+void hairtunes_set_metadata(const char *buffer, unsigned int size);
+void hairtunes_set_metadata_coverart(const char *buffer, unsigned int size);
 void hairtunes_flush(void);
 void hairtunes_cleanup(void);
 
diff -ruP src/shairport.c src/shairport.c
--- a/src/shairport.c	2012-05-07 22:26:53.000000000 +0200
+++ b/src/shairport.c	2012-05-08 18:45:30.000000000 +0200
@@ -513,7 +513,8 @@
     while(1 == tMoreDataNeeded)
     {
       tError = readDataFromClient(pSock, &(tConn.recv));
-      if(!tError && strlen(tConn.recv.data) > 0)
+      //if(!tError && strlen(tConn.recv.data) > 0)
+      if(!tError && tConn.recv.current > 0)
       {
         xprintf("Finished Reading some data from client\n");
         // parse client request
@@ -632,7 +633,7 @@
     }
     
     tSize = (int) (tShortest - tFound);
-    xprintf("Found %.*s  length: %d\n", tSize, tFound, tSize);
+    xprintf("Found %s  length: %d\n",tFound, tSize);
     if(pReturnSize != NULL)
     {
       *pReturnSize = tSize;
@@ -744,7 +745,7 @@
   if(tContent != NULL)
   {
     int tContentSize = atoi(tContent);
-    if(pConn->recv.marker == 0 || strlen(pConn->recv.data+pConn->recv.marker) != tContentSize)
+    if(pConn->recv.marker == 0 || pConn->recv.current-pConn->recv.marker != tContentSize)
     {
       if(isLogEnabledFor(HEADER_LOG_LEVEL))
       {
@@ -752,7 +753,7 @@
         if(pConn->recv.marker != 0)
         {
           xprintf("ContentPtr has %d, but needs %d\n", 
-                  strlen(pConn->recv.data+pConn->recv.marker), tContentSize);
+                  (pConn->recv.current-pConn->recv.marker), tContentSize);
         }
       }
       // check if value in tContent > 2nd read from client.
@@ -989,15 +990,67 @@
   {
     propogateCSeq(pConn);
     int tSize = 0;
+    char *buffer = NULL;
+    char *contentType = getFromHeader(pConn->recv.data, "Content-Type", &tSize);
+    char *tContent = getFromHeader(pConn->recv.data, "Content-Length", NULL);
+    int iContentSize = 0;
+    int isJpg = 0;
+    
+    if(tContent != NULL)
+    {
+      iContentSize = atoi(tContent);
+    }
+
+    if( tSize > 1 && 
+        (strncmp(contentType, "application/x-dmap-tagged", tSize) == 0) ||
+        (strncmp(contentType, "image/jpeg", tSize) == 0)                 )
+    {
+      if( (pConn->recv.current - pConn->recv.marker) == iContentSize && pConn->recv.marker != 0)
+      {
+        if(strncmp(contentType, "image/jpeg", tSize) == 0)
+        {
+          isJpg = 1;
+        }
+        buffer = (char *)malloc(iContentSize * sizeof(char));
+        memcpy(buffer, pConn->recv.data + pConn->recv.marker, iContentSize);                                                                                                                                     
+      }
+      else
+      {
+        iContentSize = 0;
+      }
+    }
+    else
+    {
+      iContentSize = 0;
+    }
     char *tVol = getFromHeader(pConn->recv.data, "volume", &tSize);
-    xprintf("About to write [vol: %.*s] data to hairtunes\n", tSize, tVol);
+    if( tVol)
+    {
+      xprintf("About to write [vol: %.*s] data to hairtunes\n", tSize, tVol);
+    }
     // TBD VOLUME
 #ifndef XBMC
     write(pConn->hairtunes->in[1], "vol: ", 5);
     write(pConn->hairtunes->in[1], tVol, tSize);
     write(pConn->hairtunes->in[1], "\n", 1);
 #else
-    hairtunes_setvolume(atof(tVol));
+    if(tVol)
+    {
+      hairtunes_setvolume(atof(tVol));
+    }
+    
+    if(iContentSize)
+    {
+      if(isJpg)
+      {
+        hairtunes_set_metadata_coverart(buffer, iContentSize);      
+      }
+      else
+      {
+        hairtunes_set_metadata(buffer, iContentSize);
+      }
+      free(buffer);
+    }
 #endif
     xprintf("Finished writing data write data to hairtunes\n");
   }
