| ︙ | | |
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
-
+
|
# include <arpa/inet.h>
# include <sys/times.h>
# include <sys/time.h>
# include <sys/wait.h>
# include <sys/select.h>
# include <errno.h>
#endif
#ifdef __EMX__
#if defined(__EMX__) || defined(__morphos__)
typedef int socklen_t;
#endif
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
|
| ︙ | | |
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
|
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
|
+
+
+
+
+
+
+
+
|
/*
** All possible forms of an IP address. Needed to work around GCC strict
** aliasing rules.
*/
typedef union {
struct sockaddr sa; /* Abstract superclass */
struct sockaddr_in sa4; /* IPv4 */
#ifdef AF_INET6
struct sockaddr_in6 sa6; /* IPv6 */
struct sockaddr_storage sas; /* Should be the maximum of the above 3 */
#endif
} address;
/*
** Determine the IP address on the other side of a connection.
** Return a pointer to a string. Or return 0 if unable.
**
** The string is held in a static buffer that is overwritten on
** each call.
*/
char *cgi_remote_ip(int fd){
address remoteAddr;
socklen_t size = sizeof(remoteAddr);
#ifdef AF_INET6
static char zHost[NI_MAXHOST];
#endif
if( getpeername(0, &remoteAddr.sa, &size) ){
return 0;
}
#ifdef AF_INET6
if( getnameinfo(&remoteAddr.sa, size, zHost, sizeof(zHost), 0, 0,
NI_NUMERICHOST) ){
return 0;
}
return zHost;
#else
return inet_ntoa(((struct sockaddr_in *)&remoteAddr.sa)->sin_addr);
#endif
}
/*
** This routine handles a single HTTP request which is coming in on
** g.httpIn and which replies on g.httpOut
**
** The HTTP request is read from g.httpIn and is used to initialize
|
| ︙ | | |
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
|
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
|
+
+
|
int connection; /* An incoming connection */
int nRequest = 0; /* Number of requests handled so far */
fd_set readfds; /* Set of file descriptors for select() */
socklen_t lenaddr; /* Length of the inaddr structure */
int child; /* PID of the child process */
int nchildren = 0; /* Number of child processes */
struct timeval delay; /* How long to wait inside select() */
#ifdef AF_INET6
struct sockaddr_in6 inaddr6; /* Address for IPv6 */
#endif
struct sockaddr_in inaddr4; /* Address for IPv4 */
struct sockaddr_un uxaddr; /* The address for unix-domain sockets */
int opt = 1; /* setsockopt flag */
int rc; /* Result code from system calls */
int iPort = mnPort; /* Port to try to use */
const char *zRequestType; /* Type of requests to listen for */
|
| ︙ | | |
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
|
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
|
+
|
** https://fossil-scm.org/forum/forumpost/7517680ef9684c57 */
if( g.zSockOwner ){
file_set_owner(g.zSockName, listen4, g.zSockOwner);
}
fossil_print("Listening for %s requests on unix socket %s\n",
zRequestType, g.zSockName);
fflush(stdout);
#ifdef AF_INET6
}else if( zIpAddr && strchr(zIpAddr,':')!=0 ){
/* CASE 2: TCP on IPv6 IP address specified by zIpAddr and on port iPort.
*/
assert( mnPort==mxPort );
memset(&inaddr6, 0, sizeof(inaddr6));
inaddr6.sin6_family = AF_INET6;
inaddr6.sin6_port = htons(iPort);
|
| ︙ | | |
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
|
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
|
+
|
zIpAddr, mnPort);
}
mxListen = listen6;
listen4 = -1;
fossil_print("Listening for %s requests on [%s]:%d\n",
zRequestType, zIpAddr, iPort);
fflush(stdout);
#endif
}else if( zIpAddr && zIpAddr[0] ){
/* CASE 3: TCP on IPv4 IP address specified by zIpAddr and on port iPort.
*/
assert( mnPort==mxPort );
memset(&inaddr4, 0, sizeof(inaddr4));
inaddr4.sin_family = AF_INET;
inaddr4.sin_port = htons(iPort);
|
| ︙ | | |
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
|
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
|
+
|
}
if( listen4<0 ){
iPort++;
continue;
}
mxListen = listen4;
#ifdef AF_INET6
/* If we get here, that means we found an open TCP port at iPort for
** IPv4. Try to set up a corresponding IPv6 socket on the same port.
*/
memset(&inaddr6, 0, sizeof(inaddr6));
inaddr6.sin6_family = AF_INET6;
inaddr6.sin6_port = htons(iPort);
if( flags & HTTP_SERVER_LOCALHOST ){
|
| ︙ | | |
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
|
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
|
+
+
+
|
}
if( listen6<0 ){
zProto = "IPv4 only";
}else{
zProto = "IPv4 and IPv6";
if( listen6>listen4 ) mxListen = listen6;
}
#else
zProto = "IPv4 only";
#endif
fossil_print("Listening for %s requests on TCP port %s%d, %s\n",
zRequestType,
(flags & HTTP_SERVER_LOCALHOST)!=0 ? "localhost:" : "",
iPort, zProto);
fflush(stdout);
break;
|
| ︙ | | |
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
|
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
|
+
+
+
+
+
+
|
assert( listen4>0 || listen6>0 );
if( listen4>0 ) FD_SET( listen4, &readfds);
if( listen6>0 ) FD_SET( listen6, &readfds);
select( mxListen+1, &readfds, 0, 0, &delay);
if( listen4>0 && FD_ISSET(listen4, &readfds) ){
lenaddr = sizeof(inaddr4);
connection = accept(listen4, (struct sockaddr*)&inaddr4, &lenaddr);
#ifdef AF_INET6
}else if( listen6>0 && FD_ISSET(listen6, &readfds) ){
lenaddr = sizeof(inaddr6);
connection = accept(listen6, (struct sockaddr*)&inaddr6, &lenaddr);
#endif
}else{
connection = -1;
}
if( connection>=0 ){
#ifndef __morphos__
if( flags & HTTP_SERVER_NOFORK ){
child = 0;
}else{
child = fork();
}
#else
child = 0;
#endif
if( child!=0 ){
if( child>0 ){
nchildren++;
nRequest++;
}
close(connection);
}else{
|
| ︙ | | |