diff options
-rw-r--r-- | url.c | 149 | ||||
-rw-r--r-- | url.h | 144 |
2 files changed, 142 insertions, 151 deletions
@@ -1,149 +0,0 @@ -#include <netdb.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -/* - schemes are case sensitive but cononicals are lower case. - domain is case insensitive. return it lowercased? - port is optional and in decimal - path - scheme://username:password@domain:port/path?query_string#fragment_id - mailto:username@domain - - optional stuff: - scheme, username, password, port, path, query_string, fragment_id -*/ - -#include "url.h" - -/* -struct url { - char *scheme; - char *username; - char *password; - char *domain; - char *port; - char *path; - char *query_string; - char *fragment_id; -} -*/ - -void urlfromline(struct url *u,char *line) { - int i; - //split at first single / into line and path - for(i=0;line[i];i++) { - if(line[i] == '/' && line[i+1] == '/') { - i++; - continue; - } - if(line[i] == '/') { - line[i]=0; - u->path=line+i+1; - break; - } - } - if(u->path) { - if(strchr(u->path,'?')) { - u->query_string=strchr(u->path,'?'); - *u->query_string=0; - u->query_string++; - } - } - - if(u->query_string) { - if(strchr(u->query_string,'#')) { - u->fragment_id=strchr(u->query_string,'#'); - *u->fragment_id=0; - u->fragment_id++; - } - } - - if(strstr(line,"://")) { - u->scheme=line; - u->domain=strstr(line,"://"); - *u->domain=0; - u->domain+=3; - } else { - u->domain=line; - } - - if(u->domain) { - if(strchr(u->domain,'@')) { - u->username=u->domain; - u->domain=strchr(u->domain,'@'); - *u->domain=0; - u->domain++; - } - } - - if(u->username) { - if(strchr(u->username,':')) { - u->password=strchr(u->username,':'); - *u->password=0; - u->password++; - } - } - - if(u->domain) { - if(strchr(u->domain,']')) {//the end of an IPv6 address - if(strchr(strchr(u->domain,']'),':')) { - u->port=strchr(strchr(u->domain,']'),':'); - if(u->port[1] == '?') {//for magnet links - u->port=0; - } else { - *u->port=0; - u->port++; - } - } - } else { - if(strchr(u->domain,':')) { - u->port=strchr(u->domain,':'); - if(u->port[1] == '?') {//for magnet links - u->port=0; - } else { - *u->port=0; - u->port++; - } - } - } - } - - if(u->domain) {//for magnet links. - if(strchr(u->domain,'?')) { - u->query_string=strchr(u->domain,'?'); - *u->query_string=0; - u->query_string++; - } - } - - if(strchr(u->domain,':') && !strchr(u->domain,']')) {//for scheme:?query_string - u->scheme=u->domain; - *strchr(u->scheme,':')=0; - u->domain=0; - } - - if(!u->scheme && u->username) {//for mailto: - u->scheme=u->username; - u->username=u->password; - u->password=0; - } -} - -#define AorB(a,b) ((a)?(a):(b)) - -void magic_and_defaults(struct url *u) { - struct servent *serv; - char sport[10]; - u->scheme=AorB(u->scheme,AorB(getenv("URL_SCHEME"),"DEFAULT")); - u->username=AorB(u->username,AorB(getenv("URL_USERNAME"),"DEFAULT")); - u->password=AorB(u->password,AorB(getenv("URL_PASSWORD"),"DEFAULT")); - u->domain=AorB(u->domain,AorB(getenv("URL_DOMAIN"),"DEFAULT")); - serv=getservbyname(u->scheme,strcmp(u->scheme,"udp")?"tcp":"udp");//gets default port for the scheme. http -> 80 - if(serv) snprintf(sport,sizeof(sport)-1,"%d",ntohs(serv->s_port)); - u->port=AorB(u->port,AorB(getenv("URL_PORT"),(serv?sport:"DEFAULT"))); - u->path=AorB(u->path,AorB(getenv("URL_PATH"),"DEFAULT")); - u->query_string=AorB(u->query_string,AorB(getenv("URL_QUERY_STRING"),"DEFAULT")); - u->fragment_id=AorB(u->fragment_id,AorB(getenv("URL_FRAGMENT_ID"),"DEFAULT")); -} @@ -1,6 +1,11 @@ #ifndef URL_H #define URL_H +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + struct url { char *scheme; char *username; @@ -12,6 +17,141 @@ struct url { char *fragment_id; }; -void urlfromline(struct url *,char *); -void magic_and_defaults(struct url *); + +/* + schemes are case sensitive but cononicals are lower case. + domain is case insensitive. return it lowercased? + port is optional and in decimal + path + scheme://username:password@domain:port/path?query_string#fragment_id + mailto:username@domain + + optional stuff: + scheme, username, password, port, path, query_string, fragment_id +*/ + +void urlfromline(struct url *u,char *line) { + int i; + //split at first single / into line and path + for(i=0;line[i];i++) { + if(line[i] == '/' && line[i+1] == '/') { + i++; + continue; + } + if(line[i] == '/') { + line[i]=0; + u->path=line+i+1; + break; + } + } + if(u->path) { + if(strchr(u->path,'?')) { + u->query_string=strchr(u->path,'?'); + *u->query_string=0; + u->query_string++; + } + } + + if(u->query_string) { + if(strchr(u->query_string,'#')) { + u->fragment_id=strchr(u->query_string,'#'); + *u->fragment_id=0; + u->fragment_id++; + } + } + + if(strstr(line,"://")) { + u->scheme=line; + u->domain=strstr(line,"://"); + *u->domain=0; + u->domain+=3; + } else { + u->domain=line; + } + + if(u->domain) { + if(strchr(u->domain,'@')) { + u->username=u->domain; + u->domain=strchr(u->domain,'@'); + *u->domain=0; + u->domain++; + } + } + + if(u->username) { + if(strchr(u->username,':')) { + u->password=strchr(u->username,':'); + *u->password=0; + u->password++; + } + } + + if(u->domain) { + if(strchr(u->domain,']')) {//the end of an IPv6 address + if(strchr(strchr(u->domain,']'),':')) { + u->port=strchr(strchr(u->domain,']'),':'); + if(u->port[1] == '?') {//for magnet links + u->port=0; + } else { + *u->port=0; + u->port++; + } + } + } else { + if(strchr(u->domain,':')) { + u->port=strchr(u->domain,':'); + if(u->port[1] == '?') {//for magnet links + u->port=0; + } else { + *u->port=0; + u->port++; + } + } + } + } + + if(u->domain) {//for magnet links. + if(strchr(u->domain,'?')) { + u->query_string=strchr(u->domain,'?'); + *u->query_string=0; + u->query_string++; + } + } + + if(strchr(u->domain,':') && !strchr(u->domain,']')) {//for scheme:?query_string + u->scheme=u->domain; + *strchr(u->scheme,':')=0; + u->domain=0; + } + + if(!u->scheme && u->username) {//for mailto: + u->scheme=u->username; + u->username=u->password; + u->password=0; + } +} + +#define AorB(a,b) ((a)?(a):(b)) + +void magic_and_defaults(struct url *u) { + struct servent *serv; + char sport[10]; + u->scheme=AorB(u->scheme,AorB(getenv("URL_SCHEME"),"DEFAULT")); + u->username=AorB(u->username,AorB(getenv("URL_USERNAME"),"DEFAULT")); + u->password=AorB(u->password,AorB(getenv("URL_PASSWORD"),"DEFAULT")); + u->domain=AorB(u->domain,AorB(getenv("URL_DOMAIN"),"DEFAULT")); + serv=getservbyname(u->scheme,strcmp(u->scheme,"udp")?"tcp":"udp");//gets default port for the scheme. http -> 80 + if(serv) snprintf(sport,sizeof(sport)-1,"%d",ntohs(serv->s_port)); +// else snprintf(sport,sizeof(sport)-1,"%d",serv); + u->port=AorB(u->port,AorB(getenv("URL_PORT"),(serv||1?strdup(sport):"DEFAULT"))); + +// if(!strcmp(u->port,"DEFAULT")) { + //this shouldn't happen most of the time. :/ +// printf("serv: %d\nsport: %s\nu->scheme: %s\n",serv,sport,u->scheme); +// } + + u->path=AorB(u->path,AorB(getenv("URL_PATH"),"DEFAULT")); + u->query_string=AorB(u->query_string,AorB(getenv("URL_QUERY_STRING"),"DEFAULT")); + u->fragment_id=AorB(u->fragment_id,AorB(getenv("URL_FRAGMENT_ID"),"DEFAULT")); +} #endif |