Newer
Older
/* websrvr.c */
/* Synchronet Web Server */
/* $Id$ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* 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; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
/*
* General notes: (ToDo stuff)
*
* Support the ident protocol... the standard log format supports it.
* Add in support to pass connections through to a different webserver...
* probobly in access.ars... with like a simplified mod_rewrite.
* This would allow people to run apache and Synchronet as the same site.
//#define ONE_JS_RUNTIME
#if defined(__unix__)
#include <sys/wait.h> /* waitpid() */
#include <sys/types.h>
#include <signal.h> /* kill() */
#define JAVASCRIPT
#undef SBBS /* this shouldn't be defined unless building sbbs.dll/libsbbs.so */
#include "sockwrap.h" /* sendfilesocket() */
#include "threadwrap.h"
#include "semwrap.h"
#include "websrvr.h"
#include "js_rtpool.h"
#include "js_request.h"
static const char* server_name="Synchronet Web Server";
static const char* newline="\r\n";
static const char* http_scheme="http://";
static const size_t http_scheme_len=7;
static const char* error_301="301 Moved Permanently";
static const char* error_302="302 Moved Temporarily";
static const char* error_404="404 Not Found";
static const char* error_416="416 Requested Range Not Satisfiable";
static const char* error_500="500 Internal Server Error";
static const char* unknown="<unknown>";
#define MAX_REQUEST_LINE 1024 /* NOT including terminator */
#define MAX_HEADERS_SIZE 16384 /* Maximum total size of all headers
(Including terminator )*/
#define MAX_REDIR_LOOPS 20 /* Max. times to follow internal redirects for a single request */
#define MAX_POST_LEN 1048576 /* Max size of body for POSTS */
#define OUTBUF_LEN 20480 /* Size of output thread ring buffer */
enum {
CLEANUP_SSJS_TMP_FILE
,CLEANUP_POST_DATA
,MAX_CLEANUPS
static scfg_t scfg;
static volatile BOOL http_logging_thread_running=FALSE;
static protected_int32_t active_clients;
static volatile ulong sockets=0;
static volatile BOOL terminate_server=FALSE;
static volatile BOOL terminate_http_logging_thread=FALSE;
static volatile ulong thread_count=0;
static SOCKET server_socket=INVALID_SOCKET;
static char revision[16];
static char root_dir[MAX_PATH+1];
static char error_dir[MAX_PATH+1];
static char temp_dir[MAX_PATH+1];
static char cgi_env_ini[MAX_PATH+1];
static char default_auth_list[MAX_PATH+1];
static volatile time_t uptime=0;
static volatile ulong served=0;
static web_startup_t* startup=NULL;
static js_server_props_t js_server_props;
static str_list_t recycle_semfiles;
static str_list_t shutdown_semfiles;
static str_list_t cgi_env;
static volatile ulong session_threads=0;
static named_string_t** mime_types;
static named_string_t** cgi_handlers;
static named_string_t** xjs_handlers;
/* Logging stuff */
link_list_t log_list;
struct log_data {
char *hostname;
char *ident;
char *user;
char *request;
char *referrer;
char *agent;
char *vhost;
int status;
unsigned int size;
struct tm completed;
};
enum auth_type {
AUTHENTICATION_UNKNOWN
,AUTHENTICATION_BASIC
,AUTHENTICATION_DIGEST
};
char *auth_type_names[4] = {
"Unknown"
,"Basic"
,"Digest"
,NULL
};
enum algorithm {
ALGORITHM_UNKNOWN
,ALGORITHM_MD5
,ALGORITHM_MD5_SESS
};
enum qop_option {
QOP_NONE
,QOP_AUTH
,QOP_AUTH_INT
,QOP_UNKNOWN
};
typedef struct {
enum auth_type type;
char username[(LEN_ALIAS > LEN_NAME ? LEN_ALIAS : LEN_NAME)+1];
char password[LEN_PASS+1];
char *digest_uri;
char *realm;
char *nonce;
enum algorithm algorithm;
enum qop_option qop_value;
char *cnonce;
char *nonce_count;
unsigned char digest[16]; /* MD5 digest */
BOOL stale;
typedef struct {
char virtual_path[MAX_PATH+1];
char physical_path[MAX_PATH+1];
BOOL expect_go_ahead;
time_t if_modified_since;
BOOL keep_alive;
char ars[256];
char host[128]; /* The requested host. (as used for self-referencing URLs) */
char vhost[128]; /* The requested host. (virtual host) */
int send_location;
const char* mime_type;
str_list_t headers;
char status[MAX_REQUEST_LINE+1];
char * post_data;
size_t post_len;
int dynamic;
char xjs_handler[MAX_PATH+1];
Loading
Loading full blame...