1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include <string.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;
}
}
|