mjpg-streamer/plugins/output_http/httpd.h

196 lines
5.8 KiB
C

/*******************************************************************************
# #
# MJPG-streamer allows to stream JPG frames from an input-plugin #
# to several output plugins #
# #
# Copyright (C) 2007 Tom Stöveken #
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
# #
*******************************************************************************/
#define IO_BUFFER 256
#define BUFFER_SIZE 1024
/* the boundary is used for the M-JPEG stream, it separates the multipart stream of pictures */
#define BOUNDARY "boundarydonotcross"
/*
* this defines the buffer size for a JPG-frame
* selecting to large values will allocate much wasted RAM for each buffer
* selecting to small values will lead to crashes due to to small buffers
*/
#define MAX_FRAME_SIZE (256*1024)
#define TEN_K (10*1024)
/*
* Standard header to be send along with other header information like mimetype.
*
* The parameters should ensure the browser does not cache our answer.
* A browser should connect for each file and not serve files from his cache.
* Using cached pictures would lead to showing old/outdated pictures
* Many browser seem to ignore, or at least not always obey those headers
* since i observed caching of files from time to time.
*/
#define STD_HEADER "Connection: close\r\n" \
"Server: MJPG-Streamer/0.2\r\n" \
"Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n" \
"Pragma: no-cache\r\n" \
"Expires: Mon, 3 Jan 2000 12:34:56 GMT\r\n"
/*
* Maximum number of server sockets (i.e. protocol families) to listen.
*/
#define MAX_SD_LEN 50
/*
* Only the following fileypes are supported.
*
* Other filetypes are simply ignored!
* This table is a 1:1 mapping of files extension to a certain mimetype.
*/
static const struct {
const char *dot_extension;
const char *mimetype;
} mimetypes[] = {
{ ".html", "text/html" },
{ ".htm", "text/html" },
{ ".css", "text/css" },
{ ".js", "text/javascript" },
{ ".txt", "text/plain" },
{ ".jpg", "image/jpeg" },
{ ".jpeg", "image/jpeg" },
{ ".png", "image/png"},
{ ".gif", "image/gif" },
{ ".ico", "image/x-icon" },
{ ".swf", "application/x-shockwave-flash" },
{ ".cab", "application/x-shockwave-flash" },
{ ".jar", "application/java-archive" },
{ ".json", "application/json" }
};
/* the webserver determines between these values for an answer */
typedef enum {
A_UNKNOWN,
A_SNAPSHOT,
A_SNAPSHOT_WXP,
A_STREAM,
A_STREAM_WXP,
A_COMMAND,
A_FILE,
A_CGI,
A_TAKE,
A_INPUT_JSON,
A_OUTPUT_JSON,
A_PROGRAM_JSON,
#ifdef MANAGMENT
A_CLIENTS_JSON
#endif
} answer_t;
/*
* the client sends information with each request
* this structure is used to store the important parts
*/
typedef struct {
answer_t type;
char *parameter;
char *client;
char *credentials;
char *query_string;
} request;
/* the iobuffer structure is used to read from the HTTP-client */
typedef struct {
int level; /* how full is the buffer */
char buffer[IO_BUFFER]; /* the data */
} iobuffer;
/* store configuration for each server instance */
typedef struct {
int port;
char *hostname;
char *credentials;
char *www_folder;
char nocommands;
} config;
/* context of each server thread */
typedef struct {
int sd[MAX_SD_LEN];
int sd_len;
int id;
globals *pglobal;
pthread_t threadID;
config conf;
} context;
#if defined(MANAGMENT)
/*
* this struct is used to hold information from the clients address, and last picture take time
*/
typedef struct _client_info {
struct _client_info *next;
char *address;
struct timeval last_take_time;
} client_info;
struct {
client_info **infos;
unsigned int client_count;
pthread_mutex_t mutex;
} client_infos;
#endif
/*
* this struct is just defined to allow passing all necessary details to a worker thread
* "cfd" is for connected/accepted filedescriptor
*/
typedef struct {
context *pc;
int fd;
#ifdef MANAGMENT
client_info *client;
#endif
} cfd;
/* prototypes */
void *server_thread(void *arg);
void send_error(int fd, int which, char *message);
void send_output_JSON(int fd, int plugin_number);
void send_input_JSON(int fd, int plugin_number);
void send_program_JSON(int fd);
void check_JSON_string(char *source, char *destination);
#ifdef MANAGMENT
client_info *add_client(char *address);
int check_client_status(client_info *client);
void update_client_timestamp(client_info *client);
void send_clients_JSON(int fd);
#endif