Make URL parser more dynamic

This commit is contained in:
Jaroslav Kysela 2014-04-09 20:30:44 +02:00
parent f150d5d706
commit 9ca6f0c45d
5 changed files with 76 additions and 27 deletions

View file

@ -81,6 +81,8 @@ http_remove ( http_client_t *hc )
/* Free CURL memory */
curl_easy_cleanup(hc->hc_curl);
hc->hc_curl = NULL;
urlreset(&hc->hc_url);
}
/*
@ -199,7 +201,7 @@ http_connect
/* Setup structure */
http_client_t *hc = calloc(1, sizeof(http_client_t));
hc->hc_curl = curl_easy_init();
hc->hc_url = *url;
urlcopy(&hc->hc_url, url);
hc->hc_conn = conn_cb;
hc->hc_data = data_cb;
hc->hc_fail = fail_cb;

View file

@ -218,6 +218,7 @@ iptv_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi )
im->mm_active = NULL;
pthread_mutex_unlock(&iptv_lock);
urlreset(&url);
return ret;
}

View file

@ -466,6 +466,7 @@ satip_discovery_destroy(satip_discovery_t *d, int unlink)
}
if (d->http_client)
http_close(d->http_client);
urlreset(&d->url);
free(d->myaddr);
free(d->location);
free(d->server);
@ -622,7 +623,7 @@ satip_discovery_timerq_cb(void *aux)
next = TAILQ_NEXT(d, disc_link);
if (d->http_client) {
if (dispatch_clock - d->http_start > 4)
satip_discovery_destroy(d, 1);;
satip_discovery_destroy(d, 1);
continue;
}
d->http_client = http_connect(&d->url, NULL,
@ -631,7 +632,8 @@ satip_discovery_timerq_cb(void *aux)
d);
if (d->http_client == NULL)
satip_discovery_destroy(d, 1);
d->http_start = dispatch_clock;
else
d->http_start = dispatch_clock;
}
if (TAILQ_FIRST(&satip_discoveries))
gtimer_arm(&satip_discovery_timerq, satip_discovery_timerq_cb, NULL, 5);

View file

@ -25,11 +25,40 @@
#include <regex.h>
#include <string.h>
void
urlreset ( url_t *url )
{
free(url->scheme);
free(url->user);
free(url->pass);
free(url->host);
free(url->path);
free(url->query);
free(url->frag);
free(url->raw);
memset(url, 0, sizeof(*url));
}
void
urlcopy ( url_t *dst, const url_t *src )
{
dst->scheme = strdup(src->scheme);
dst->user = strdup(src->user);
dst->pass = strdup(src->pass);
dst->host = strdup(src->host);
dst->port = src->port;
dst->path = strdup(src->path);
dst->query = strdup(src->query);
dst->frag = strdup(src->frag);
dst->raw = strdup(src->raw);
}
/* Use liburiparser if available */
#if ENABLE_URIPARSER
#include <uriparser/Uri.h>
int
int
urlparse ( const char *str, url_t *url )
{
UriParserStateA state;
@ -37,6 +66,11 @@ urlparse ( const char *str, url_t *url )
UriUriA uri;
char *s, buf[256];
if (str == NULL || url == NULL)
return -1;
urlreset(url);
/* Parse */
state.uri = &uri;
if (uriParseUriA(&state, str) != URI_SUCCESS) {
@ -45,32 +79,36 @@ urlparse ( const char *str, url_t *url )
}
/* Store raw */
strncpy(url->raw, str, sizeof(url->raw));
url->raw = strdup(str);
/* Copy */
#define uri_copy(y, x)\
if (x.first) {\
size_t len = x.afterLast - x.first;\
y = strndup(x.first, len);\
}
#define uri_copy_static(y, x)\
if (x.first) {\
size_t len = x.afterLast - x.first;\
strncpy(y, x.first, len);\
y[len] = 0;\
} else {\
*y = 0;\
y[0] = '\0';\
}
uri_copy(url->scheme, uri.scheme);
uri_copy(url->host, uri.hostText);
uri_copy(url->user, uri.userInfo);
uri_copy(url->query, uri.query);
uri_copy(url->frag, uri.fragment);
uri_copy(buf, uri.portText);
uri_copy_static(buf, uri.portText);
if (*buf)
url->port = atoi(buf);
else
url->port = 0;
*url->path = 0;
path = uri.pathHead;
while (path) {
strcat(url->path, "/");
uri_copy(buf, path->text);
url->path = realloc(url->path, strlen(url->path) + strlen(buf) + 2);
strcat(url->path, "/");
strcat(url->path, buf);
path = path->next;
}
@ -81,8 +119,6 @@ urlparse ( const char *str, url_t *url )
if (s) {
strcpy(url->pass, s+1);
*s = 0;
} else {
*url->pass = 0;
}
/* Cleanup */
@ -113,6 +149,11 @@ urlparse ( const char *str, url_t *url )
regmatch_t m[16];
char buf[16];
if (str == NULL || url == NULL)
return -1;
urlreset(url);
/* Create regexp */
if (!urlparse_exp) {
urlparse_exp = calloc(1, sizeof(regex_t));
@ -124,10 +165,14 @@ urlparse ( const char *str, url_t *url )
/* Execute */
if (regexec(urlparse_exp, str, ARRAY_SIZE(m), m, 0))
return 1;
return -1;
/* Extract data */
#define copy(x, i)\
{\
x = strndup(str+m[i].rm_so, m[i].rm_eo - m[i].rm_so);\
}(void)0
#define copy_static(x, i)\
{\
int len = m[i].rm_eo - m[i].rm_so;\
if (len >= sizeof(x) - 1)\
@ -140,12 +185,12 @@ urlparse ( const char *str, url_t *url )
copy(url->pass, 5);
copy(url->host, 6);
copy(url->path, 9);
copy(buf, 8);
copy_static(buf, 8);
url->port = atoi(buf);
copy(url->query, 11);
copy(url->frag, 13);
strncpy(url->raw, str, sizeof(url->raw));
url->raw = strdup(str);
return 0;
}

View file

@ -22,24 +22,23 @@
#include <stdint.h>
// TODO: limits are a bit arbitrary and it's a bit inflexible, but it
// does keep things simple, not having dynamically allocated strings
/* URL structure */
typedef struct url
{
char scheme[32];
char user[128];
char pass[128];
char host[256];
short port;
char path[256];
char query[1024];
char frag[256];
char raw[2048];
char *scheme;
char *user;
char *pass;
char *host;
short port;
char *path;
char *query;
char *frag;
char *raw;
} url_t;
void urlreset ( url_t *url );
int urlparse ( const char *str, url_t *url );
void urlparse_done ( void );
void urlcopy ( url_t *dst, const url_t *src );
#endif