Subversion Repositories Tewi

Rev

Rev 214 | Rev 216 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 214 Rev 215
Line 1... Line 1...
1
/* $Id: server.c 214 2024-10-02 17:49:31Z nishi $ */
1
/* $Id: server.c 215 2024-10-02 19:24:43Z nishi $ */
2
 
2
 
3
#define SOURCE
3
#define SOURCE
4
 
4
 
5
#include "../config.h"
5
#include "../config.h"
6
 
6
 
Line 13... Line 13...
13
#include "tw_config.h"
13
#include "tw_config.h"
14
#include "tw_http.h"
14
#include "tw_http.h"
15
#include "tw_module.h"
15
#include "tw_module.h"
16
#include "tw_version.h"
16
#include "tw_version.h"
17
 
17
 
18
#ifndef _MSC_VER
18
#if !defined(_MSC_VER) && !defined(__BORLANDC__)
19
#include <unistd.h>
19
#include <unistd.h>
20
#endif
20
#endif
21
#include <string.h>
21
#include <string.h>
22
#include <stdbool.h>
22
#include <stdbool.h>
23
#include <stdarg.h>
23
#include <stdarg.h>
Line 30... Line 30...
30
 
30
 
31
#include <cm_string.h>
31
#include <cm_string.h>
32
#include <cm_log.h>
32
#include <cm_log.h>
33
#include <cm_dir.h>
33
#include <cm_dir.h>
34
 
34
 
35
#if defined(__MINGW32__) || defined(_MSC_VER)
35
#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__BORLANDC__)
36
#ifndef NO_GETADDRINFO
36
#ifndef NO_GETADDRINFO
37
#include <ws2tcpip.h>
37
#include <ws2tcpip.h>
38
#include <wspiapi.h>
38
#include <wspiapi.h>
39
#endif
39
#endif
40
#include <winsock2.h>
40
#include <winsock2.h>
Line 81... Line 81...
81
int sockcount = 0;
81
int sockcount = 0;
82
 
82
 
83
SOCKADDR addresses[MAX_PORTS];
83
SOCKADDR addresses[MAX_PORTS];
84
int sockets[MAX_PORTS];
84
int sockets[MAX_PORTS];
85
 
85
 
86
#if defined(__MINGW32__) || defined(_MSC_VER)
86
#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__BORLANDC__)
87
const char* reserved_names[] = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"};
87
const char* reserved_names[] = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"};
88
#endif
88
#endif
89
 
89
 
90
/* https://qiita.com/gyu-don/items/5a640c6d2252a860c8cd */
90
/* https://qiita.com/gyu-don/items/5a640c6d2252a860c8cd */
91
int tw_wildcard_match(const char* wildcard, const char* target) {
91
int tw_wildcard_match(const char* wildcard, const char* target) {
Line 108... Line 108...
108
		}
108
		}
109
	}
109
	}
110
}
110
}
111
 
111
 
112
void close_socket(int sock) {
112
void close_socket(int sock) {
113
#if defined(__MINGW32__) || defined(_MSC_VER)
113
#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__BORLANDC__)
114
	closesocket(sock);
114
	closesocket(sock);
115
#else
115
#else
116
	close(sock);
116
	close(sock);
117
#endif
117
#endif
118
}
118
}
119
 
119
 
120
int tw_server_init(void) {
120
int tw_server_init(void) {
121
	int i;
121
	int i;
122
#if defined(__MINGW32__) || defined(_MSC_VER)
122
#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__BORLANDC__)
123
	WSADATA wsa;
123
	WSADATA wsa;
124
	WSAStartup(MAKEWORD(2, 0), &wsa);
124
	WSAStartup(MAKEWORD(2, 0), &wsa);
125
#endif
125
#endif
126
	for(i = 0; config.ports[i] != -1; i++)
126
	for(i = 0; config.ports[i] != -1; i++)
127
		;
127
		;
Line 132... Line 132...
132
#ifdef NO_IPV6
132
#ifdef NO_IPV6
133
		int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
133
		int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
134
#else
134
#else
135
		int sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
135
		int sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
136
#endif
136
#endif
137
#if defined(__MINGW32__) || defined(_MSC_VER)
137
#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__BORLANDC__)
138
		if(sock == INVALID_SOCKET)
138
		if(sock == INVALID_SOCKET)
139
#else
139
#else
140
		if(sock < 0)
140
		if(sock < 0)
141
#endif
141
#endif
142
		{
142
		{
Line 235... Line 235...
235
		size = 0;
235
		size = 0;
236
		headers = NULL;
236
		headers = NULL;
237
		f = NULL;
237
		f = NULL;
238
		doc = NULL;
238
		doc = NULL;
239
	}
239
	}
240
#ifdef _MSC_VER
240
#if defined(_MSC_VER) || defined(__BORLANDC__)
241
	sprintf(construct, "%lu", (unsigned long)size);
241
	sprintf(construct, "%lu", (unsigned long)size);
242
#else
242
#else
243
	sprintf(construct, "%llu", (unsigned long long)size);
243
	sprintf(construct, "%llu", (unsigned long long)size);
244
#endif
244
#endif
245
	tw_write(ssl, sock, "HTTP/1.1 ", 9);
245
	tw_write(ssl, sock, "HTTP/1.1 ", 9);
Line 448... Line 448...
448
	SOCKADDR addr;
448
	SOCKADDR addr;
449
};
449
};
450
 
450
 
451
#if defined(__MINGW32__) || defined(_MSC_VER)
451
#if defined(__MINGW32__) || defined(_MSC_VER)
452
unsigned int WINAPI tw_server_pass(void* ptr) {
452
unsigned int WINAPI tw_server_pass(void* ptr) {
-
 
453
#elif defined(__BORLANDC__)
-
 
454
void tw_server_pass(void* ptr) {
453
#elif defined(__HAIKU__)
455
#elif defined(__HAIKU__)
454
int32_t tw_server_pass(void* ptr) {
456
int32_t tw_server_pass(void* ptr) {
455
#elif defined(_PSP) || defined(__PPU__)
457
#elif defined(_PSP) || defined(__PPU__)
456
int tw_server_pass(void* ptr) {
458
int tw_server_pass(void* ptr) {
457
#endif
459
#endif
458
#if defined(__HAIKU__) || defined(__MINGW32__) || defined(_PSP) || defined(__PPU__) || defined(_MSC_VER)
460
#if defined(__HAIKU__) || defined(__MINGW32__) || defined(_PSP) || defined(__PPU__) || defined(_MSC_VER) || defined(__BORLANDC__)
459
#define FREE_PTR
461
#define FREE_PTR
460
	int sock = ((struct pass_entry*)ptr)->sock;
462
	int sock = ((struct pass_entry*)ptr)->sock;
461
	bool ssl = ((struct pass_entry*)ptr)->ssl;
463
	bool ssl = ((struct pass_entry*)ptr)->ssl;
462
	int port = ((struct pass_entry*)ptr)->port;
464
	int port = ((struct pass_entry*)ptr)->port;
463
	SOCKADDR addr = ((struct pass_entry*)ptr)->addr;
465
	SOCKADDR addr = ((struct pass_entry*)ptr)->addr;
Line 546... Line 548...
546
				} else if(cm_strcaseequ(req.headers[i], "If-Modified-Since")) {
548
				} else if(cm_strcaseequ(req.headers[i], "If-Modified-Since")) {
547
					struct tm tm;
549
					struct tm tm;
548
					time_t t;
550
					time_t t;
549
					struct tm* btm;
551
					struct tm* btm;
550
					strptime(req.headers[i + 1], "%a, %d %b %Y %H:%M:%S GMT", &tm);
552
					strptime(req.headers[i + 1], "%a, %d %b %Y %H:%M:%S GMT", &tm);
551
#if defined(__MINGW32__) || defined(_PSP) || defined(__PPU__) || defined(__ps2sdk__) || defined(_MSC_VER)
553
#if defined(__MINGW32__) || defined(_PSP) || defined(__PPU__) || defined(__ps2sdk__) || defined(_MSC_VER) || defined(__BORLANDC__)
552
					t = 0;
554
					t = 0;
553
					btm = localtime(&t);
555
					btm = localtime(&t);
554
					cmtime = mktime(&tm);
556
					cmtime = mktime(&tm);
555
					cmtime -= (btm->tm_hour * 60 + btm->tm_min) * 60;
557
					cmtime -= (btm->tm_hour * 60 + btm->tm_min) * 60;
556
#else
558
#else
Line 609... Line 611...
609
		}
611
		}
610
		if(!res._processed) {
612
		if(!res._processed) {
611
			char* path;
613
			char* path;
612
			char* rpath;
614
			char* rpath;
613
			struct stat st;
615
			struct stat st;
-
 
616
			char* slash;
614
			cm_log("Server", "Document root is %s", vhost_entry->root == NULL ? "not set" : vhost_entry->root);
617
			cm_log("Server", "Document root is %s", vhost_entry->root == NULL ? "not set" : vhost_entry->root);
615
			path = cm_strcat(vhost_entry->root == NULL ? "" : vhost_entry->root, req.path);
618
			path = cm_strcat(vhost_entry->root == NULL ? "" : vhost_entry->root, req.path);
616
			cm_log("Server", "Filesystem path is %s", path);
619
			cm_log("Server", "Filesystem path is %s", path);
-
 
620
#if defined(_MSC_VER) || defined(__BORLANDC__)
-
 
621
			for(i = strlen(path) - 1; i >= 0; i--){
-
 
622
				if(path[i] == '/'){
-
 
623
					path[i] = 0;
-
 
624
				}else{
-
 
625
					break;
-
 
626
				}
-
 
627
			}
-
 
628
#endif
617
#if defined(__MINGW32__) || defined(_MSC_VER)
629
#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__BORLANDC__)
618
			rpath = cm_strdup(path);
630
			rpath = cm_strdup(path);
619
			for(i = strlen(rpath) - 1; i >= 0; i--) {
631
			for(i = strlen(rpath) - 1; i >= 0; i--) {
620
				if(rpath[i] == '/') {
632
				if(rpath[i] == '/') {
621
					int j;
633
					int j;
622
					for(j = i + 1; rpath[j] != 0; j++) {
634
					for(j = i + 1; rpath[j] != 0; j++) {
Line 644... Line 656...
644
			if(!rej && stat(path, &st) == 0) {
656
			if(!rej && stat(path, &st) == 0) {
645
				if(!tw_permission_allowed(path, addr, req, vhost_entry)) {
657
				if(!tw_permission_allowed(path, addr, req, vhost_entry)) {
646
					tw_http_error(s, sock, 403, name, port, vhost_entry);
658
					tw_http_error(s, sock, 403, name, port, vhost_entry);
647
				} else if(S_ISDIR(st.st_mode)) {
659
				} else if(S_ISDIR(st.st_mode)) {
648
					if(req.path[strlen(req.path) - 1] != '/') {
660
					if(req.path[strlen(req.path) - 1] != '/') {
649
						char* headers[3] = {"Location", cm_strcat(req.path, "/"), NULL};
661
						char* headers[3] = {"Location", NULL, NULL};
-
 
662
						headers[1] = cm_strcat(req.path, "/");
650
						cm_log("Server", "Accessing directory without the slash at the end");
663
						cm_log("Server", "Accessing directory without the slash at the end");
651
						_tw_process_page(s, sock, tw_http_status(301), NULL, NULL, NULL, 0, headers, 0, 0);
664
						_tw_process_page(s, sock, tw_http_status(301), NULL, NULL, NULL, 0, headers, 0, 0);
652
						free(headers[1]);
665
						free(headers[1]);
653
					} else {
666
					} else {
654
						char** indexes = vhost_entry->index_count == 0 ? config.root.indexes : vhost_entry->indexes;
667
						char** indexes = vhost_entry->index_count == 0 ? config.root.indexes : vhost_entry->indexes;
Line 882... Line 895...
882
		SSL_shutdown(s);
895
		SSL_shutdown(s);
883
	}
896
	}
884
	SSL_free(s);
897
	SSL_free(s);
885
#endif
898
#endif
886
	close_socket(sock);
899
	close_socket(sock);
887
#if defined(__MINGW32__) || defined(_MSC_VER)
900
#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__BORLANDC__)
888
	_endthread(0);
901
	_endthread(
-
 
902
#ifndef __BORLANDC__
-
 
903
		0
-
 
904
#endif
-
 
905
	);
889
#elif defined(__HAIKU__)
906
#elif defined(__HAIKU__)
890
		exit_thread(0);
907
		exit_thread(0);
891
#endif
908
#endif
-
 
909
#ifndef __BORLANDC__
892
	return 0;
910
	return 0;
-
 
911
#endif
893
}
912
}
894
 
913
 
895
#ifdef SERVICE
914
#ifdef SERVICE
896
extern SERVICE_STATUS status;
915
extern SERVICE_STATUS status;
897
extern SERVICE_STATUS_HANDLE status_handle;
916
extern SERVICE_STATUS_HANDLE status_handle;
898
#endif
917
#endif
899
 
918
 
900
#if defined(__MINGW32__) || defined(__HAIKU__) || defined(_MSC_VER)
919
#if defined(__MINGW32__) || defined(__HAIKU__) || defined(_MSC_VER) || defined(__BORLANDC__)
901
struct thread_entry {
920
struct thread_entry {
902
#ifdef __HAIKU__
921
#ifdef __HAIKU__
903
	thread_id thread;
922
	thread_id thread;
904
#else
923
#else
905
	HANDLE handle;
924
	HANDLE handle;
Line 914... Line 933...
914
	int i;
933
	int i;
915
#ifndef USE_POLL
934
#ifndef USE_POLL
916
	fd_set fdset;
935
	fd_set fdset;
917
	struct timeval tv;
936
	struct timeval tv;
918
#endif
937
#endif
919
#if defined(__MINGW32__) || defined(__HAIKU__) || defined(_MSC_VER)
938
#if defined(__MINGW32__) || defined(__HAIKU__) || defined(_MSC_VER) || defined(__BORLANDC__)
920
	struct thread_entry threads[2048];
939
	struct thread_entry threads[2048];
921
	for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++) {
940
	for(i = 0; i < sizeof(threads) / sizeof(threads[0]); i++) {
922
		threads[i].used = false;
941
		threads[i].used = false;
923
	}
942
	}
924
#endif
943
#endif
Line 945... Line 964...
945
#else
964
#else
946
			ret = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
965
			ret = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
947
#endif
966
#endif
948
#endif
967
#endif
949
		if(ret == -1) {
968
		if(ret == -1) {
950
#if !defined(__MINGW32__) && !defined(_MSC_VER)
969
#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(__BORLANDC__)
951
			cm_log("Server", "Select failure: %s", strerror(errno));
970
			cm_log("Server", "Select failure: %s", strerror(errno));
952
#endif
971
#endif
953
			break;
972
			break;
954
		} else if(ret == 0) {
973
		} else if(ret == 0) {
955
#ifdef SERVICE
974
#ifdef SERVICE
Line 969... Line 988...
969
#endif
988
#endif
970
				if(cond) {
989
				if(cond) {
971
					SOCKADDR claddr;
990
					SOCKADDR claddr;
972
					socklen_t clen = sizeof(claddr);
991
					socklen_t clen = sizeof(claddr);
973
					int sock = accept(sockets[i], (struct sockaddr*)&claddr, &clen);
992
					int sock = accept(sockets[i], (struct sockaddr*)&claddr, &clen);
974
#if defined(__MINGW32__) || defined(__HAIKU__) || defined(_PSP) || defined(__PPU__) || defined(_MSC_VER)
993
#if defined(__MINGW32__) || defined(__HAIKU__) || defined(_PSP) || defined(__PPU__) || defined(_MSC_VER) || defined(__BORLANDC__)
975
					int j;
994
					int j;
976
					struct pass_entry* e = malloc(sizeof(*e));
995
					struct pass_entry* e = malloc(sizeof(*e));
977
					cm_log("Server", "New connection accepted");
996
					cm_log("Server", "New connection accepted");
978
					e->sock = sock;
997
					e->sock = sock;
979
#ifdef _MSC_VER
998
#if defined(_MSC_VER) || defined(__BORLANDC__)
980
					e->ssl = config.ports[i] & (1UL << 31);
999
					e->ssl = config.ports[i] & (1UL << 31);
981
#else
1000
#else
982
					e->ssl = config.ports[i] & (1ULL << 31);
1001
					e->ssl = config.ports[i] & (1ULL << 31);
983
#endif
1002
#endif
984
					e->port = config.ports[i];
1003
					e->port = config.ports[i];
985
					e->addr = claddr;
1004
					e->addr = claddr;
986
#endif
1005
#endif
987
#if defined(__MINGW32__) || defined(_MSC_VER)
1006
#if defined(__MINGW32__) || defined(_MSC_VER) || defined(__BORLANDC__)
988
					_beginthread(tw_server_pass, 0, e);
1007
					_beginthread(tw_server_pass, 0, e);
989
#elif defined(_PSP) || defined(__PPU__)
1008
#elif defined(_PSP) || defined(__PPU__)
990
						tw_server_pass(e);
1009
						tw_server_pass(e);
991
#elif defined(__HAIKU__)
1010
#elif defined(__HAIKU__)
992
					for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) {
1011
					for(j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) {