Diff

Differences From Artifact [a92c173e7c]:

To Artifact [66294af131]:


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <pwd.h>

/* Compile time constants */
#define FILED_VERSION "1.19"
#define FILED_SENDFILE_MAX 16777215
#define FILED_MAX_FAILURE_COUNT 30
#define FILED_DEFAULT_TYPE "application/octet-stream"
#define FILED_PATH_BUFFER_SIZE 1010

/* Default values */
#define PORT 80







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <pwd.h>

/* Compile time constants */
#define FILED_VERSION "1.21"
#define FILED_SENDFILE_MAX 16777215
#define FILED_MAX_FAILURE_COUNT 30
#define FILED_DEFAULT_TYPE "application/octet-stream"
#define FILED_PATH_BUFFER_SIZE 1010

/* Default values */
#define PORT 80
270
271
272
273
274
275
276


277
278
279
280
281
282
283
284
285
286
287
288
289
290

291




292
293
294



295

296
297
298
299
300
301
302

	return(0);
}

/* Initialize process */
static int filed_init(unsigned int cache_size) {
	static int called = 0;


	ssize_t read_ret = 0;
	unsigned int random_value = 0;
	int cache_ret;
	int random_fd;

	if (called) {
		return(0);
	}

	called = 1;

	/* Attempt to lock all memory to physical RAM (but don't care if we can't) */
	mlockall(MCL_CURRENT | MCL_FUTURE);


	/* Ignore SIGPIPE */




	signal(SIGPIPE, SIG_IGN);

	/* Handle SIGHUP to release all caches */



	signal(SIGHUP, filed_signal_handler);


	/* Initialize cache structure */
	cache_ret = filed_init_cache(cache_size);
	if (cache_ret != 0) {
		return(cache_ret);
	}








>
>














>
|
>
>
>
>
|


>
>
>
|
>







270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

	return(0);
}

