Commit ccdb215d authored by brendan's avatar brendan

add util_dict_urlencode, update shout_set_metadata to use it.

This will also be used for audio_info.

This function hammers malloc - should be made more polite later.

svn path=/trunk/libshout/; revision=4360
parent d1b6cc7f
......@@ -240,65 +240,27 @@ int shout_set_metadata(shout_t *self, shout_metadata_t *metadata)
if (!self || !metadata)
return SHOUTERR_INSANE;
if (!(encvalue = util_dict_urlencode(metadata, '&')))
return SHOUTERR_MALLOC;
if (!self->connected)
return SHOUTERR_UNCONNECTED;
if ((socket = sock_connect(self->host, self->port)) <= 0)
return SHOUTERR_NOCONNECT;
if (self->protocol == SHOUT_PROTOCOL_ICY)
rv = sock_write(socket, "GET /admin.cgi?mode=updinfo&pass=%s", self->password);
else if (self->protocol == SHOUT_PROTOCOL_HTTP)
rv = sock_write(socket, "GET /admin/metadata?mode=updinfo&mount=%s", self->mount);
else
rv = sock_write(socket, "GET /admin.cgi?mode=updinfo&pass=%s&mount=%s", self->password, self->mount);
if (!rv) {
sock_close(socket);
return SHOUTERR_SOCKET;
}
while (metadata) {
if (metadata->key) {
if (metadata->val) {
if (!(encvalue = util_url_encode(metadata->val))) {
rv = SHOUTERR_MALLOC;
break;
}
rv = sock_write(socket, "&%s=%s", metadata->key, encvalue);
} else
rv = sock_write(socket, "&%s", metadata->key);
free (encvalue);
if (!rv) {
sock_close(socket);
return SHOUTERR_SOCKET;
}
}
rv = SHOUTERR_SUCCESS;
metadata = metadata->next;
}
if (rv != SHOUTERR_SUCCESS) {
sock_close(socket);
return rv;
}
if (!sock_write(socket, " HTTP/1.0\r\nUser-Agent: %s\r\n", shout_get_agent(self))) {
sock_close(socket);
return SHOUTERR_SOCKET;
}
if (self->protocol == SHOUT_PROTOCOL_HTTP) {
rv = sock_write(socket, "GET /admin.cgi?mode=updinfo&pass=%s&%s HTTP/1.0\r\nUser-Agent: %s\r\n\r\n",
self->password, encvalue, shout_get_agent(self));
else if (self->protocol == SHOUT_PROTOCOL_HTTP) {
char *auth = http_basic_authorization(self);
if (auth) {
if (!sock_write(socket, auth)) {
sock_close(socket);
free(auth);
return SHOUTERR_SOCKET;
}
free (auth);
}
}
if (!sock_write(socket, "\r\n")) {
rv = sock_write(socket, "GET /admin/metadata?mode=updinfo&mount=%s&%s HTTP/1.0\r\nUser-Agent: %s\r\n%s\r\n",
self->mount, encvalue, shout_get_agent(self), auth ? auth : "");
} else
rv = sock_write(socket, "GET /admin.cgi?mode=updinfo&pass=%s&mount=%s&%s HTTP/1.0\r\nUser-Agent: %s\r\n\r\n",
self->password, self->mount, encvalue, shout_get_agent(self));
free(encvalue);
if (!rv) {
sock_close(socket);
return SHOUTERR_SOCKET;
}
......
......@@ -194,4 +194,63 @@ int util_dict_set(util_dict *dict, const char *key, const char *val)
}
return SHOUTERR_SUCCESS;
}
/* given a dictionary, URL-encode each key and val and stringify them in order as
key=val;key=val... if val is set, or just key;key if val is NULL.
sep is the separator character (';' in the example above)
TODO: Memory management needs overhaul. */
char *util_dict_urlencode(util_dict *dict, char sep)
{
char *res, *tmp;
char *enc;
int start = 1;
for (res = NULL; dict; dict = dict->next) {
/* encode key */
if (!dict->key)
continue;
if (!(enc = util_url_encode(dict->key))) {
if (res)
free(res);
return NULL;
}
if (start) {
if (!(res = malloc(strlen(enc) + 1))) {
free(enc);
return NULL;
}
sprintf(res, "%s", enc);
free(enc);
start = 0;
} else {
if (!(tmp = realloc(res, strlen(res) + strlen(enc) + 2))) {
free(enc);
free(res);
return NULL;
} else
res = tmp;
sprintf(res + strlen(res), "%c%s", sep, enc);
free(enc);
}
/* encode value */
if (!dict->val)
continue;
if (!(enc = util_url_encode(dict->val))) {
free(res);
return NULL;
}
if (!(tmp = realloc(res, strlen(res) + strlen(enc) + 2))) {
free(enc);
free(res);
return NULL;
} else
res = tmp;
sprintf(res + strlen(res), "=%s", enc);
free(enc);
}
return res;
}
\ No newline at end of file
......@@ -18,6 +18,7 @@ void util_dict_free(util_dict *dict);
/* dict, key must not be NULL. */
int util_dict_set(util_dict *dict, const char *key, const char *val);
const char *util_dict_get(util_dict *dict, const char *key);
char *util_dict_urlencode(util_dict *dict, char sep);
char *util_base64_encode(char *data);
char *util_url_encode(const char *data);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment