Skip to content

Instantly share code, notes, and snippets.

@errzey
Created June 11, 2010 03:37
Show Gist options
  • Save errzey/434005 to your computer and use it in GitHub Desktop.
Save errzey/434005 to your computer and use it in GitHub Desktop.
/*
mthomas@atticus:~$ ./u "http://fdsfdsu:sfsdfds@www.ackers.net:8080/fda"
Scheme = http
Host = www.ackers.net
Port = 8080
User = fdsfdsu
Pass = sfsdfds
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
struct userinfo {
char *user;
char *pass;
};
struct authority {
char *host;
struct userinfo *userinfo;
uint16_t port;
};
struct query {
char *key;
char *val;
struct query *next;
};
struct parsed_url {
char *scheme;
struct authority *authority;
char *path;
char *raw_query;
struct query *query;
char *fragment;
};
static char *
get_tok(char *data, char *needle, int *offset)
{
char *out;
char *start = data;
char *end = NULL;
if ((end = strstr(data, needle)) == NULL) {
return(NULL);
}
out = calloc((end - start) + 1, 1);
strncpy(out, start, (end - start));
*offset += (end - start) + strlen(needle);
return(out);
}
char *
parse_scheme(char *url, int *offset)
{
return(get_tok(url, "://", offset));
}
char *
parse_raw_authority(char *url, int *offset)
{
char *auth = get_tok(url, "/", offset);
if (auth == NULL) {
return(url);
}
return(auth);
}
char *
parse_raw_userinfo(char *url, int *offset)
{
return(get_tok(url, "@", offset));
}
char *parse_username(char *url, int *offset)
{
char *user = get_tok(url, ":", offset);
return(user);
}
struct authority *
parse_authority(char *url, int *offset)
{
/* authority = [ userinfo "@" ] host [ ":" port ] */
struct authority *authority;
char *raw_authority = NULL;
char *host = NULL;
char *raw_userinfo = NULL;
char *username = NULL;
char *password = NULL;
uint16_t port;
int auth_offset = 0;
raw_authority = parse_raw_authority(url, offset);
if (raw_authority == NULL) {
return(NULL);
}
raw_userinfo = parse_raw_userinfo(raw_authority, &auth_offset);
if (raw_userinfo != NULL) {
int userinfo_offset = 0;
username = parse_username(raw_userinfo, &userinfo_offset);
if (username == NULL) {
username = raw_userinfo;
userinfo_offset = 0;
} else {
password = strdup((char *)(raw_userinfo + strlen(username) + 1));
userinfo_offset += strlen(password);
}
}
if ((host = get_tok(&raw_authority[auth_offset], ":", &auth_offset)) == NULL) {
host = strdup(&raw_authority[auth_offset]);
} else {
port = atoi(&raw_authority[auth_offset]);
}
authority = calloc(sizeof(struct authority), 1);
authority->host = host;
authority->port = port;
if (username) {
authority->userinfo = calloc(sizeof(struct userinfo), 1);
authority->userinfo->user = username;
authority->userinfo->pass = password;
}
return(authority);
} /* parse_authority */
void
print_authority(struct authority *auth)
{
printf("Host = %s\n", auth->host);
printf("Port = %d\n", auth->port);
if (auth->userinfo) {
printf("User = %s\n", auth->userinfo->user);
printf("Pass = %s\n", auth->userinfo->pass);
}
}
struct parsed_url *
parse_url(const char *url)
{
int offset = 0;
char *urlcpy = strdup(url);
char *scheme;
struct authority *author;
scheme = parse_scheme(&urlcpy[offset], &offset);
author = parse_authority(&urlcpy[offset], &offset);
printf("Scheme = %s\n", scheme);
print_authority(author);
return(NULL);
}
int main(int argc, char **argv)
{
char *inputurl;
struct parsed_url *parsed;
if (argc < 2) {
return(-1);
}
parsed = parse_url(argv[1]);
return(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment