diff options
-rw-r--r-- | libpiano/src/CMakeLists.txt | 8 | ||||
-rw-r--r-- | libpiano/src/http.c | 91 | ||||
-rw-r--r-- | libpiano/src/http.h | 6 | ||||
-rw-r--r-- | libpiano/src/main.c | 232 | ||||
-rw-r--r-- | libpiano/src/piano.h | 11 |
5 files changed, 139 insertions, 209 deletions
diff --git a/libpiano/src/CMakeLists.txt b/libpiano/src/CMakeLists.txt index 9525101..432c5fd 100644 --- a/libpiano/src/CMakeLists.txt +++ b/libpiano/src/CMakeLists.txt @@ -1,11 +1,13 @@ set (CMAKE_C_FLAGS -Wall) find_package (LibXml2 REQUIRED) -find_package (CURL REQUIRED) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) -include_directories (${LIBXML2_INCLUDE_DIR} ${CURL_INCLUDE_DIRS}) +include_directories (${LIBXML2_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../../libwaitress/src) + add_library (piano STATIC crypt.c http.c main.c xml.c) -target_link_libraries (${CURL_LIBRARIES} ${LIBXML_LIBRARIES}) +target_link_libraries (piano ${LIBXML_LIBRARIES} waitress) + diff --git a/libpiano/src/http.c b/libpiano/src/http.c index 6a73aa7..acae893 100644 --- a/libpiano/src/http.c +++ b/libpiano/src/http.c @@ -21,40 +21,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include <curl/curl.h> #include <stdlib.h> #include <string.h> +#include <stdio.h> -#include "http.h" - -struct PianoHttpBuffer { - size_t size; /* size of string without NUL-byte */ - char *buf; /* NUL-terminated string */ -}; - -/* callback for curl, writes data to buffer - * @param received data - * @param block size - * @param blocks received - * @param write data into this buffer - * @return written bytes - */ -size_t PianoCurlRetToVar (void *ptr, size_t size, size_t nmemb, - void *stream) { - struct PianoHttpBuffer *curlRet = stream; +#include <waitress.h> - if (curlRet->buf == NULL) { - curlRet->buf = malloc (nmemb + 1); - curlRet->size = 0; - } else { - curlRet->buf = realloc (curlRet->buf, curlRet->size + nmemb + 1); - } - memcpy (curlRet->buf + curlRet->size, ptr, size*nmemb); - curlRet->size += nmemb; - curlRet->buf[curlRet->size] = 0; - - return size*nmemb; -} +#include "http.h" /* FIXME: we may use a callback given by the library client here. would be * more flexible... */ @@ -65,33 +38,16 @@ size_t PianoCurlRetToVar (void *ptr, size_t size, size_t nmemb, * @param put received data here, memory is allocated by this function * @return nothing yet */ -PianoReturn_t PianoHttpPost (CURL *ch, const char *url, const char *postData, - char **retData) { - struct curl_slist *headers = NULL; - struct PianoHttpBuffer curlRet = {0, NULL}; - PianoReturn_t ret; - - headers = curl_slist_append (headers, "Content-Type: text/xml"); - - curl_easy_setopt (ch, CURLOPT_URL, url); - curl_easy_setopt (ch, CURLOPT_POSTFIELDS, postData); - curl_easy_setopt (ch, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt (ch, CURLOPT_WRITEFUNCTION, PianoCurlRetToVar); - /* don't verify certificate for now, it's easier ;) */ - curl_easy_setopt (ch, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt (ch, CURLOPT_WRITEDATA, (void *) &curlRet); - - if (curl_easy_perform (ch) == CURLE_OK) { - ret = PIANO_RET_OK; - *retData = curlRet.buf; - } else { - ret = PIANO_RET_NET_ERROR; - *retData = NULL; +PianoReturn_t PianoHttpPost (WaitressHandle_t *waith, const char *postData, + char *retData, size_t retDataSize) { + waith->extraHeaders = "Content-Type: text/xml\r\n"; + waith->postData = postData; + waith->method = WAITRESS_METHOD_POST; + + if (WaitressFetchBuf (waith, retData, retDataSize) == WAITRESS_RET_OK) { + return PIANO_RET_OK; } - - curl_slist_free_all (headers); - - return ret; + return PIANO_RET_NET_ERROR; } /* get data @@ -100,23 +56,12 @@ PianoReturn_t PianoHttpPost (CURL *ch, const char *url, const char *postData, * @param put received data here, memory is allocated by this function * @return nothing yet */ -PianoReturn_t PianoHttpGet (CURL *ch, const char *url, char **retData) { - struct PianoHttpBuffer curlRet = {0, NULL}; - PianoReturn_t ret; - - curl_easy_setopt (ch, CURLOPT_URL, url); - curl_easy_setopt (ch, CURLOPT_HTTPGET, 1L); - curl_easy_setopt (ch, CURLOPT_HTTPHEADER, NULL); - curl_easy_setopt (ch, CURLOPT_WRITEFUNCTION, PianoCurlRetToVar); - curl_easy_setopt (ch, CURLOPT_WRITEDATA, (void *) &curlRet); +PianoReturn_t PianoHttpGet (WaitressHandle_t *waith, char *retData, + size_t retDataSize) { + waith->method = WAITRESS_METHOD_GET; - if (curl_easy_perform (ch) == CURLE_OK) { - ret = PIANO_RET_OK; - *retData = curlRet.buf; - } else { - ret = PIANO_RET_NET_ERROR; - *retData = NULL; + if (WaitressFetchBuf (waith, retData, retDataSize) == WAITRESS_RET_OK) { + return PIANO_RET_OK; } - - return ret; + return PIANO_RET_NET_ERROR; } diff --git a/libpiano/src/http.h b/libpiano/src/http.h index fa525dd..c56ef8b 100644 --- a/libpiano/src/http.h +++ b/libpiano/src/http.h @@ -24,10 +24,10 @@ THE SOFTWARE. #ifndef _HTTP_H #define _HTTP_H +#include <waitress.h> #include "piano.h" -PianoReturn_t PianoHttpPost (CURL *ch, const char *url, const char *postData, - char **retData); -PianoReturn_t PianoHttpGet (CURL *ch, const char *url, char **retData); +PianoReturn_t PianoHttpPost (WaitressHandle_t *, const char *, char *, size_t); +PianoReturn_t PianoHttpGet (WaitressHandle_t *, char *, size_t); #endif /* _HTTP_H */ diff --git a/libpiano/src/main.c b/libpiano/src/main.c index 7e7b989..e662c14 100644 --- a/libpiano/src/main.c +++ b/libpiano/src/main.c @@ -34,21 +34,19 @@ THE SOFTWARE. #include "config.h" #define PIANO_PROTOCOL_VERSION "23" -#define PIANO_RPC_URL "http://www.pandora.com/radio/xmlrpc/v" \ - PIANO_PROTOCOL_VERSION "?" -#define PIANO_SECURE_RPC_URL "https://www.pandora.com/radio/xmlrpc/v" \ - PIANO_PROTOCOL_VERSION "?" -#define PIANO_URL_BUFFER_SIZE 1024 +#define PIANO_RPC_HOST "www.pandora.com" +#define PIANO_RPC_PORT "80" +#define PIANO_RPC_PATH "/radio/xmlrpc/v" PIANO_PROTOCOL_VERSION "?" #define PIANO_SEND_BUFFER_SIZE 10000 +/* station responses are _huge_... */ +#define PIANO_RECV_BUFFER 100*1024 /* prototypes */ PianoReturn_t PianoAddFeedback (PianoHandle_t *, const char *, const char *, const char *, const char *, const char *, PianoSongRating_t); const char *PianoAudioFormatToString (PianoAudioFormat_t); -/* more "secure" free version; only use this function, not original free () - * in this library - * @public no!!! +/* more "secure" free version * @param free this pointer * @param zero n bytes; 0 disables zeroing (for strings with unknown size, * e.g.) @@ -71,11 +69,13 @@ void PianoFree (void *ptr, size_t size) { */ void PianoInit (PianoHandle_t *ph) { memset (ph, 0, sizeof (*ph)); - ph->curlHandle = curl_easy_init (); + + WaitressInit (&ph->waith); + strncpy (ph->waith.host, PIANO_RPC_HOST, sizeof (ph->waith.host)-1); + strncpy (ph->waith.port, PIANO_RPC_PORT, sizeof (ph->waith.port)-1); + + /* route-id seems to be random. we're using time anyway... */ snprintf (ph->routeId, sizeof (ph->routeId), "%07liP", time (NULL) % 10000000); - curl_easy_setopt (ph->curlHandle, CURLOPT_USERAGENT, PACKAGE); - curl_easy_setopt (ph->curlHandle, CURLOPT_CONNECTTIMEOUT, 60); - curl_easy_setopt (ph->curlHandle, CURLOPT_TIMEOUT, 60); } /* free complete search result @@ -164,7 +164,8 @@ void PianoDestroyPlaylist (PianoHandle_t *ph) { * @return nothing */ void PianoDestroy (PianoHandle_t *ph) { - curl_easy_cleanup (ph->curlHandle); + WaitressFree (&ph->waith); + PianoFree (ph->user.webAuthToken, 0); PianoFree (ph->user.authToken, 0); PianoFree (ph->user.listenerId, 0); @@ -191,12 +192,11 @@ void PianoDestroy (PianoHandle_t *ph) { * is not hashed and will be sent as plain-text! */ PianoReturn_t PianoConnect (PianoHandle_t *ph, const char *user, - const char *password, char secureLogin) { - char url[PIANO_URL_BUFFER_SIZE]; + const char *password) { + char retStr[PIANO_RECV_BUFFER], requestStrPlain[PIANO_SEND_BUFFER_SIZE]; char *requestStr = PianoEncryptString ("<?xml version=\"1.0\"?>" "<methodCall><methodName>misc.sync</methodName>" "<params></params></methodCall>"); - char *retStr, requestStrPlain[PIANO_SEND_BUFFER_SIZE]; PianoReturn_t ret; #if 0 @@ -205,11 +205,10 @@ PianoReturn_t PianoConnect (PianoHandle_t *ph, const char *user, "==========\n"); #endif /* sync (is the return value used by pandora? for now: ignore result) */ - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&method=sync", - ph->routeId); - ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr); + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&method=sync", ph->routeId); + ret = PianoHttpPost (&ph->waith, requestStr, retStr, sizeof (retStr)); PianoFree (requestStr, 0); - PianoFree (retStr, 0); if (ret != PIANO_RET_OK) { return ret; @@ -224,13 +223,12 @@ PianoReturn_t PianoConnect (PianoHandle_t *ph, const char *user, "<param><value><string>%s</string></value></param>" "</params></methodCall>", time (NULL), user, password); requestStr = PianoEncryptString (requestStrPlain); - snprintf (url, sizeof (url), "%srid=%s&method=authenticateListener", - secureLogin ? PIANO_SECURE_RPC_URL : PIANO_RPC_URL, ph->routeId); + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&method=authenticateListener", ph->routeId); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseUserinfo (ph, retStr); - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -243,8 +241,8 @@ PianoReturn_t PianoConnect (PianoHandle_t *ph, const char *user, * @param piano handle filled with some authentication data by PianoConnect */ PianoReturn_t PianoGetStations (PianoHandle_t *ph) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret; snprintf (xmlSendBuf, sizeof (xmlSendBuf), "<?xml version=\"1.0\"?>" @@ -253,14 +251,13 @@ PianoReturn_t PianoGetStations (PianoHandle_t *ph) { "<param><value><string>%s</string></value></param>" "</params></methodCall>", time (NULL), ph->user.authToken); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH "rid=%s&lid=%s&method=getStations", ph->routeId, ph->user.listenerId); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseStations (ph, retStr); - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -274,8 +271,8 @@ PianoReturn_t PianoGetStations (PianoHandle_t *ph) { */ PianoReturn_t PianoGetPlaylist (PianoHandle_t *ph, const char *stationId, PianoAudioFormat_t format) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret; /* FIXME: remove static numbers */ @@ -291,16 +288,15 @@ PianoReturn_t PianoGetPlaylist (PianoHandle_t *ph, const char *stationId, "</params></methodCall>", time (NULL), ph->user.authToken, stationId, PianoAudioFormatToString (format)); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH "rid=%s&lid=%s&method=getFragment&arg1=%s&arg2=0" "&arg3=&arg4=&arg5=%s", ph->routeId, ph->user.listenerId, stationId, PianoAudioFormatToString (format)); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParsePlaylist (ph, retStr); - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -363,8 +359,8 @@ PianoReturn_t PianoAddFeedback (PianoHandle_t *ph, const char *stationId, const char *songMusicId, const char *songMatchingSeed, const char *songUserSeed, const char *songFocusTraitId, PianoSongRating_t rating) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret = PIANO_RET_ERR; snprintf (xmlSendBuf, sizeof (xmlSendBuf), "<?xml version=\"1.0\"?>" @@ -386,7 +382,7 @@ PianoReturn_t PianoAddFeedback (PianoHandle_t *ph, const char *stationId, (songFocusTraitId == NULL) ? "" : songFocusTraitId, (rating == PIANO_RATE_LOVE) ? 1 : 0); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH "rid=%s&lid=%s&method=addFeedback&arg1=%s&arg2=%s" "&arg3=%s&arg4=%s&arg5=%s&arg6=&arg7=%s&arg8=false", ph->routeId, ph->user.listenerId, stationId, songMusicId, @@ -395,10 +391,9 @@ PianoReturn_t PianoAddFeedback (PianoHandle_t *ph, const char *stationId, (songFocusTraitId == NULL) ? "" : songFocusTraitId, (rating == PIANO_RATE_LOVE) ? "true" : "false"); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseSimple (retStr); - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -415,8 +410,8 @@ PianoReturn_t PianoAddFeedback (PianoHandle_t *ph, const char *stationId, */ PianoReturn_t PianoRenameStation (PianoHandle_t *ph, PianoStation_t *station, const char *newName) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr, *urlencodedNewName, *xmlencodedNewName; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr, *urlencodedNewName, *xmlencodedNewName; PianoReturn_t ret = PIANO_RET_ERR; xmlencodedNewName = PianoXmlEncodeString (newName); @@ -430,21 +425,20 @@ PianoReturn_t PianoRenameStation (PianoHandle_t *ph, PianoStation_t *station, station->id, xmlencodedNewName); requestStr = PianoEncryptString (xmlSendBuf); - urlencodedNewName = curl_easy_escape (ph->curlHandle, newName, 0); - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&lid=%s" - "&method=setStationName&arg1=%s&arg2=%s", ph->routeId, - ph->user.listenerId, station->id, urlencodedNewName); + urlencodedNewName = WaitressUrlEncode (newName); + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&lid=%s&method=setStationName&arg1=%s&arg2=%s", + ph->routeId, ph->user.listenerId, station->id, urlencodedNewName); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { if ((ret = PianoXmlParseSimple (retStr)) == PIANO_RET_OK) { PianoFree (station->name, 0); station->name = strdup (newName); } - PianoFree (retStr, 0); } - curl_free (urlencodedNewName); + PianoFree (urlencodedNewName, 0); PianoFree (xmlencodedNewName, 0); PianoFree (requestStr, 0); @@ -457,8 +451,8 @@ PianoReturn_t PianoRenameStation (PianoHandle_t *ph, PianoStation_t *station, * @param station you want to delete */ PianoReturn_t PianoDeleteStation (PianoHandle_t *ph, PianoStation_t *station) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret = PIANO_RET_ERR; snprintf (xmlSendBuf, sizeof (xmlSendBuf), "<?xml version=\"1.0\"?>" @@ -470,11 +464,11 @@ PianoReturn_t PianoDeleteStation (PianoHandle_t *ph, PianoStation_t *station) { station->id); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&lid=%s" - "&method=removeStation&arg1=%s", ph->routeId, ph->user.listenerId, - station->id); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&lid=%s&method=removeStation&arg1=%s", ph->routeId, + ph->user.listenerId, station->id); + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { if ((ret = PianoXmlParseSimple (retStr)) == PIANO_RET_OK) { /* delete station from local station list */ PianoStation_t *curStation = ph->stations, *lastStation = NULL; @@ -494,7 +488,6 @@ PianoReturn_t PianoDeleteStation (PianoHandle_t *ph, PianoStation_t *station) { curStation = curStation->next; } } - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -510,10 +503,10 @@ PianoReturn_t PianoDeleteStation (PianoHandle_t *ph, PianoStation_t *station) { * @param utf-8 search string * @param return search result */ -PianoReturn_t PianoSearchMusic (const PianoHandle_t *ph, +PianoReturn_t PianoSearchMusic (PianoHandle_t *ph, const char *searchStr, PianoSearchResult_t *searchResult) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr, *xmlencodedSearchStr, *urlencodedSearchStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr, *xmlencodedSearchStr, *urlencodedSearchStr; PianoReturn_t ret; xmlencodedSearchStr = PianoXmlEncodeString (searchStr); @@ -526,18 +519,17 @@ PianoReturn_t PianoSearchMusic (const PianoHandle_t *ph, xmlencodedSearchStr); requestStr = PianoEncryptString (xmlSendBuf); - urlencodedSearchStr = curl_easy_escape (ph->curlHandle, searchStr, 0); - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&lid=%s&" - "method=search&arg1=%s", ph->routeId, ph->user.listenerId, - urlencodedSearchStr); + urlencodedSearchStr = WaitressUrlEncode (searchStr); + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&lid=%s&method=search&arg1=%s", ph->routeId, + ph->user.listenerId, urlencodedSearchStr); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseSearch (retStr, searchResult); - PianoFree (retStr, 0); } - curl_free (urlencodedSearchStr); + PianoFree (urlencodedSearchStr, 0); PianoFree (xmlencodedSearchStr, 0); PianoFree (requestStr, 0); @@ -553,8 +545,8 @@ PianoReturn_t PianoSearchMusic (const PianoHandle_t *ph, */ PianoReturn_t PianoCreateStation (PianoHandle_t *ph, const char *type, const char *id) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret; snprintf (xmlSendBuf, sizeof (xmlSendBuf), "<?xml version=\"1.0\"?>" @@ -566,14 +558,13 @@ PianoReturn_t PianoCreateStation (PianoHandle_t *ph, const char *type, type, id); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&lid=%s" - "&method=createStation&arg1=%s%s", ph->routeId, + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&lid=%s&method=createStation&arg1=%s%s", ph->routeId, ph->user.listenerId, type, id); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseCreateStation (ph, retStr); - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -592,8 +583,8 @@ PianoReturn_t PianoCreateStation (PianoHandle_t *ph, const char *type, */ PianoReturn_t PianoStationAddMusic (PianoHandle_t *ph, PianoStation_t *station, const char *musicId) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret; snprintf (xmlSendBuf, sizeof (xmlSendBuf), "<?xml version=\"1.0\"?>" @@ -606,14 +597,13 @@ PianoReturn_t PianoStationAddMusic (PianoHandle_t *ph, station->id, musicId); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&lid=%s" - "&method=addSeed&arg1=%s&arg2=%s", ph->routeId, + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&lid=%s&method=addSeed&arg1=%s&arg2=%s", ph->routeId, ph->user.listenerId, station->id, musicId); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseAddSeed (ph, retStr, station); - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -627,8 +617,8 @@ PianoReturn_t PianoStationAddMusic (PianoHandle_t *ph, * @return _OK or error */ PianoReturn_t PianoSongTired (PianoHandle_t *ph, const PianoSong_t *song) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret; snprintf (xmlSendBuf, sizeof (xmlSendBuf), "<?xml version=\"1.0\"?>" @@ -640,14 +630,13 @@ PianoReturn_t PianoSongTired (PianoHandle_t *ph, const PianoSong_t *song) { song->identity); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&lid=%s&" - "method=addTiredSong&arg1=%s", ph->routeId, ph->user.listenerId, - song->identity); + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&lid=%s&method=addTiredSong&arg1=%s", ph->routeId, + ph->user.listenerId, song->identity); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseSimple (retStr); - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -661,8 +650,8 @@ PianoReturn_t PianoSongTired (PianoHandle_t *ph, const PianoSong_t *song) { */ PianoReturn_t PianoSetQuickmix (PianoHandle_t *ph) { char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], valueBuf[1000], urlArgBuf[1000], - url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret; PianoStation_t *curStation = ph->stations; @@ -699,14 +688,13 @@ PianoReturn_t PianoSetQuickmix (PianoHandle_t *ph) { sizeof (xmlSendBuf) - strlen (xmlSendBuf) - 1); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&lid=%s&" - "method=setQuickMix&arg1=RANDOM&arg2=%s", ph->routeId, - ph->user.listenerId, urlArgBuf); + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&lid=%s&method=setQuickMix&arg1=RANDOM&arg2=%s", + ph->routeId, ph->user.listenerId, urlArgBuf); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseSimple (retStr); - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -735,17 +723,15 @@ PianoStation_t *PianoFindStationById (PianoStation_t *stations, * @return _OK or error */ PianoReturn_t PianoGetGenreStations (PianoHandle_t *ph) { - char url[PIANO_URL_BUFFER_SIZE]; - char *retStr; + char retStr[PIANO_RECV_BUFFER]; PianoReturn_t ret; - snprintf (url, sizeof (url), "http://www.pandora.com/xml/genre?r=%li", + snprintf (ph->waith.path, sizeof (ph->waith.path), "/xml/genre?r=%li", time (NULL)); - if ((ret = PianoHttpGet (ph->curlHandle, url, &retStr)) == + if ((ret = PianoHttpGet (&ph->waith, retStr, sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseGenreExplorer (ph, retStr); - PianoFree (retStr, 0); } return ret; @@ -759,8 +745,8 @@ PianoReturn_t PianoGetGenreStations (PianoHandle_t *ph) { */ PianoReturn_t PianoTransformShared (PianoHandle_t *ph, PianoStation_t *station) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret; snprintf (xmlSendBuf, sizeof (xmlSendBuf), "<?xml version=\"1.0\"?>" @@ -772,19 +758,18 @@ PianoReturn_t PianoTransformShared (PianoHandle_t *ph, station->id); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&lid=%s&" - "method=transformShared&arg1=%s", ph->routeId, ph->user.listenerId, - station->id); + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&lid=%s&method=transformShared&arg1=%s", ph->routeId, + ph->user.listenerId, station->id); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseTranformStation (retStr); /* though this call returns a bunch of "new" data only this one is * changed and important (at the moment) */ if (ret == PIANO_RET_OK) { station->isCreator = 1; } - PianoFree (retStr, 0); } PianoFree (requestStr, 0); @@ -798,10 +783,10 @@ PianoReturn_t PianoTransformShared (PianoHandle_t *ph, * @param return allocated string; you have to free it yourself * @return _OK or error */ -PianoReturn_t PianoExplain (const PianoHandle_t *ph, const PianoSong_t *song, +PianoReturn_t PianoExplain (PianoHandle_t *ph, const PianoSong_t *song, char **retExplain) { - char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], url[PIANO_URL_BUFFER_SIZE]; - char *requestStr, *retStr; + char xmlSendBuf[PIANO_SEND_BUFFER_SIZE], retStr[PIANO_RECV_BUFFER]; + char *requestStr; PianoReturn_t ret; snprintf (xmlSendBuf, sizeof (xmlSendBuf), "<?xml version=\"1.0\"?>" @@ -814,14 +799,13 @@ PianoReturn_t PianoExplain (const PianoHandle_t *ph, const PianoSong_t *song, song->stationId, song->musicId); requestStr = PianoEncryptString (xmlSendBuf); - snprintf (url, sizeof (url), PIANO_RPC_URL "rid=%s&lid=%s&" - "method=method=narrative&arg1=%s&arg2=%s", ph->routeId, - ph->user.listenerId, song->stationId, song->musicId); + snprintf (ph->waith.path, sizeof (ph->waith.path), PIANO_RPC_PATH + "rid=%s&lid=%s&method=method=narrative&arg1=%s&arg2=%s", + ph->routeId, ph->user.listenerId, song->stationId, song->musicId); - if ((ret = PianoHttpPost (ph->curlHandle, url, requestStr, &retStr)) == - PIANO_RET_OK) { + if ((ret = PianoHttpPost (&ph->waith, requestStr, retStr, + sizeof (retStr))) == PIANO_RET_OK) { ret = PianoXmlParseNarrative (retStr, retExplain); - PianoFree (retStr, 0); } PianoFree (requestStr, 0); diff --git a/libpiano/src/piano.h b/libpiano/src/piano.h index db85108..7ed5394 100644 --- a/libpiano/src/piano.h +++ b/libpiano/src/piano.h @@ -29,7 +29,7 @@ THE SOFTWARE. * all strings _must_ be utf-8 encoded. i won't care, but pandora does. so * be nice and check the encoding of your strings. thanks :) */ -#include <curl/curl.h> +#include <waitress.h> typedef struct PianoUserInfo { char *webAuthToken; @@ -85,7 +85,7 @@ typedef struct PianoGenreCategory { } PianoGenreCategory_t; typedef struct PianoHandle { - CURL *curlHandle; + WaitressHandle_t waith; char routeId[9]; PianoUserInfo_t user; /* linked lists */ @@ -110,7 +110,7 @@ void PianoInit (PianoHandle_t *); void PianoDestroy (PianoHandle_t *); void PianoDestroyPlaylist (PianoHandle_t *); void PianoDestroySearchResult (PianoSearchResult_t *); -PianoReturn_t PianoConnect (PianoHandle_t *, const char *, const char *, char); +PianoReturn_t PianoConnect (PianoHandle_t *, const char *, const char *); PianoReturn_t PianoGetStations (PianoHandle_t *); PianoReturn_t PianoGetPlaylist (PianoHandle_t *, const char *, @@ -123,7 +123,7 @@ PianoReturn_t PianoMoveSong (PianoHandle_t *, const PianoStation_t *, PianoReturn_t PianoRenameStation (PianoHandle_t *, PianoStation_t *, const char *); PianoReturn_t PianoDeleteStation (PianoHandle_t *, PianoStation_t *); -PianoReturn_t PianoSearchMusic (const PianoHandle_t *, const char *, +PianoReturn_t PianoSearchMusic (PianoHandle_t *, const char *, PianoSearchResult_t *); PianoReturn_t PianoCreateStation (PianoHandle_t *, const char *, const char *); @@ -134,8 +134,7 @@ PianoReturn_t PianoSetQuickmix (PianoHandle_t *); PianoStation_t *PianoFindStationById (PianoStation_t *, const char *); PianoReturn_t PianoGetGenreStations (PianoHandle_t *); PianoReturn_t PianoTransformShared (PianoHandle_t *, PianoStation_t *); -PianoReturn_t PianoExplain (const PianoHandle_t *, const PianoSong_t *, - char **); +PianoReturn_t PianoExplain (PianoHandle_t *, const PianoSong_t *, char **); const char *PianoErrorToStr (PianoReturn_t); #endif /* _PIANO_H */ |