#include #include #include #include "yuri.h" /* * TODO: percent encode appropriate characters */ char * uri_encode(struct uri *u) { int i; char *ret; char *dup; char portbuf[6]; /* highest port number is 5 digits minus \0 */ size_t len; len = 1; /* \0 */ ret = NULL; if (u->scheme) { len += strlen(u->scheme)+1; /* scheme: */ ret = realloc(NULL, len); if (ret == NULL) return NULL; strlcpy(ret, u->scheme, len); strlcat(ret, ":", len); } if (u->authority.host) { len += 2; /* // */ dup = realloc(ret, len); if (dup == NULL) { free(ret); return NULL; } ret = dup; strlcat(ret, "//", len); if (u->authority.user) { len += strlen(u->authority.user); dup = realloc(ret, len); if (dup == NULL) { free(ret); return NULL; } ret = dup; strlcat(ret, u->authority.user, len); } len += strlen(u->authority.host); dup = realloc(ret, len); if (dup == NULL) { free(ret); return NULL; } ret = dup; strlcat(ret, u->authority.host, len); if (u->authority.port) { memset(portbuf, 0, sizeof(portbuf)); /* snprintf is to be replaced in the future */ snprintf(portbuf, sizeof(portbuf), "%d", u->authority.port); len += strlen(portbuf)+1; /* :port */ dup = realloc(ret, len); if (dup == NULL) { free(ret); return NULL; } ret = dup; strlcat(ret, ":", len); strlcat(ret, portbuf, len); } } if (u->npath != 0) { for (i = 0; i < u->npath; i++) { if ((i == 0) ? u->authority.host : 1) { len += 1; /* / */ dup = realloc(ret, len); if (dup == NULL) { free(ret); return NULL; } ret = dup; strlcat(ret, "/", len); } len += strlen(u->path[i]); dup = realloc(ret, len); if (dup == NULL) { free(ret); return NULL; } ret = dup; strlcat(ret, u->path[i], len); } } if (u->query) { len += strlen(u->query)+1; /* ?query */ dup = realloc(ret, len); if (dup == NULL) { free(ret); return NULL; } ret = dup; strlcat(ret, "?", len); strlcat(ret, u->query, len); } if (u->fragment) { len += strlen(u->fragment)+1; /* #fragment */ dup = realloc(ret, len); if (dup == NULL) { free(ret); return NULL; } ret = dup; strlcat(ret, "#", len); strlcat(ret, u->fragment, len); } return ret; }