]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/httpd/content.c
tls: fix various tlsClient()/tlsServer() related bugs
[plan9front.git] / sys / src / cmd / ip / httpd / content.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "httpd.h"
5 #include "httpsrv.h"
6
7 typedef struct Suffix   Suffix;
8 struct Suffix 
9 {
10         Suffix  *next;
11         char    *suffix;
12         char    *generic;
13         char    *specific;
14         char    *encoding;
15 };
16
17 Suffix  *suffixes = nil;
18
19 static  Suffix*                 parsesuffix(char*, Suffix*);
20 static  char*                   skipwhite(char*);
21 static  HContents               suffixclass(char*);
22 static  char*                   towhite(char*);
23
24 int
25 updateQid(int fd, Qid *q)
26 {
27         Dir *dir;
28         Qid dq;
29
30         dir = dirfstat(fd);
31         if(dir == nil)
32                 sysfatal("can't dirfstat");
33         dq = dir->qid;
34         free(dir);
35         if(q->path == dq.path && q->vers == dq.vers && q->type == dq.type)
36                 return 0;
37         *q = dq;
38         return 1;
39 }
40
41 void
42 contentinit(void)
43 {
44         static Biobuf *b = nil;
45         static Qid qid;
46         char *file, *s;
47         Suffix *this;
48
49         file = "/sys/lib/mimetype";
50         if(b == nil){ /* first time */
51                 b = Bopen(file, OREAD);
52                 if(b == nil)
53                         sysfatal("can't read from %s", file);
54         }
55         if(updateQid(Bfildes(b), &qid) == 0)
56                 return;
57         Bseek(b, 0, 0);
58         while(suffixes!=nil){
59                 this = suffixes;
60                 suffixes = suffixes->next;
61                 free(this->suffix);
62                 free(this->generic);
63                 free(this->specific);
64                 free(this->encoding);
65                 free(this);
66         }
67
68         while((s = Brdline(b, '\n')) != nil){
69                 s[Blinelen(b) - 1] = 0;
70                 suffixes = parsesuffix(s, suffixes);
71         }
72 }
73
74 static Suffix*
75 parsesuffix(char *line, Suffix *suffix)
76 {
77         Suffix *s;
78         char *p, *fields[5];
79         int i, nf;
80
81         p = strchr(line, '#');
82         if(p != nil)
83                 *p = '\0';
84         nf = tokenize(line, fields, 5);
85         for(i = 0; i < 4; i++)
86                 if(i >= nf || fields[i][0] == '-')
87                         fields[i] = nil;
88
89         if(fields[2] == nil)
90                 fields[1] = nil;
91         if(fields[1] == nil && fields[3] == nil)
92                 return suffix;
93         if(fields[0] == nil)
94                 return suffix;
95
96         s = ezalloc(sizeof *s);
97         s->next = suffix;
98         s->suffix = estrdup(fields[0]);
99         if(fields[1] != nil){
100                 s->generic = estrdup(fields[1]);
101                 s->specific = estrdup(fields[2]);
102         }
103         if(fields[3] != nil)
104                 s->encoding = estrdup(fields[3]);
105         return s;
106 }
107
108 /*
109  * classify by file name extensions
110  */
111 HContents
112 uriclass(HConnect *hc, char *name)
113 {
114         HContents conts;
115         Suffix *s;
116         HContent *type, *enc;
117         char *buf, *p;
118
119         type = nil;
120         enc = nil;
121         if((p = strrchr(name, '/')) != nil)
122                 name = p + 1;
123         buf = hstrdup(hc, name);
124         while((p = strrchr(buf, '.')) != nil){
125                 for(s = suffixes; s; s = s->next){
126                         if(strcmp(p, s->suffix) == 0){
127                                 if(s->generic != nil && type == nil)
128                                         type = hmkcontent(hc, s->generic, s->specific, nil);
129                                 if(s->encoding != nil && enc == nil)
130                                         enc = hmkcontent(hc, s->encoding, nil, nil);
131                         }
132                 }
133                 *p = 0;
134         }
135         conts.type = type;
136         conts.encoding = enc;
137         return conts;
138 }
139
140 /*
141  * classify by initial contents of file
142  */
143 HContents
144 dataclass(HConnect *hc, char *buf, int n)
145 {
146         HContents conts;
147         Rune r;
148         int c, m;
149
150         for(; n > 0; n -= m){
151                 c = *buf;
152                 if(c < Runeself){
153                         if(c < 32 && c != '\n' && c != '\r' && c != '\t' && c != '\v'){
154                                 conts.type = nil;
155                                 conts.encoding = nil;
156                                 return conts;
157                         }
158                         m = 1;
159                 }else{
160                         m = chartorune(&r, buf);
161                         if(r == Runeerror){
162                                 conts.type = nil;
163                                 conts.encoding = nil;
164                                 return conts;
165                         }
166                 }
167                 buf += m;
168         }
169         conts.type = hmkcontent(hc, "text", "plain", nil);
170         conts.encoding = nil;
171         return conts;
172 }