/* Initialize process */
static int filed_init(unsigned int cache_size) {
	static int called = 0;
	struct sigaction signal_handler_info;
	sigset_t signal_handler_mask;
	ssize_t read_ret = 0;
	unsigned int random_value = 0;
	int cache_ret;
	int random_fd;

	if (called) {
		return(0);
	}

	called = 1;

	/* Attempt to lock all memory to physical RAM (but don't care if we can't) */
	mlockall(MCL_CURRENT | MCL_FUTURE);

	/* Establish signal handlers */
	/* SIGPIPE should interrupt system calls */
	sigfillset(&signal_handler_mask);
	signal_handler_info.sa_handler = filed_signal_handler;
	signal_handler_info.sa_mask = signal_handler_mask;
	signal_handler_info.sa_flags = SA_RESTART;
	sigaction(SIGPIPE, &signal_handler_info, NULL);

	/* Handle SIGHUP to release all caches */
	sigfillset(&signal_handler_mask);
	signal_handler_info.sa_handler = filed_signal_handler;
	signal_handler_info.sa_mask = signal_handler_mask;
	signal_handler_info.sa_flags = 0;
	sigaction(SIGHUP, &signal_handler_info, NULL);

	/* Initialize cache structure */
	cache_ret = filed_init_cache(cache_size);
	if (cache_ret != 0) {
		return(cache_ret);
	}

603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
#define filed_sockettimeout_close(x) /**/
#else
time_t filed_sockettimeout_time;
struct {
	time_t expiration_time;
	pthread_t thread_id;
	int valid;
}* filed_sockettimeout_sockstatus;
long filed_sockettimeout_sockstatus_length;
int filed_sockettimeout_devnull_fd;

static int filed_sockettimeout_sockfd_in_range(int sockfd) {
	if (sockfd < 3) {
		return(0);
	}







|







614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
#define filed_sockettimeout_close(x) /**/
#else
time_t filed_sockettimeout_time;
struct {
	time_t expiration_time;
	pthread_t thread_id;
	int valid;
} *filed_sockettimeout_sockstatus;
long filed_sockettimeout_sockstatus_length;
int filed_sockettimeout_devnull_fd;

static int filed_sockettimeout_sockfd_in_range(int sockfd) {
	if (sockfd < 3) {
		return(0);
	}
676
677
678
679
680
681
682

683
684
685
686
687
688
689
690


691
692
693
694
695
696
697
698

	atomic_store(&filed_sockettimeout_sockstatus[sockfd].valid, false);

	return;
}

static void *filed_sockettimeout_thread(void *arg) {

	time_t now, expiration_time;
	pthread_t thread_id;
	long idx;
	int count;
	int valid;

	while (1) {
		for (count = 0; count < 10; count++) {


			usleep(30000000);

			now = time(NULL);

			atomic_store(&filed_sockettimeout_time, now);
		}

		for (idx = 0; idx < filed_sockettimeout_sockstatus_length; idx++) {







>








>
>
|







687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712

	atomic_store(&filed_sockettimeout_sockstatus[sockfd].valid, false);

	return;
}

static void *filed_sockettimeout_thread(void *arg) {
	struct timespec sleep_time;
	time_t now, expiration_time;
	pthread_t thread_id;
	long idx;
	int count;
	int valid;

	while (1) {
		for (count = 0; count < 10; count++) {
			sleep_time.tv_sec = 30;
			sleep_time.tv_nsec = 0;
			nanosleep(&sleep_time, NULL);

			now = time(NULL);

			atomic_store(&filed_sockettimeout_time, now);
		}

		for (idx = 0; idx < filed_sockettimeout_sockstatus_length; idx++) {
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
	long maxfd, idx;

	maxfd = sysconf(_SC_OPEN_MAX);
	if (maxfd <= 0) {
		maxfd = 4096;
	}


	filed_sockettimeout_sockstatus = malloc(sizeof(*filed_sockettimeout_sockstatus) * maxfd);
	if (filed_sockettimeout_sockstatus == NULL) {
		return(-1);
	}

	for (idx = 0; idx < maxfd; idx++) {
		filed_sockettimeout_sockstatus[idx].valid = false;
	}

	filed_sockettimeout_sockstatus_length = maxfd;
	filed_sockettimeout_devnull_fd = open("/dev/null", O_RDWR);
	if (filed_sockettimeout_devnull_fd < 0) {
		return(-1);
	}

	return(0);
}







>
|








<







750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

767
768
769
770
771
772
773
	long maxfd, idx;

	maxfd = sysconf(_SC_OPEN_MAX);
	if (maxfd <= 0) {
		maxfd = 4096;
	}

	filed_sockettimeout_sockstatus_length = maxfd;
	filed_sockettimeout_sockstatus = malloc(sizeof(*filed_sockettimeout_sockstatus) * filed_sockettimeout_sockstatus_length);
	if (filed_sockettimeout_sockstatus == NULL) {
		return(-1);
	}

	for (idx = 0; idx < maxfd; idx++) {
		filed_sockettimeout_sockstatus[idx].valid = false;
	}


	filed_sockettimeout_devnull_fd = open("/dev/null", O_RDWR);
	if (filed_sockettimeout_devnull_fd < 0) {
		return(-1);
	}

	return(0);
}
1167
1168
1169
1170
1171
1172
1173

1174
1175
1176
1177
1178
1179
1180
1181
1182

	fclose(fp);

	return;
}

/* Return a redirect to index.html */

static void filed_redirect_index(FILE *fp, const char *date_current, const char *path, struct filed_log_entry *log) {
	int http_code = 301;
	fprintf(fp, "HTTP/1.1 %i OK\r\nDate: %s\r\nServer: filed\r\nLast-Modified: %s\r\nContent-Length: 0\r\nConnection: close\r\nLocation: %s\r\n\r\n",
		http_code,
		date_current,
		date_current,
		"index.html"
	);








>

|







1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197

	fclose(fp);

	return;
}

/* Return a redirect to index.html */
#ifndef FILED_DONT_REDIRECT_DIRECTORIES
static void filed_redirect_index(FILE *fp, const char *date_current, const char *path, struct filed_log_entry *log) {
	int http_code = 302;
	fprintf(fp, "HTTP/1.1 %i OK\r\nDate: %s\r\nServer: filed\r\nLast-Modified: %s\r\nContent-Length: 0\r\nConnection: close\r\nLocation: %s\r\n\r\n",
		http_code,
		date_current,
		date_current,
		"index.html"
	);

1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202
1203
1204
1205
	fclose(fp);

	return;

	/* Currently unused: path */
	path = path;
}


/* Convert an enum representing the "Connection" header value to a string */
static const char *filed_connection_str(int connection_value) {
	switch (connection_value) {
		case FILED_CONNECTION_CLOSE:
			return("close");
		case FILED_CONNECTION_KEEP_ALIVE:







>







1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
	fclose(fp);

	return;

	/* Currently unused: path */
	path = path;
}
#endif

/* Convert an enum representing the "Connection" header value to a string */
static const char *filed_connection_str(int connection_value) {
	switch (connection_value) {
		case FILED_CONNECTION_CLOSE:
			return("close");
		case FILED_CONNECTION_KEEP_ALIVE:
1253
1254
1255
1256
1257
1258
1259














1260
1261
1262

1263
1264
1265
1266
1267
1268
1269

	path = request->path;
	strcpy(log->buffer, path);
	log->method = request->method;

	/* If the requested path is a directory, redirect to index page */
	if (request->type == FILED_REQUEST_TYPE_DIRECTORY) {














		filed_redirect_index(fp, date_current, path, log);

		return(FILED_CONNECTION_CLOSE);

	}

	fileinfo = filed_open_file(path, &request->fileinfo, options);
	if (fileinfo == NULL) {
		filed_error_page(fp, date_current, 404, request->method, "open_failed", log);

		return(FILED_CONNECTION_CLOSE);







>
>
>
>
>
>
>
>
>
>
>
>
>
>



>







1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300

	path = request->path;
	strcpy(log->buffer, path);
	log->method = request->method;

	/* If the requested path is a directory, redirect to index page */
	if (request->type == FILED_REQUEST_TYPE_DIRECTORY) {
#ifdef FILED_DONT_REDIRECT_DIRECTORIES
		char localpath[8192];
		int snprintf_ret;

		snprintf_ret = snprintf(localpath, sizeof(localpath), "%s/index.html", path);

		if (snprintf_ret <= 0 || snprintf_ret > (sizeof(localpath) - 1)) {
			filed_error_page(fp, date_current, 500, request->method, "path_format", log);

			return(FILED_CONNECTION_CLOSE);
		}

		path = localpath;
#else
		filed_redirect_index(fp, date_current, path, log);

		return(FILED_CONNECTION_CLOSE);
#endif
	}

	fileinfo = filed_open_file(path, &request->fileinfo, options);
	if (fileinfo == NULL) {
		filed_error_page(fp, date_current, 404, request->method, "open_failed", log);

		return(FILED_CONNECTION_CLOSE);
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886

		return(5);
	}

	/* Wait for threads to exit */
	/* XXX:TODO: Monitor thread usage */
	while (1) {
		sleep(60);
	}

	/* Return in failure */
	return(2);
}







|





1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917

		return(5);
	}

	/* Wait for threads to exit */
	/* XXX:TODO: Monitor thread usage */
	while (1) {
		sleep(86400);
	}

	/* Return in failure */
	return(2);
}