source: titan/titan/httpd.h @ 15340

Last change on this file since 15340 was 15340, checked in by nit, 10 years ago

[titan] add queryraw

File size: 15.0 KB
Line 
1#ifndef HTTPD_H
2#define HTTPD_H
3
4char* getmimetype(char* name, char* mime)
5{
6        char* dot;
7
8        if(mime != NULL) return mime;
9        if(name == NULL) return "text/html";
10
11        dot = strrchr( name, '.' );
12        if(dot == NULL || strcmp(dot, ".html") == 0 || strcmp(dot, ".htm") == 0)
13                return "text/html";
14        if(strcmp(dot, ".jpg") == 0 || strcmp( dot, ".jpeg" ) == 0)
15                return "image/jpeg";
16        if(strcmp(dot, ".gif") == 0)
17                return "image/gif";
18        if(strcmp(dot, ".png") == 0)
19                return "image/png";
20        if(strcmp(dot, ".css") == 0)
21                return "text/css";
22        if(strcmp(dot, ".au") == 0)
23                return "audio/basic";
24        if(strcmp(dot, ".wav") == 0)
25                return "audio/wav";
26        if(strcmp(dot, ".avi") == 0)
27                return "video/x-msvideo";
28        if(strcmp(dot, ".mov") == 0 || strcmp(dot, ".qt" ) == 0)
29                return "video/quicktime";
30        if(strcmp(dot, ".mpeg") == 0 || strcmp(dot, ".mpe" ) == 0)
31                return "video/mpeg";
32        if(strcmp(dot, ".ts") == 0)
33                return "video/MP2T";   
34        if(strcmp(dot, ".vrml") == 0 || strcmp(dot, ".wrl" ) == 0)
35                return "model/vrml";
36        if(strcmp(dot, ".midi") == 0 || strcmp(dot, ".mid" ) == 0)
37                return "audio/midi";
38        if(strcmp(dot, ".mp3") == 0)
39                return "audio/mpeg";
40        if(strcmp(dot, ".ogg") == 0)
41                return "application/ogg";
42        if(strcmp(dot, ".pac") == 0)
43                return "application/x-ns-proxy-autoconfig";
44
45        return "text/html";
46}
47
48char* createheader(off64_t len, char* filename, char* mime, char* ext, int code, int auth)
49{
50        char* header = NULL, *buf = NULL;
51        time_t now = time(NULL);
52
53        buf = malloc(100);
54        if(buf == NULL)
55        {
56                err("no mem");
57                return NULL;
58        }
59
60        if(auth == 1) code=401;
61        switch(code)
62        {
63                case 200:
64                        header = ostrcat(header, "HTTP/1.1 200 OK\r\n", 1, 0);
65                        break;
66                case 302:
67                        header = ostrcat(header, "HTTP/1.1 302 Found\r\n", 1, 0);
68                        break;
69                case 401:
70                        header = ostrcat(header, "HTTP/1.1 401 Unauthorized\r\n", 1, 0);
71                        break;
72                case 500:
73                        header = ostrcat(header, "HTTP/1.1 500 Internal Server Error\r\n", 1, 0);
74                        break;
75        }
76
77        snprintf(buf, 99, "Server: %s\r\n", PROGNAME);
78        header = ostrcat(header, buf, 1, 0);
79
80        if(auth == 1)
81        {
82                snprintf(buf, 99, "WWW-Authenticate: Basic realm=\"Contol Panel\"\r\n");
83                header = ostrcat(header, buf, 1, 0);
84        }
85
86        strftime(buf, 99, "Date: %a, %d %b %Y %H:%M:%S GMT\r\n", gmtime(&now));
87        header = ostrcat(header, buf, 1, 0);
88
89        header = ostrcat(header, "Content-Type: ", 1, 0);
90        header = ostrcat(header, getmimetype(filename, mime), 1, 0);
91        header = ostrcat(header, "\r\n", 1, 0);
92
93        if(auth == 1) len = 0;
94        snprintf(buf, 99, "Content-Length: %lld\r\n", len);
95        header = ostrcat(header, buf, 1, 0);
96
97        strftime(buf, 99, "Expires: %a, %d %b %Y %H:%M:%S GMT\r\n", gmtime(&now));
98        header = ostrcat(header, buf, 1, 0);
99
100        if(filename != NULL)
101        {
102                now = getfiletime(filename, 1);
103                strftime(buf, 99, "Last-Modified: %a, %d %b %Y %H:%M:%S GMT\r\n", gmtime(&now));
104                header = ostrcat(header, buf, 1, 0);
105        }
106
107        if(ext != NULL)
108        {
109                header = ostrcat(header, ext, 1, 0);
110                header = ostrcat(header, "\r\n", 1, 0);
111        }
112
113        header = ostrcat(header, "Connection: close\r\n", 1, 0);
114        header = ostrcat(header, "\r\n", 1, 0);
115
116        free(buf);
117        return header;
118}
119
120void senderror(int* connfd, char* title, char* text, int auth)
121{
122        char* buf = NULL, *header = NULL;;
123
124        buf = ostrcat(buf, "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><link rel=stylesheet type=text/css href=titan.css><title>Error ", 1, 0);
125        buf = ostrcat(buf, title, 1, 0);
126        buf = ostrcat(buf, "</title></head><body class=body><font class=error>Error - ", 1, 0);
127        buf = ostrcat(buf, text, 1, 0);
128        buf = ostrcat(buf, "</font></body></html>", 1, 0);
129
130        header = createheader(strlen(buf), NULL, NULL, NULL, 500, auth);
131
132        socksend(connfd, (unsigned char*)header, strlen(header), 5000 * 1000);
133        socksend(connfd, (unsigned char*)buf, strlen(buf), 5000 * 1000);
134
135        free(header);
136        free(buf);
137}
138
139void checkquery(int* connfd, char* query, int auth, int fmt)
140{
141        char* buf = NULL, *header = NULL, *param = NULL;
142        char* ext = NULL, *mime = NULL;
143        int buflen = 0, onlyheader = 0, code = 200;
144
145        //create param
146        param = strchr(query, '&');
147        if(param != NULL)
148                *param++ = '\0';
149
150        if(ostrcmp(query, "sendrc") == 0)
151                websendrc(param, fmt);
152        if(ostrcmp(query, "getrectimer") == 0)
153                buf = webgetrectimer(param, 0, fmt);
154        if(ostrcmp(query, "addrectimer") == 0)
155                buf = webaddrectimer(param, fmt);
156        if(ostrcmp(query, "delrectimer") == 0)
157                buf = webdelrectimer(param, fmt);
158        if(ostrcmp(query, "editrectimer") == 0)
159                buf = webeditrectimer(param, fmt);
160        if(ostrcmp(query, "rectimersend") == 0)
161                buf = webrectimersend(param, fmt);
162        if(ostrcmp(query, "getrectimerarchive") == 0)
163                buf = webgetrectimer(param, 1, fmt);
164        if(ostrcmp(query, "setvol") == 0)
165                buf = websetvol(param, fmt);
166        if(ostrcmp(query, "setmute") == 0)
167                buf = websetmute(param, fmt);
168        if(ostrcmp(query, "getbouquet") == 0)
169                buf = webgetbouquet(fmt);
170        if(ostrcmp(query, "getsat") == 0)
171                buf = webgetsat(fmt);
172        if(ostrcmp(query, "getprovider") == 0)
173                buf = webgetprovider(fmt);
174        if(ostrcmp(query, "getaz") == 0)
175                buf = webgetaz(fmt);
176        if(ostrcmp(query, "getchannelpage") == 0)
177                buf = webgetchannelpage(param, fmt);
178        if(ostrcmp(query, "getallchannel") == 0)
179                buf = webgetchannel(0, 0, 1, fmt);
180        if(ostrcmp(query, "getbouquetchannel") == 0)
181                buf = webgetbouquetchannel(param, fmt);
182        if(ostrcmp(query, "getsatchannel") == 0 && param != NULL)
183                buf = webgetchannel(atoi(param), 1, 1, fmt);
184        if(ostrcmp(query, "getproviderchannel") == 0 && param != NULL)
185                buf = webgetchannel(atoi(param), 2, 1, fmt);
186        if(ostrcmp(query, "getazchannel") == 0 && param != NULL)
187                buf = webgetchannel(atoi(param), 3, 1, fmt);
188        if(ostrcmp(query, "switch") == 0)
189                buf = webswitch(param, fmt);
190        if(ostrcmp(query, "getaktservice") == 0)
191                buf = webgetaktservice(fmt);
192        if(ostrcmp(query, "getepg") == 0)
193                buf = webgetepg(param, fmt);
194        if(ostrcmp(query, "getmovieepg") == 0)
195                buf = webgetmovieepg(param, getconfig("rec_streampath", NULL), 1, fmt);
196        if(ostrcmp(query, "getsingleepg") == 0)
197                buf = webgetsingleepg(param, fmt);
198        if(ostrcmp(query, "getgmultiepg") == 0)
199                buf = webgetgmultiepg(param, fmt);
200        if(query != NULL && strstr(query, "getepgsearch") == query)
201                buf = webgetepgsearch(query, param, fmt);
202        if(ostrcmp(query, "getsignal") == 0)
203                buf = webgetsignal(fmt);
204        if(ostrcmp(query, "getmoviefilelist") == 0)
205                buf = webgetfilelist(param, "getmoviefilelist", "delmoviefile", getconfig("rec_streampath", NULL), "*.avi *.dat *.divx *.flv *.mkv *.m4v *.mp4 *.mov *.mpg *.mpeg *.mts *.m2ts *.trp *.ts *.vdr *.vob *.wmv *.rm", 31, fmt);
206        if(ostrcmp(query, "delmoviefile") == 0)
207                buf = webdelfile(param, "getmoviefilelist", "delmoviefile", getconfig("rec_streampath", NULL), "*.avi *.dat *.divx *.flv *.mkv *.m4v *.mp4 *.mov *.mpg *.mpeg *.mts *.m2ts *.trp *.ts *.vdr *.vob *.wmv *.rm", 31, fmt);
208        if(ostrcmp(query, "getm3u") == 0)
209        {
210                buf = webgetm3u(param, *connfd, fmt);
211                if(fmt == 0)
212                {
213                        ext = "Content-Disposition: attachment; filename=stream.m3u";
214                        mime = "text/plain";
215                }
216        }
217        if(ostrcmp(query, "getvideo") == 0)
218                buf = webgetvideo(param, *connfd, fmt);
219        if(ostrcmp(query, "getshoot") == 0)
220        {
221                webgetshoot(param, fmt);
222                if(fmt == 0)
223                {
224                        ext = "Location: shoot.html";
225                        onlyheader = 1;
226                        code = 302;
227                }
228                else
229                        buf = ostrcat("shoot.html", NULL, 0, 0);
230        }
231        if(query != NULL && strstr(query, "poweroff") == query)
232                oshutdown(1, 1);
233        if(query != NULL && strstr(query, "restart") == query)
234                oshutdown(2, 1);
235        if(query != NULL && strstr(query, "guirestart") == query)
236                oshutdown(3, 1);
237        if(query != NULL && strstr(query, "standby") == query)
238        {
239                status.standby = 2;
240                addtimer(&screenstandby, START, 1000, 1, NULL, NULL, NULL);
241        }
242        if(query != NULL && strstr(query, "boxstatus") == query)
243        {
244                if(status.standby > 0)
245                {
246                        if(fmt == 0)
247                                sendoktext(connfd, "standby", auth);
248                        else
249                                buf = ostrcat("standby", NULL, 0, 0);
250                }
251                else
252                {
253                        if(fmt == 0)
254                                sendoktext(connfd, "running", auth);
255                        else
256                                buf = ostrcat("running", NULL, 0, 0);
257                }
258        }
259        if(query != NULL && strstr(query, "message") == query)
260                buf = websendmessage(query, fmt);
261               
262        if(buf != NULL || onlyheader == 1)
263        {
264                if(buflen == 0 && onlyheader == 0) buflen = strlen(buf);
265
266                header = createheader(buflen, NULL, mime, ext, code, auth);
267                socksend(connfd, (unsigned char*)header, strlen(header), 5000 * 1000);
268                if(onlyheader == 0 && auth == 0)
269                        socksend(connfd, (unsigned char*)buf, buflen, 5000 * 1000);
270        }
271        else
272                senderror(connfd, "query", "Error in query string", auth);
273
274        free(header);
275        free(buf);
276}
277
278void gotdata(int* connfd)
279{
280        int ret = 0, filefd = -1, auth = 0;
281        unsigned char* buf = NULL;
282        char* tmpstr = NULL, *tmpstr1 = NULL, *filename = NULL, *fullfilename = NULL, *header = NULL, *query = NULL;
283
284        buf = malloc(MINMALLOC);
285        if(buf == NULL)
286        {
287                err("no mem");
288                sockclose(connfd);
289                return;
290        }
291        memset(buf, 0, MINMALLOC);
292
293        debug(250, "get client data");
294
295        //read one line
296        unsigned char* pbuf = buf;
297        while(pbuf - buf < MINMALLOC)
298        {
299                unsigned char c;
300
301                ret = sockreceive(connfd, &c, 1, 5000 * 1000);
302                if(ret != 0)
303                {
304                        err("no client data in buffer");
305                        break;
306                }
307
308                *pbuf = c;
309                if(buf != NULL && (strstr((char*)buf, "\n\n") != NULL || strstr((char*)buf, "\r\n\r\n") != NULL))
310                        break;
311                pbuf++;
312        }
313
314        if(buf != NULL)
315        {
316                tmpstr = strstr((char*)buf, "GET /");
317                tmpstr1 = strstr((char*)buf, "Authorization: Basic ");
318        }
319
320        //Auth Password
321        if(status.httpauth != NULL)
322        {
323                if(tmpstr1 != NULL)
324                {
325                        tmpstr1 += 21;
326                        char* tmpstr3 = malloc(255);
327                        if(tmpstr3 != NULL)
328                        {
329                                int l = b64dec(tmpstr3, tmpstr1);
330                                if(l < 255) tmpstr3[l] = '\0';
331                        }
332                        if(ostrncmp(tmpstr3, status.httpauth, strlen(status.httpauth)) != 0)
333                        {
334                                //not ok:
335                                tmpstr1 = NULL;
336                        }
337                        free(tmpstr3); tmpstr3 = NULL;
338                }
339       
340                if(tmpstr1 == NULL) auth = 1;
341        }
342
343        if(tmpstr != NULL)
344        {
345                tmpstr += 4;
346
347                filename = malloc(MINMALLOC);
348                if(filename == NULL)
349                {
350                        err("no mem");
351                        sockclose(connfd);
352                        free(buf); buf = NULL;
353                        tmpstr = NULL;
354                        return;
355                }
356                memset(filename, 0, MINMALLOC);
357
358                ret = sscanf(tmpstr, "%s", filename);
359                if(ret == 1)
360                {
361                        htmldecode(filename, filename);
362                       
363                        if(strstr(filename, "xmessage") == filename + 1  || strstr(filename, "/cgi-bin/xmessage") == filename )
364                        {       
365                                xmessage(filename);
366                                sendoktext(connfd, "ok", 0);
367                                //senderror(connfd, "ok", "ok", 0);
368                                free(buf); buf = NULL;
369                                free(filename); filename = NULL;
370                                tmpstr = NULL;
371                                return;
372                        }
373
374                        //create query
375                        query = strchr(filename, '?');
376                        if(query != NULL)
377                        {
378                                *query++ = '\0';
379                                debug(250, "httpd query=%s", query);
380                        }
381
382                        //queryraw
383                        if(ostrcmp(filename, "/queryraw") == 0 && query != NULL)
384                        {
385                                checkquery(connfd, query, auth, 1);
386                                free(buf); buf = NULL;
387                                free(filename); filename = NULL;
388                                tmpstr = NULL;
389                                return;
390                        }
391
392                        //query
393                        if(ostrcmp(filename, "/query") == 0 && query != NULL)
394                        {
395                                checkquery(connfd, query, auth, 0);
396                                free(buf); buf = NULL;
397                                free(filename); filename = NULL;
398                                tmpstr = NULL;
399                                return;
400                        }
401
402                        //create index.html
403                        if(filename[strlen(filename) - 1] == '/')
404                                filename = ostrcat(filename, "index.html", 1, 0);
405
406                        debug(250, "httpd filename=%s", filename);
407
408                        if(strstr(filename, "/movie/") != NULL)
409                                fullfilename = ostrcat(filename,"", 0, 0);
410                        else
411                                fullfilename = ostrcat(getconfig("httpdpath", NULL), filename, 0, 0);
412                        filefd = open(fullfilename, O_RDONLY | O_LARGEFILE);
413                        if(filefd < 0)
414                        {
415                                perr("open filename=%s", fullfilename);
416                                senderror(connfd, "Open File", "Can't open File", auth);
417                                free(fullfilename); fullfilename = NULL;
418                                free(buf); buf = NULL;
419                                free(filename); filename = NULL;
420                                tmpstr = NULL;
421                                return;
422                        }
423                        debug(250, "sende OK response to client");
424                        char* rpath = realpath(fullfilename, NULL);
425                        header = createheader(getfilesize(rpath), fullfilename, NULL, NULL, 200, auth);
426                        free(rpath); rpath = NULL;
427                        free(fullfilename); fullfilename = NULL;
428                        ret = socksend(connfd, (unsigned char*)header, strlen(header), 5000 * 1000);
429                        free(header); header = NULL;
430
431                        if(ret != 0)
432                        {
433                                sockclose(connfd);
434                                free(buf); buf = NULL;
435                                free(filename); filename = NULL;
436                                tmpstr = NULL;
437                                return;
438                        }
439
440                        //TODO:
441                        int readret = 1;
442                        while(readret > 0 && auth == 0)
443                        {
444                                readret = dvbreadfd(filefd, buf, 0, MINMALLOC, 1000);
445                                if(readret > 0)
446                                        socksend(connfd, buf, readret, 5000 * 1000);
447                        }
448                }
449        }
450
451        close(filefd);
452        free(buf); buf = NULL;
453        free(filename); filename = NULL;
454        tmpstr = NULL;
455}
456
457int newconn(int* streamfd, int* connfd)
458{
459        int i, fd = -1;
460
461        fd = sockaccept(streamfd, 1);
462        if(fd < 0) return -1;
463
464        for(i = 0; i < MAXHTTPDCONN; i++)
465        {
466                if(connfd[i] < 0)
467                {
468                        connfd[i] = fd;
469                        debug(250, "accept httpd connection fd=%d", fd);
470                        fd = -1;
471                        break;
472                }
473        }
474
475        if(fd != -1)
476        {
477                debug(250, "all connections in use");
478                sockclose(&fd);
479                return -1;
480        }
481
482        return 0;
483}
484
485void httpdthreadfunc(struct stimerthread* timernode)
486{
487        struct timeval timeout;
488        fd_set rfds;
489        int i, ret = 0, streamfd = -1, connfd[MAXHTTPDCONN], maxfd = -1;
490
491        debug(250, "Starting httpd thread");
492
493        for(i = 0; i < MAXHTTPDCONN; i++)
494                connfd[i] = -1;
495
496        while(timernode->aktion != STOP)
497        {
498                if(streamfd < 0)
499                {
500                        sockportcreate(&streamfd, getconfigint("httpdport", NULL), MAXHTTPDCONN);
501                        if(streamfd < 0) break;
502                        maxfd = streamfd;
503
504                        //set nonblocking
505                        fcntl(streamfd, F_SETFL, fcntl(streamfd, F_GETFL) | O_NONBLOCK);
506                }
507
508                timeout.tv_sec = 1;
509                timeout.tv_usec = 0;
510
511                FD_ZERO(&rfds);
512                FD_SET(streamfd, &rfds);
513
514                for(i = 0; i < MAXHTTPDCONN; i++)
515                {
516                        if(connfd[i] > -1)
517                        {
518                                FD_SET(connfd[i], &rfds);
519                                if(connfd[i] > maxfd) maxfd = connfd[i];
520                        }
521                }
522
523                ret = TEMP_FAILURE_RETRY(select(maxfd + 1, &rfds , NULL, NULL, &timeout));
524
525                if(ret < 0)
526                {
527                        perr("httpd listen socket fd=%d", maxfd);
528                        sleep(1);
529                        continue;
530                }
531                if(ret == 0) continue; //timeout
532
533                if(FD_ISSET(streamfd, &rfds))
534                {
535                        ret = newconn(&streamfd, connfd);
536                        if(ret < 0) continue;
537                }
538
539                for(i = 0; i < MAXHTTPDCONN; i++)
540                {
541                        if(connfd[i] > -1 && FD_ISSET(connfd[i], &rfds))
542                                gotdata(&connfd[i]);
543                }
544        }
545
546        debug(250, "Stopping httpd thread");
547        sockclose(&streamfd);
548        for(i = 0; i < MAXHTTPDCONN; i++)
549                sockclose(&connfd[i]);
550
551        return;
552}
553
554void sendoktext(int* connfd, char* text, int auth)
555{
556        char* buf = NULL;
557        char* header = NULL;
558        buf = webcreatehead(buf, NULL, 1);
559        buf = ostrcat(buf, "<tr><td align=center valign=top><font class=biglabel><br><br>", 1, 0);
560        buf = ostrcat(buf, text, 1, 0);
561        buf = ostrcat(buf, "</font></td></tr>", 1, 0);
562        buf = webcreatetail(buf, 1);
563        int buflen = strlen(buf);
564        header = createheader(buflen, NULL, NULL, NULL, 200, auth);
565        socksend(connfd, (unsigned char*)header, strlen(header), 5000 * 1000);
566        if(auth == 0)
567                socksend(connfd, (unsigned char*)buf, buflen, 5000 * 1000);
568        free(buf); buf=NULL;
569        free(header); header=NULL;
570}
571
572#endif
Note: See TracBrowser for help on using the repository browser.