Up to enumerating the database

This commit is contained in:
Ron Pedde 2003-10-30 22:42:11 +00:00
parent 30183d97b2
commit 506cbcfb03
4 changed files with 186 additions and 42 deletions

View File

@ -82,7 +82,12 @@ install_sh = /Users/ron/Documents/School/cs4953 - Concurrency/mt-daapd/install-s
#
sbin_PROGRAMS = mt-daapd
mt_daapd_SOURCES = main.c rend.c uici.c webserver.c configfile.c err.c restart.c mdns/mDNS.c mdns/mDNSClientAPI.h mdns/mDNSDebug.h mdns/mDNSPosix.c mdns/mDNSUNP.c
mt_daapd_SOURCES = main.c daapd.h rend.c rend.h uici.c uici.h webserver.c \
webserver.h configfile.c configfile.h err.c err.h restart.c restart.h \
daap-proto.c daap-proto.h daap.c daap.h \
mdns/mDNS.c mdns/mDNSClientAPI.h mdns/mDNSDebug.h mdns/mDNSPosix.c \
mdns/mDNSUNP.c
subdir = src
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
@ -92,8 +97,8 @@ PROGRAMS = $(sbin_PROGRAMS)
am_mt_daapd_OBJECTS = main.$(OBJEXT) rend.$(OBJEXT) uici.$(OBJEXT) \
webserver.$(OBJEXT) configfile.$(OBJEXT) err.$(OBJEXT) \
restart.$(OBJEXT) mDNS.$(OBJEXT) mDNSPosix.$(OBJEXT) \
mDNSUNP.$(OBJEXT)
restart.$(OBJEXT) daap-proto.$(OBJEXT) daap.$(OBJEXT) \
mDNS.$(OBJEXT) mDNSPosix.$(OBJEXT) mDNSUNP.$(OBJEXT)
mt_daapd_OBJECTS = $(am_mt_daapd_OBJECTS)
mt_daapd_LDADD = $(LDADD)
mt_daapd_DEPENDENCIES =
@ -102,15 +107,17 @@ mt_daapd_LDFLAGS =
DEFS = -DHAVE_CONFIG_H
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
CPPFLAGS = -DDEBUG -g -no-cpp-precomp -DHAVE_SOCKADDR_SA_LEN -DHAVE_SOCKLEN_T
LDFLAGS = -lpthread
LDFLAGS = -lpthread -lz
LIBS =
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
DEP_FILES = ./$(DEPDIR)/configfile.Po ./$(DEPDIR)/err.Po \
./$(DEPDIR)/mDNS.Po ./$(DEPDIR)/mDNSPosix.Po \
./$(DEPDIR)/mDNSUNP.Po ./$(DEPDIR)/main.Po \
./$(DEPDIR)/rend.Po ./$(DEPDIR)/restart.Po \
./$(DEPDIR)/uici.Po ./$(DEPDIR)/webserver.Po
DEP_FILES = ./$(DEPDIR)/configfile.Po \
./$(DEPDIR)/daap-proto.Po ./$(DEPDIR)/daap.Po \
./$(DEPDIR)/err.Po ./$(DEPDIR)/mDNS.Po \
./$(DEPDIR)/mDNSPosix.Po ./$(DEPDIR)/mDNSUNP.Po \
./$(DEPDIR)/main.Po ./$(DEPDIR)/rend.Po \
./$(DEPDIR)/restart.Po ./$(DEPDIR)/uici.Po \
./$(DEPDIR)/webserver.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
@ -167,6 +174,8 @@ distclean-compile:
-rm -f *.tab.c
include ./$(DEPDIR)/configfile.Po
include ./$(DEPDIR)/daap-proto.Po
include ./$(DEPDIR)/daap.Po
include ./$(DEPDIR)/err.Po
include ./$(DEPDIR)/mDNS.Po
include ./$(DEPDIR)/mDNSPosix.Po

View File

@ -33,6 +33,8 @@
#include <sys/types.h>
#include "configfile.h"
#include "daap.h"
#include "daap-proto.h"
#include "err.h"
#include "rend.h"
#include "webserver.h"
@ -46,6 +48,67 @@
CONFIG config;
/*
* daap_handler
*
* Handle daap-related web pages
*/
void daap_handler(WS_CONNINFO *pwsc) {
int len;
int close;
DAAP_BLOCK *root,*error;
int compress=0;
close=pwsc->close;
pwsc->close=1;
ws_addresponseheader(pwsc,"Accept-Ranges","bytes");
ws_addresponseheader(pwsc,"DAAP-Server","iTunes/4.1 (Mac OS X)");
ws_addresponseheader(pwsc,"Content-Type","application/x-dmap-tagged");
if(!strcasecmp(pwsc->uri,"/server-info")) {
root=daap_response_server_info();
} else if (!strcasecmp(pwsc->uri,"/content-codes")) {
root=daap_response_content_codes();
} else if (!strcasecmp(pwsc->uri,"/login")) {
root=daap_response_login();
} else if (!strcasecmp(pwsc->uri,"/update")) {
root=daap_response_update();
} else if (!strcasecmp(pwsc->uri,"/databases")) {
root=daap_response_databases();
} else if (!strcasecmp(pwsc->uri,"/logout")) {
ws_returnerror(pwsc,204,"Logout Successful");
return;
} else {
DPRINTF(ERR_WARN,"Bad handler! Can't find uri handler for %s\n",
pwsc->uri);
return;
}
if(!root)
return;
pwsc->close=close;
ws_addresponseheader(pwsc,"Content-Length","%d",root->reported_size + 8);
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
ws_emitheaders(pwsc);
/*
if(ws_testrequestheader(pwsc,"Accept-Encoding","gzip")) {
ws_addresponseheader(pwsc,"Content-Encoding","gzip");
compress=1;
}
*/
daap_serialize(root,pwsc->fd,0);
daap_free(root);
return;
}
/*
* config_handler
*
@ -164,6 +227,7 @@ void usage(char *program) {
#ifdef DEBUG
printf(" -d <number> Debuglevel (0-9)\n");
#endif
printf(" -m Use mDNS\n");
printf(" -c <file> Use configfile specified");
printf("\n\n");
}
@ -174,11 +238,12 @@ int main(int argc, char *argv[]) {
WSCONFIG ws_config;
WSHANDLE server;
pid_t rendezvous_pid;
int use_mdns=0;
#ifdef DEBUG
char *optval="d:c:";
char *optval="d:c:m";
#else
char *optval="c:";
char *optval="c:m";
#endif /* DEBUG */
printf("mt-daapd: version $Revision$\n");
@ -195,6 +260,11 @@ int main(int argc, char *argv[]) {
case 'c':
configfile=optarg;
break;
case 'm':
use_mdns=1;
break;
default:
usage(argv[0]);
exit(EXIT_FAILURE);
@ -231,8 +301,15 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
ws_registerhandler(server, "^.*$",config_handler,config_auth);
ws_registerhandler(server, "^.*$",config_handler,config_auth,1);
ws_registerhandler(server, "^/server-info$",daap_handler,NULL,0);
ws_registerhandler(server, "^/content-codes$",daap_handler,NULL,0);
ws_registerhandler(server,"^/login$",daap_handler,NULL,0);
ws_registerhandler(server,"^/update$",daap_handler,NULL,0);
ws_registerhandler(server,"^/databases$",daap_handler,NULL,0);
ws_registerhandler(server,"^/logout$",daap_handler,NULL,0);
if(use_mdns)
rend_init(&rendezvous_pid);
while(1) {

View File

@ -25,12 +25,13 @@
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <regex.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <sys/param.h>
#include <sys/types.h>
@ -43,7 +44,7 @@
*/
#define MAX_HOSTNAME 256
#define MAX_LINEBUFFER 256
#define MAX_LINEBUFFER 1024
/*
* Local (private) typedefs
@ -53,6 +54,7 @@ typedef struct tag_ws_handler {
regex_t regex;
void (*req_handler)(WS_CONNINFO*);
int(*auth_handler)(char *, char *);
int addheaders;
struct tag_ws_handler *next;
} WS_HANDLER;
@ -91,16 +93,22 @@ int ws_testarg(ARGLIST *root, char *key, char *value);
void ws_emitheaders(WS_CONNINFO *pwsc);
int ws_findhandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc,
void(**preq)(WS_CONNINFO*),
int(**pauth)(char *, char *));
int(**pauth)(char *, char *),
int *addheaders);
int ws_registerhandler(WSHANDLE ws, char *regex,
void(*handler)(WS_CONNINFO*),
int(*auth)(char *, char *));
int(*auth)(char *, char *),
int addheaders);
int ws_decodepassword(char *header, char **username, char **password);
int ws_testrequestheader(WS_CONNINFO *pwsc, char *header, char *value);
/*
* Globals
*/
pthread_mutex_t munsafe=PTHREAD_MUTEX_INITIALIZER;
char *ws_dow[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
char *ws_moy[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec" };
/*
* ws_lock_unsafe
@ -517,6 +525,9 @@ void *ws_dispatcher(void *arg) {
int connection_done=0;
int can_dispatch;
char *auth, *username, *password;
int hdrs,handler;
time_t now;
struct tm now_tm;
void (*req_handler)(WS_CONNINFO*);
int(*auth_handler)(char *, char *);
@ -546,6 +557,7 @@ void *ws_dispatcher(void *arg) {
pwsc->error=EINVAL;
free(argvp[0]);
ws_returnerror(pwsc,400,"Bad request");
ws_close(pwsc);
return NULL;
}
@ -558,6 +570,7 @@ void *ws_dispatcher(void *arg) {
pwsc->error=EINVAL;
free(argvp[0]);
ws_returnerror(pwsc,501,"Not implemented");
ws_close(pwsc);
return NULL;
}
@ -575,18 +588,6 @@ void *ws_dispatcher(void *arg) {
* decide whether or not this is a persistant
* connection */
pwsc->close=!ws_testarg(&pwsc->request_headers,"connection",
"keep-alive");
ws_addarg(&pwsc->response_headers,"Connection",
pwsc->close ? "close" : "keep-alive");
ws_addarg(&pwsc->response_headers,"Server",
"mt-daapd/%s",VERSION);
ws_addarg(&pwsc->response_headers,"Content-Type","text/html");
ws_addarg(&pwsc->response_headers,"Content-Language","en_us");
pwsc->uri=strdup(argvp[1]);
free(argvp[0]);
@ -597,6 +598,7 @@ void *ws_dispatcher(void *arg) {
DPRINTF(ERR_FATAL,"Thread %d: Error allocation URI\n",
pwsc->threadno);
ws_returnerror(pwsc,500,"Internal server error");
ws_close(pwsc);
return NULL;
}
@ -625,8 +627,37 @@ void *ws_dispatcher(void *arg) {
if(pwsc->request_type == RT_POST)
ws_getpostvars(pwsc);
hdrs=1;
handler=ws_findhandler(pwsp,pwsc,&req_handler,&auth_handler,&hdrs);
time(&now);
DPRINTF(ERR_DEBUG,"Thread %d: Time is %d seconds after epoch\n",
pwsc->threadno,now);
gmtime_r(&now,&now_tm);
DPRINTF(ERR_DEBUG,"Thread %d: Setting time header\n",pwsc->threadno);
ws_addarg(&pwsc->response_headers,"Date",
"%s, %d %s %d %02d:%02d:%02d GMT",
ws_dow[now_tm.tm_wday],now_tm.tm_mday,
ws_moy[now_tm.tm_mon],now_tm.tm_year + 1900,
now_tm.tm_hour,now_tm.tm_min,now_tm.tm_sec);
pwsc->close=ws_testarg(&pwsc->request_headers,"connection",
"close");
if(hdrs) {
ws_addarg(&pwsc->response_headers,"Connection",
pwsc->close ? "close" : "keep-alive");
ws_addarg(&pwsc->response_headers,"Server",
"mt-daapd/%s",VERSION);
ws_addarg(&pwsc->response_headers,"Content-Type","text/html");
ws_addarg(&pwsc->response_headers,"Content-Language","en_us");
}
/* Find the appropriate handler and dispatch it */
if(ws_findhandler(pwsp,pwsc,&req_handler,&auth_handler) == -1) {
if(handler == -1) {
DPRINTF(ERR_DEBUG,"Thread %d: Using default handler.\n",
pwsc->threadno);
ws_defaulthandler(pwsp,pwsc);
@ -651,15 +682,15 @@ void *ws_dispatcher(void *arg) {
"Basic realm=\"webserver\"");
pwsc->close=1;
ws_returnerror(pwsc,401,"Unauthorized");
ws_close(pwsc);
return NULL;
}
}
if(req_handler)
req_handler(pwsc);
else
ws_defaulthandler(pwsp,pwsc);
}
}
if((pwsc->close)||(pwsc->error))
connection_done=1;
@ -713,7 +744,6 @@ int ws_returnerror(WS_CONNINFO *pwsc,int error, char *description) {
ws_writefd(pwsc,"</i></BODY>\r\n</HTML>\r\n");
ws_close(pwsc);
return 0;
}
@ -797,6 +827,7 @@ void ws_defaulthandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc) {
pwsc->error=errno;
DPRINTF(ERR_WARN,"Cannot resolve %s\n",path);
ws_returnerror(pwsc,404,"Not found");
ws_close(pwsc);
return;
}
@ -809,6 +840,7 @@ void ws_defaulthandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc) {
DPRINTF(ERR_WARN,"Thread %d: Requested file %s out of root\n",
pwsc->threadno,resolved_path);
ws_returnerror(pwsc,403,"Forbidden");
ws_close(pwsc);
return;
}
@ -818,6 +850,7 @@ void ws_defaulthandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc) {
DPRINTF(ERR_WARN,"Thread %d: Error opening %s: %s\n",
pwsc->threadno,resolved_path,strerror(errno));
ws_returnerror(pwsc,404,"Not found");
ws_close(pwsc);
return;
}
@ -845,6 +878,18 @@ void ws_defaulthandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc) {
}
/*
* ws_testrequestheader
*
* Check to see if a request header is a particular value
*
* Example:
*
*/
int ws_testrequestheader(WS_CONNINFO *pwsc, char *header, char *value) {
return ws_testarg(&pwsc->request_headers,header,value);
}
/*
* ws_testarg
*
@ -1025,7 +1070,8 @@ char *ws_urldecode(char *string) {
*/
int ws_registerhandler(WSHANDLE ws, char *regex,
void(*handler)(WS_CONNINFO*),
int(*auth)(char *, char *)) {
int(*auth)(char *, char *),
int addheaders) {
WS_HANDLER *phandler;
WS_PRIVATE *pwsp = (WS_PRIVATE *)ws;
@ -1041,6 +1087,7 @@ int ws_registerhandler(WSHANDLE ws, char *regex,
phandler->req_handler=handler;
phandler->auth_handler=auth;
phandler->addheaders=addheaders;
ws_lock_unsafe();
phandler->next=pwsp->handlers.next;
@ -1060,7 +1107,8 @@ int ws_registerhandler(WSHANDLE ws, char *regex,
*/
int ws_findhandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc,
void(**preq)(WS_CONNINFO*),
int(**pauth)(char *, char *)) {
int(**pauth)(char *, char *),
int *addheaders) {
WS_HANDLER *phandler=pwsp->handlers.next;
ws_lock_unsafe();
@ -1074,6 +1122,7 @@ int ws_findhandler(WS_PRIVATE *pwsp, WS_CONNINFO *pwsc,
DPRINTF(ERR_DEBUG,"Thread %d: URI Match!\n",pwsc->threadno);
*preq=phandler->req_handler;
*pauth=phandler->auth_handler;
*addheaders=phandler->addheaders;
ws_unlock_unsafe();
return 0;
}
@ -1202,8 +1251,15 @@ int ws_decodepassword(char *header, char **username, char **password) {
*
* Simple wrapper around the CONNINFO response headers
*/
int ws_addresponseheader(WS_CONNINFO *pwsc, char *header, char *val) {
return ws_addarg(&pwsc->response_headers,header,val);
int ws_addresponseheader(WS_CONNINFO *pwsc, char *header, char *fmt, ...) {
va_list ap;
char value[MAX_LINEBUFFER];
va_start(ap,fmt);
vsnprintf(value,sizeof(value),fmt,ap);
va_end(ap);
return ws_addarg(&pwsc->response_headers,header,value);
}
/*

View File

@ -71,12 +71,14 @@ extern WSHANDLE ws_start(WSCONFIG *config);
extern int ws_stop(WSHANDLE ws);
extern int ws_registerhandler(WSHANDLE ws, char *regex,
void(*handler)(WS_CONNINFO*),
int(*auth)(char *, char *));
int(*auth)(char *, char *),
int addheaders);
/* for handlers */
extern void ws_close(WS_CONNINFO *pwsc);
extern int ws_returnerror(WS_CONNINFO *pwsc, int error, char *description);
extern int ws_addresponseheader(WS_CONNINFO *pwsc, char *header, char *val);
extern int ws_addresponseheader(WS_CONNINFO *pwsc, char *header, char *fmt, ...);
extern int ws_writefd(WS_CONNINFO *pwsc, char *fmt, ...);
extern char *ws_getvar(WS_CONNINFO *pwsc, char *var);
extern int ws_testrequestheader(WS_CONNINFO *pwsc, char *header, char *value);
#endif /* _WEBSERVER_H_ */