⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webhttpd.c

📁 motion motion
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *      webhttpd.c * *      HTTP Control interface for motion. * *      Specs : http://www.lavrsen.dk/twiki/bin/view/Motion/MotionHttpAPI * *      Copyright 2004-2005 by Angel Carpintero  (ack@telefonica.net) *      This software is distributed under the GNU Public License Version 2 *      See also the file 'COPYING'. * */#include "webhttpd.h"	/* already includes motion.h */#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <stddef.h>#include <stdint.h> pthread_mutex_t httpd_mutex;int warningkill; // This is a dummy variable use to kill warnings when not checking sscanf and similar functionsstatic const char* ini_template =	"<html><head><title>Motion "VERSION"</title></head>\n"	"<body>\n";static const char *set_template =	"<html><head><script language='javascript'>"	"function show(){top.location.href="	"'set?'+document.n.onames.options[document.n.onames.selectedIndex].value"	"+'='+document.s.valor.value;"	"}</script>\n<title>Motion "VERSION"</title>\n"	"</head><body>\n";static const char* end_template =	"</body>\n"	"</html>\n";static const char* ok_response =	"HTTP/1.1 200 OK\r\n"	"Server: Motion-httpd/"VERSION"\r\n"	"Connection: close\r\n"	"Max-Age: 0\r\n"	"Expires: 0\r\n"	"Cache-Control: no-cache\r\n"	"Cache-Control: private\r\n"	"Pragma: no-cache\r\n"	"Content-type: text/html\r\n\r\n";static const char* ok_response_raw =	"HTTP/1.1 200 OK\r\n"	"Server: Motion-httpd/"VERSION"\r\n"	"Connection: close\r\n"	"Max-Age: 0\r\n"	"Expires: 0\r\n"	"Cache-Control: no-cache\r\n"	"Cache-Control: private\r\n"	"Pragma: no-cache\r\n"	"Content-type: text/plain\r\n\r\n";static const char* bad_request_response =	"HTTP/1.0 400 Bad Request\r\n"	"Content-type: text/html\r\n\r\n"	"<html>\n"	"<body>\n"	"<h1>Bad Request</h1>\n"	"<p>The server did not understand your request.</p>\n"	"</body>\n"	"</html>\n";static const char* bad_request_response_raw =	"HTTP/1.0 400 Bad Request\r\n"	"Content-type: text/plain\r\n\r\n"	"Bad Request";static const char* not_found_response_template =	"HTTP/1.0 404 Not Found\r\n"	"Content-type: text/html\r\n\r\n"	"<html>\n"	"<body>\n"	"<h1>Not Found</h1>\n"	"<p>The requested URL was not found on the server.</p>\n"	"</body>\n"	"</html>\n";static const char* not_found_response_template_raw =	"HTTP/1.0 404 Not Found\r\n"	"Content-type: text/plain\r\n\r\n"	"Not Found";static const char* not_found_response_valid =	"HTTP/1.0 404 Not Valid\r\n"	"Content-type: text/html\r\n\r\n"	"<html>\n"	"<body>\n"	"<h1>Not Valid</h1>\n"	"<p>The requested URL is not valid.</p>\n"	"</body>\n"	"</html>\n";static const char* not_found_response_valid_raw =	"HTTP/1.0 404 Not Valid\r\n"	"Content-type: text/plain\r\n\r\n"	"The requested URL is not valid.";static const char* not_valid_syntax =	"HTTP/1.0 404 Not Valid Syntax\r\n"	"Content-type: text/html\r\n\r\n"	"<html>\n"	"<body>\n"	"<h1>Not Valid Syntax</h1>\n"	"</body>\n"	"</html>\n";static const char* not_valid_syntax_raw =	"HTTP/1.0 404 Not Valid Syntax\r\n"	"Content-type: text/plain\r\n\r\n"	"Not Valid Syntax\n";static const char* not_track =	"HTTP/1.0 200 OK\r\n"	"Content-type: text/html\r\n\r\n"	"<html>\n"	"<body>\n"	"<h1>Tracking Not Enabled</h1>\n";static const char* not_track_raw =	"HTTP/1.0 200 OK\r\n"	"Content-type: text/plain\r\n\r\n"	"Tracking Not Enabled";static const char* track_error =	"HTTP/1.0 200 OK\r\n"	"Content-type: text/html\r\n\r\n"	"<html>\n"	"<body>\n"	"<h1>Track Error</h1>\n";static const char* track_error_raw =	"HTTP/1.0 200 OK\r\n"	"Content-type: text/plain\r\n\r\n"	"Track Error";static const char* error_value =	"HTTP/1.0 200 OK\r\n"	"Content-type: text/html\r\n\r\n"	"<html>\n"	"<body>\n"	"<h1>Value Error</h1>\n";static const char* error_value_raw =	"HTTP/1.0 200 OK\r\n"	"Content-type: text/plain\r\n\r\n"	"Value Error";	static const char* not_found_response_valid_command =	"HTTP/1.0 404 Not Valid Command\r\n"	"Content-type: text/html\r\n\r\n"	"<html>\n"	"<body>\n"	"<h1>Not Valid Command</h1>\n"	"<p>The requested URL is not valid Command.</p>\n"	"</body>\n"	"</html>\n";static const char* not_found_response_valid_command_raw =	"HTTP/1.0 404 Not Valid Command\r\n"	"Content-type: text/plain\n\n"	"Not Valid Command\n";static const char* bad_method_response_template =	"HTTP/1.0 501 Method Not Implemented\r\n"	"Content-type: text/html\r\n\r\n"	"<html>\n"	"<body>\n"	"<h1>Method Not Implemented</h1>\n"	"<p>The method is not implemented by this server.</p>\n"	"</body>\n"	"</html>\n";static const char* bad_method_response_template_raw =	"HTTP/1.0 501 Method Not Implemented\r\n"	"Content-type: text/plain\r\n\r\n"	"Method Not Implemented\n";static const char *request_auth_response_template=	"HTTP/1.0 401 Authorization Required\r\n"	"WWW-Authenticate: Basic realm=\"Motion Security Access\"\r\n";static void send_template_ini_client(int client_socket, const char* template){	ssize_t nwrite = 0;	nwrite = write(client_socket, ok_response, strlen (ok_response));	nwrite += write(client_socket, template, strlen(template));	if (nwrite != (ssize_t)(strlen(ok_response) + strlen(template)))		motion_log(LOG_ERR, 1, "httpd send_template_ini_client");}static void send_template_ini_client_raw(int client_socket){	ssize_t nwrite = 0;	nwrite = write(client_socket, ok_response_raw, strlen (ok_response_raw));	if (nwrite != (ssize_t)strlen(ok_response_raw))		motion_log(LOG_ERR, 1, "httpd send_template_ini_client_raw");}static void send_template(int client_socket, char *res){	ssize_t nwrite = 0;	nwrite = write(client_socket, res, strlen(res));	if ( nwrite != (ssize_t)strlen(res))		motion_log(LOG_ERR, 1, "httpd send_template failure write");}static void send_template_raw(int client_socket, char *res){	ssize_t nwrite = 0;	nwrite = write(client_socket, res, strlen(res));}static void send_template_end_client(int client_socket){	ssize_t nwrite = 0;	nwrite = write(client_socket, end_template, strlen(end_template));}static void response_client(int client_socket, const char* template, char *back){	ssize_t nwrite = 0;	nwrite = write(client_socket, template, strlen(template));	if (back != NULL) {		send_template(client_socket, back);		send_template_end_client(client_socket);	}}/* * check_authentication * * return 1 on success * return 0 on error */#if 0static unsigned short int check_authentication(char *authentication, char *auth_base64, size_t size_auth, const char *conf_auth){	unsigned short int ret=0;	char *userpass = NULL;	authentication = (char *) mymalloc(BASE64_LENGTH(size_auth) + 1);	userpass = mymalloc(size_auth + 4);	/* base64_encode can read 3 bytes after the end of the string, initialize it */	memset(userpass, 0, size_auth + 4);	strcpy(userpass, conf_auth);	base64_encode(userpass, authentication, size_auth);	free(userpass);	if (!strcmp(authentication, auth_base64))		ret=1;	return ret;}#endifstatic char *replace(const char *str, const char *old, const char *new){    char *ret, *r;    const char *p, *q;    size_t oldlen = strlen(old);    size_t count, retlen, newlen = strlen(new);    if (oldlen != newlen) {        for (count = 0, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen)            count++;        /* this is undefined if p - str > PTRDIFF_MAX */        retlen = p - str + strlen(p) + count * (newlen - oldlen);    } else        retlen = strlen(str);    ret = malloc(retlen + 1);    for (r = ret, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen) {        /* this is undefined if q - p > PTRDIFF_MAX */        ptrdiff_t l = q - p;        memcpy(r, p, l);        r += l;        memcpy(r, new, newlen);        r += newlen;    }    strcpy(r, p);    return ret;} /*   This function decode the values from GET request following the http RFC.*/static void url_decode(char *urlencoded, size_t length){	char *data=urlencoded;	char *urldecoded=urlencoded;	while (length > 0)  {		if (*data == '%') {			char c[3];			int i;			data++;			length--;			c[0] = *data++;			length--;			c[1] = *data;			c[2] = 0;			warningkill = sscanf(c, "%x", &i);			if (i < 128)				*urldecoded++ = (char)i;			else {				*urldecoded++ = '%';				*urldecoded++ = c[0];				*urldecoded++ = c[1];			}		} else if (*data=='+') {			*urldecoded++=' ';				}		else {			*urldecoded++=*data;		}		data++;		length--;	}	*urldecoded = '\0';}/*    This function manages/parses the config action for motion ( set , get , write , list ).    return 1 to exit from function.*/static unsigned short int config(char *pointer, char *res, unsigned short int length_uri, 				unsigned short int thread, int client_socket, void *userdata){	char question;	char command[256] = {'\0'};	unsigned short int i;	struct context **cnt = userdata;	warningkill = sscanf (pointer, "%255[a-z]%c", command , &question);	if (!strcmp(command,"list")) {		pointer = pointer + 4;		length_uri = length_uri - 4;		if (length_uri == 0) {			const char *value = NULL;			char *retval = NULL;			/*call list*/			if (cnt[0]->conf.control_html_output) {				send_template_ini_client(client_socket, ini_template);				sprintf(res, "<a href=/%hu/config>&lt;&ndash; back</a><br><br>\n<b>Thread %hu</b>\n<ul>", thread, thread);				send_template(client_socket, res);				for (i=0; config_params[i].param_name != NULL; i++) {					if ((thread != 0) && (config_params[i].main_thread)) 						continue;					value = config_params[i].print(cnt, NULL, i, thread);					if (value == NULL) {						retval=NULL;											/* Only get the thread value for main thread */ 						if (thread == 0)							config_params[i].print(cnt, &retval, i, thread);											/* thread value*/												if (retval) {														if (!strcmp(retval,"")) {								free(retval);								retval = strdup("No threads");							} else {								char *temp=retval;								size_t retval_miss = 0;								size_t retval_len = strlen(retval);								unsigned short int ind=0;								char thread_strings[1024]={'\0'};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -