Skip to content

Instantly share code, notes, and snippets.

@lotherk
Created February 15, 2017 08:22
Show Gist options
  • Save lotherk/6d044ad00bd643ecb72ebc2699753e5b to your computer and use it in GitHub Desktop.
Save lotherk/6d044ad00bd643ecb72ebc2699753e5b to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct uri_param {
char *key;
char *value;
};
struct uri {
char *proto;
char *hostname;
char *path;
struct uri_param **get_params;
size_t get_params_s;
};
struct uri *uri_new()
{
struct uri *p = malloc(sizeof(struct uri));
if (NULL == p)
return NULL;
p->proto = NULL;
p->hostname = NULL;
p->path = NULL;
p->get_params = NULL;
p->get_params_s = 0;
return p;
}
int uri_free(struct uri *uri)
{
if (uri->get_params != NULL) {
int i;
for(i = 0; i < uri->get_params_s; i++) {
struct uri_param *p = uri->get_params[i];
free(p->key);
free(p->value);
free(p);
}
free(uri->get_params);
}
free(uri);
return 0;
}
int uri_add_get_param(struct uri *uri, const char *key, const char *value)
{
if (NULL == uri)
return -1;
if (NULL == key)
return -2;
if (NULL == uri->get_params)
uri->get_params = malloc(sizeof(struct uri_param*));
else
uri->get_params = realloc(uri->get_params, uri->get_params_s + 1);
if (NULL == uri->get_params)
return -3;
struct uri_param *p = malloc(sizeof(struct uri_param));
if (NULL == p)
return -4;
p->key = strdup(key);
p->value = strdup(value);
uri->get_params[uri->get_params_s++] = p;
return 0;
}
char *uri_build(struct uri *uri)
{
#define ADD_TO_URI(s) \
if (s != NULL) { \
if (bufsize < (strlen(buf) + strlen(s))) { \
bufsize = strlen(buf) + strlen(s) + 1 + 1; \
buf = realloc(buf, bufsize); \
} \
strcat(buf, s); \
}
size_t bufsize = 64;
char *buf = malloc(bufsize * sizeof(char));
ADD_TO_URI(uri->proto);
ADD_TO_URI("://");
ADD_TO_URI(uri->hostname);
ADD_TO_URI("/");
ADD_TO_URI(uri->path);
if (NULL != uri->get_params) {
ADD_TO_URI("?");
int i;
for (i = 0; i < uri->get_params_s; i++) {
struct uri_param *p = uri->get_params[i];
ADD_TO_URI(p->key);
ADD_TO_URI("=\"");
ADD_TO_URI(p->value);
ADD_TO_URI("\"");
if (i < uri->get_params_s-1)
ADD_TO_URI("&");
}
}
#undef ADD_TO_URI
return buf;
}
int main() {
struct uri *myuri = uri_new();
myuri->proto = "http";
myuri->hostname = "lukrop.is.best";
myuri->path = "/this/is/some/path/";
uri_add_get_param(myuri, "key1", "value1");
uri_add_get_param(myuri, "key2", "value 2 with spaces");
uri_add_get_param(myuri, "key3", "value 3 with !§$ special chars äöü");
char *url = uri_build(myuri);
printf("url: %s\n", url);
free(url);
uri_free(myuri);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment