📄 webhttpd.c
字号:
response_client(client_socket, not_found_response_valid_command_raw, NULL); } } else if (length_uri == 0) { if (cnt[0]->conf.control_html_output) { send_template_ini_client(client_socket, ini_template); sprintf(res,"<b>Thread %d</b>\n" "<form action='auto'><select name='value'>\n" "<option value='0'>Disable</option><option value='1'>Enable</option>\n" "<option value='status'>status</option>\n" "</select><input type=submit value='set'>\n" "</form>\n" "<a href=/%d/track><- back</a>\n", thread, thread); send_template(client_socket, res); send_template_end_client(client_socket); } else { send_template_ini_client_raw(client_socket); sprintf(res,"auto needs a value 0,1 or status\n"); send_template_raw(client_socket, res); } } else { if (cnt[0]->conf.control_html_output) response_client(client_socket, not_found_response_valid_command, NULL); else response_client(client_socket, not_found_response_valid_command_raw, NULL); } } else { if (cnt[0]->conf.control_html_output) response_client(client_socket, not_found_response_valid_command, NULL); else response_client(client_socket, not_found_response_valid_command_raw, NULL); } return 1;}/* parses the action requested for motion ( config , action , detection , track ) and call to action function if needed.*/static int handle_get(int client_socket, const char* url, void *userdata){ struct context **cnt=userdata; if (*url == '/' ){ int i=0; char *res=NULL; res = malloc(2048); /* get the number of threads */ while (cnt[++i]); /* ROOT_URI -> GET / */ if (! (strcmp (url, "/")) ) { int y=0; if (cnt[0]->conf.control_html_output) { send_template_ini_client(client_socket,ini_template); sprintf(res,"<b>Motion "VERSION" Running [%d] Threads</b><br>\n" "<a href='/0/'>All</a><br>\n", i); send_template(client_socket, res); for (y=1; y<i; y++) { sprintf(res,"<a href='/%d/'>Thread %d</a><br>\n", y, y); send_template(client_socket, res); } send_template_end_client(client_socket); } else { send_template_ini_client_raw(client_socket); sprintf(res,"Motion "VERSION" Running [%d] Threads\n0\n",i); send_template_raw(client_socket, res); for (y=1; y<i; y++) { sprintf(res, "%d\n", y); send_template_raw(client_socket, res); } } } else { char command[256] = {'\0'}; char slash; int thread = -1; int length_uri = 0; char *pointer = (char *)url; length_uri = strlen(url); /* Check for Thread number first -> GET /2 */ pointer++; length_uri--; warningkill = sscanf (pointer, "%i%c", &thread, &slash); if ((thread != -1) && (thread < i)) { /* thread_number found */ if (thread > 9){ pointer = pointer + 2; length_uri = length_uri - 2; }else{ pointer++; length_uri--; } if (slash == '/') { /* slash found /2/ */ pointer++; length_uri--; } if (length_uri!=0) { warningkill = sscanf (pointer, "%256[a-z]%c" , command , &slash); /* config */ if (!strcmp(command,"config")) { pointer = pointer + 6; length_uri = length_uri - 6; if (length_uri == 0) { if (cnt[0]->conf.control_html_output) { send_template_ini_client(client_socket, ini_template); sprintf(res,"<b>Thread %d</b><br>\n" "<a href=/%d/config/list>list</a><br>\n" "<a href=/%d/config/write>write</a><br>\n" "<a href=/%d/config/set>set</a><br>\n" "<a href=/%d/config/get>get</a><br>\n" "<a href=/%d/><- back</a>\n", thread, thread, thread, thread, thread, thread); send_template(client_socket, res); send_template_end_client(client_socket); } else { send_template_ini_client_raw(client_socket); sprintf(res,"Thread %d\nlist\nwrite\nset\nget\n", thread); send_template_raw(client_socket, res); } } else if ((slash == '/') && (length_uri >= 4)) { /*call config() */ pointer++; length_uri--; config(pointer, res, length_uri, thread, client_socket, cnt); } else { if (cnt[0]->conf.control_html_output) response_client(client_socket, not_found_response_valid_command, NULL); else response_client(client_socket, not_found_response_valid_command_raw, NULL); } } /* action */ else if (!strcmp(command,"action")) { pointer = pointer + 6; length_uri = length_uri - 6; /* call action() */ if (length_uri == 0) { if (cnt[0]->conf.control_html_output) { send_template_ini_client(client_socket, ini_template); sprintf(res,"<b>Thread %d</b><br>\n" "<a href=/%d/action/makemovie>makemovie</a><br>\n" "<a href=/%d/action/snapshot>snapshot</a><br>\n" "<a href=/%d/action/restart>restart</a><br>\n" "<a href=/%d/action/quit>quit</a><br>\n" "<a href=/%d/><- back</a>\n", thread,thread,thread,thread,thread,thread); send_template(client_socket, res); send_template_end_client(client_socket); } else { send_template_ini_client_raw(client_socket); sprintf(res,"Thread %d\nmakemovie\nsnapshot\nrestart\nquit\n", thread); send_template_raw(client_socket, res); } } else if ((slash == '/') && (length_uri > 4)) { int ret = 1; pointer++; length_uri--; ret = action(pointer, res, length_uri, thread, client_socket, cnt); free(res); return ret; } else { if (cnt[0]->conf.control_html_output) response_client(client_socket, not_found_response_valid_command,NULL); else response_client(client_socket, not_found_response_valid_command_raw,NULL); } } /* detection */ else if (!strcmp(command,"detection")) { pointer = pointer + 9; length_uri = length_uri - 9; if (length_uri == 0) { if (cnt[0]->conf.control_html_output) { send_template_ini_client(client_socket, ini_template); sprintf(res,"<b>Thread %d</b><br>\n" "<a href=/%d/detection/status>status</a><br>\n" "<a href=/%d/detection/start>start</a><br>\n" "<a href=/%d/detection/pause>pause</a><br>\n" "<a href=/%d/><- back</a>\n", thread, thread, thread, thread, thread); send_template(client_socket, res); send_template_end_client(client_socket); } else { send_template_ini_client_raw(client_socket); sprintf(res,"Thread %d\nstatus\nstart\npause\n", thread); send_template_raw(client_socket, res); } } else if ((slash == '/') && (length_uri > 5)) { pointer++; length_uri--; /* call detection() */ detection(pointer, res, length_uri, thread, client_socket, cnt); } else { if (cnt[0]->conf.control_html_output) response_client(client_socket, not_found_response_valid_command, NULL); else response_client(client_socket, not_found_response_valid_command_raw, NULL); } } /* track */ else if (!strcmp(command,"track")) { pointer = pointer + 5; length_uri = length_uri - 5; if (length_uri == 0) { if (cnt[0]->conf.control_html_output) { send_template_ini_client(client_socket, ini_template); sprintf(res,"<b>Thread %d</b><br>\n" "<a href=/%d/track/set>track set pan/tilt</a><br>\n" "<a href=/%d/track/auto>track auto</a><br>\n" "<a href=/%d/track/status>track status</a><br>\n" "<a href=/%d/><- back</a>\n", thread, thread, thread, thread, thread); send_template(client_socket, res); send_template_end_client(client_socket); } else { send_template_ini_client_raw(client_socket); sprintf(res,"Thread %d\nset pan/tilt\nauto\nstatus\n", thread); send_template_raw(client_socket, res); } } else if ((slash == '/') && (length_uri >= 4)) { pointer++; length_uri--; /* call track() */ if (cnt[thread]->track.type) { track(pointer, res, length_uri, thread, client_socket, cnt); } else { /* error track not enable */ if (cnt[0]->conf.control_html_output) { sprintf(res,"<a href=/%d/><- back</a>\n",thread); response_client(client_socket, not_track,res); } else response_client(client_socket, not_track_raw,NULL); } } else { if (cnt[0]->conf.control_html_output) { sprintf(res,"<a href=/%d/><- back</a>\n",thread); response_client(client_socket, not_found_response_valid_command, res); } else response_client(client_socket, not_found_response_valid_command_raw, NULL); } } else { if (cnt[0]->conf.control_html_output) { sprintf(res,"<a href=/%d/><- back</a>\n",thread); response_client(client_socket, not_found_response_valid_command, res); } else response_client(client_socket, not_found_response_valid_command_raw, NULL); } } else { /* /thread_number/ requested */ if (cnt[0]->conf.control_html_output) { send_template_ini_client(client_socket,ini_template); sprintf(res,"<b>Thread %d</b><br>\n" "<a href='/%d/config'>config</a><br>\n" "<a href='/%d/action'>action</a><br>\n" "<a href='/%d/detection'>detection</a><br>\n" "<a href='/%d/track'>track</a><br>\n" "<a href=/><- back</a>\n", thread, thread, thread, thread, thread); send_template(client_socket, res); send_template_end_client(client_socket); } else { send_template_ini_client_raw(client_socket); sprintf(res,"Thread %d\nconfig\naction\ndetection\ntrack\n", thread); send_template_raw(client_socket, res); } } } else { if (cnt[0]->conf.control_html_output) { sprintf(res,"<a href=/><- back</a>\n"); response_client(client_socket, not_found_response_valid, res); } else response_client(client_socket, not_found_response_valid_raw, NULL); } } free(res); } else { if (cnt[0]->conf.control_html_output) response_client(client_socket, not_found_response_template,NULL); else response_client(client_socket, not_found_response_template_raw,NULL); } return 1;}/* -TODO- As usually web clients uses nonblocking connect/read read_client should handle nonblocking sockets.*/static int read_client(int client_socket, void *userdata, char *auth){ int alive = 1; int ret = 1; char buffer[1024] = {'\0'}; int length = 1024; struct context **cnt = userdata; /* lock the mutex */ pthread_mutex_lock(&httpd_mutex); while (alive) { int nread = 0, readb = -1; nread = read (client_socket, buffer, length); if (nread <= 0) { motion_log(LOG_ERR, 1, "httpd First read"); pthread_mutex_unlock(&httpd_mutex); return -1; } else { char method[sizeof (buffer)]; char url[sizeof (buffer)]; char protocol[sizeof (buffer)]; char *authentication=NULL; buffer[nread] = '\0'; warningkill = sscanf (buffer, "%s %s %s", method, url, protocol); while ((strstr (buffer, "\r\n\r\n") == NULL) && (readb!=0) && (nread < length)){ readb = read (client_socket, buffer+nread, sizeof (buffer) - nread); if (readb == -1){ nread = -1; break; } nread +=readb; if (nread > length) { motion_log(LOG_ERR, 1, "httpd End buffer reached waiting for buffer ending"); break; } buffer[nread] = '\0'; } /* Make sure the last read didn't fail. If it did, there's a problem with the connection, so give up. */ if (nread == -1) { motion_log(LOG_ERR, 1, "httpd READ"); pthread_mutex_unlock(&httpd_mutex); return -1; } alive = 0; /* Check Protocol */ if (strcmp (protocol, "HTTP/1.0") && strcmp (protocol, "HTTP/1.1")) { /* We don't understand this protocol. Report a bad response. */ if (cnt[0]->conf.control_html_output) warningkill = write (client_socket, bad_request_response, sizeof (bad_request_response)); else warningkill = write (client_socket, bad_request_response_raw, sizeof (bad_request_response_raw)); pthread_mutex_unlock(&httpd_mutex); return -1; } else if (strcmp (method, "GET")) { /* This server only implements the GET method. If client uses other method, report the failure. */ char response[1024]; if (cnt[0]->conf.control_html_output) snprintf (response, sizeof (response),bad_method_response_template, method); else snprintf (response, sizeof (response),bad_method_response_template_raw, method); warningkill = write (client_socket, response, strlen (response)); pthread_mutex_unlock(&httpd_mutex); return -1; } else if ( auth != NULL) { if ( (authentication = strstr(buffer,"Basic")) ) { char *end_auth = NULL; authentication = authentication + 6; if ( (end_auth = strstr(authentication,"\r\n")) ) { authentication[end_auth - authentication] = '\0'; } else { char response[1024]; snprintf (response, sizeof (response),request_auth_response_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -