ruby-lsapi 4.3 → 4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/ext/lsapi/lsapilib.c +155 -32
  3. data/lsapi.gemspec +2 -2
  4. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f50f52a087ccb168677d89ab894b8588abec069e
4
- data.tar.gz: 3eebc21ef0cac31cf1f6142a16aab8fe48a1bfd2
3
+ metadata.gz: fb7c17d4bad59b5058a4683b2c07d8abfadc9e36
4
+ data.tar.gz: 0836a55ff1392b8dc1052b2f83732e9b8f992c94
5
5
  SHA512:
6
- metadata.gz: f3143175c96d841ac986629da7208a026df9eda49be225d031fc8fd21f06c18e64ba9a3da53066c427ee4a4d0a54ca86f9b8ec18b4b0b2156c06cb2ca6db4262
7
- data.tar.gz: 7066ddb8f448c3fda956e6b5b29475d15ccaa96e6f8b518359c973f3b66100324d2712ff8af0f89b47b844b9ec94b8382a2ae92f24d61405cbf05ee48057b0b8
6
+ metadata.gz: 417955426a67c9a0a9802a4d18a6ac6d075d8b81a7b01adcf2f4e217b0e15a6b7a0b4cec3bcf40e595e39a89809328840880c860c3907aeab8b08ac83b799436
7
+ data.tar.gz: a0499088de40de67681b2aa0c94ef2fb2248568e7aa9d5c00f668daef3a020e9513c22cf9e2f746ed9eed6d1c2ec1fbb72166930c2b1b0a447fa549753206481
@@ -35,7 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
35
  #include <dlfcn.h>
36
36
  #include <errno.h>
37
37
  #include <fcntl.h>
38
-
38
+ #include <limits.h>
39
39
  #include <sys/stat.h>
40
40
  #include <signal.h>
41
41
  #include <stdlib.h>
@@ -98,7 +98,23 @@ typedef struct lsapi_MD5Context lsapi_MD5_CTX;
98
98
  #define LSAPI_RESP_BUF_SIZE 8192
99
99
  #define LSAPI_INIT_RESP_HEADER_LEN 4096
100
100
 
101
+ typedef struct _lsapi_child_status
102
+ {
103
+ int m_pid;
104
+ long m_tmStart;
101
105
 
106
+ volatile short m_iKillSent;
107
+ volatile char m_inProcess;
108
+ volatile char m_connected;
109
+ volatile int m_iReqCounter;
110
+
111
+ volatile long m_tmWaitBegin;
112
+ volatile long m_tmReqBegin;
113
+ volatile long m_tmLastCheckPoint;
114
+ }
115
+ lsapi_child_status;
116
+
117
+ static lsapi_child_status * s_pChildStatus = NULL;
102
118
 
103
119
  static int g_inited = 0;
104
120
  static int g_running = 1;
@@ -108,12 +124,17 @@ static int s_keepListener = 0;
108
124
  static int s_dump_debug_info = 0;
109
125
  static int s_pid_dump_debug_info = 0;
110
126
 
127
+ static int *s_busy_workers = NULL;
128
+ static int s_max_busy_children = -1;
129
+
111
130
  LSAPI_Request g_req = { -1, -1 };
112
131
 
113
132
  static char s_secret[24];
114
-
133
+ static char *s_pStderrLog = NULL;
115
134
 
116
135
  void Flush_RespBuf_r( LSAPI_Request * pReq );
136
+ static int lsapi_reopen_stderr(const char *p);
137
+
117
138
 
118
139
  static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] =
119
140
  {
@@ -265,6 +286,20 @@ static int lsapi_close( int fd )
265
286
  }
266
287
  }
267
288
 
289
+
290
+ static void lsapi_close_connection(LSAPI_Request *pReq)
291
+ {
292
+ if (pReq->m_fd == -1)
293
+ return;
294
+ lsapi_close(pReq->m_fd);
295
+ pReq->m_fd = -1;
296
+ if (s_busy_workers)
297
+ __sync_fetch_and_sub(s_busy_workers, 1);
298
+ if (s_pChildStatus)
299
+ s_pChildStatus->m_connected = 0;
300
+ }
301
+
302
+
268
303
  static inline ssize_t lsapi_read( int fd, void * pBuf, size_t len )
269
304
  {
270
305
  ssize_t ret;
@@ -706,8 +741,11 @@ int LSAPI_is_suEXEC_Daemon(void)
706
741
 
707
742
  static int LSAPI_perror_r( LSAPI_Request * pReq, const char * pErr1, const char *pErr2 )
708
743
  {
709
- char achError[1024];
710
- int n = snprintf(achError, 1024, "%s:%s: %s\n", pErr1, (pErr2)?pErr2:"", strerror( errno ) );
744
+ char achError[4096];
745
+ int n = snprintf(achError, sizeof(achError), "[%d] %s:%s: %s\n", getpid(),
746
+ pErr1, (pErr2)?pErr2:"", strerror(errno));
747
+ if (n > sizeof(achError))
748
+ n = sizeof(achError);
711
749
  if ( pReq )
712
750
  LSAPI_Write_Stderr_r( pReq, achError, n );
713
751
  else
@@ -908,7 +946,8 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
908
946
  {
909
947
  int uid = s_defaultUid;
910
948
  int gid = s_defaultGid;
911
- const char * pChroot = NULL;
949
+ const char *pStderrLog;
950
+ const char *pChroot = NULL;
912
951
  struct LSAPI_key_value_pair * pEnv;
913
952
  struct LSAPI_key_value_pair * pAuth;
914
953
  int i;
@@ -973,6 +1012,10 @@ static int lsapi_changeUGid( LSAPI_Request * pReq )
973
1012
  }
974
1013
 
975
1014
  s_uid = uid;
1015
+
1016
+ pStderrLog = LSAPI_GetEnv_r( pReq, "LSAPI_STDERR_LOG");
1017
+ if (pStderrLog)
1018
+ lsapi_reopen_stderr(pStderrLog);
976
1019
 
977
1020
  return 0;
978
1021
 
@@ -1335,6 +1378,10 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
1335
1378
  }
1336
1379
  else
1337
1380
  {
1381
+ if (s_pChildStatus)
1382
+ s_pChildStatus->m_connected = 1;
1383
+ if (s_busy_workers)
1384
+ __sync_fetch_and_add(s_busy_workers, 1);
1338
1385
  lsapi_set_nblock( pReq->m_fd , 0 );
1339
1386
  if (((struct sockaddr *)&achPeer)->sa_family == AF_INET )
1340
1387
  {
@@ -1354,8 +1401,7 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
1354
1401
  if ( !readReq( pReq ) )
1355
1402
  break;
1356
1403
  //abort();
1357
- lsapi_close( pReq->m_fd );
1358
- pReq->m_fd = -1;
1404
+ lsapi_close_connection(pReq);
1359
1405
  LSAPI_Reset_r( pReq );
1360
1406
  }
1361
1407
  return 0;
@@ -1802,8 +1848,7 @@ int LSAPI_Flush_r( LSAPI_Request * pReq )
1802
1848
  n, pReq->m_totalLen );
1803
1849
  if ( ret < pReq->m_totalLen )
1804
1850
  {
1805
- lsapi_close( pReq->m_fd );
1806
- pReq->m_fd = -1;
1851
+ lsapi_close_connection(pReq);
1807
1852
  ret = -1;
1808
1853
  }
1809
1854
  pReq->m_totalLen = 0;
@@ -1826,7 +1871,7 @@ ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t le
1826
1871
 
1827
1872
  if ( !pReq )
1828
1873
  return -1;
1829
- if (( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen ))
1874
+ if (s_pStderrLog||( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen ))
1830
1875
  return write( 2, pBuf, len );
1831
1876
  if ( pReq->m_pRespBufPos != pReq->m_pRespBuf )
1832
1877
  {
@@ -1858,8 +1903,7 @@ ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t le
1858
1903
  2, totalLen );
1859
1904
  if ( ret < totalLen )
1860
1905
  {
1861
- lsapi_close( pReq->m_fd );
1862
- pReq->m_fd = -1;
1906
+ lsapi_close_connection(pReq);
1863
1907
  ret = -1;
1864
1908
  }
1865
1909
  }
@@ -2435,23 +2479,6 @@ int LSAPI_CreateListenSock( const char * pBind, int backlog )
2435
2479
 
2436
2480
  static fn_select_t g_fnSelect = select;
2437
2481
 
2438
- typedef struct _lsapi_child_status
2439
- {
2440
- int m_pid;
2441
- long m_tmStart;
2442
-
2443
- volatile short m_iKillSent;
2444
- volatile short m_inProcess;
2445
- volatile int m_iReqCounter;
2446
-
2447
- volatile long m_tmWaitBegin;
2448
- volatile long m_tmReqBegin;
2449
- volatile long m_tmLastCheckPoint;
2450
- }
2451
- lsapi_child_status;
2452
-
2453
- static lsapi_child_status * s_pChildStatus = NULL;
2454
-
2455
2482
  typedef struct _lsapi_prefork_server
2456
2483
  {
2457
2484
  int m_fd;
@@ -2482,6 +2509,7 @@ int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork )
2482
2509
  if ( max_children >= 10000)
2483
2510
  max_children = 10000;
2484
2511
 
2512
+ s_max_busy_children = max_children / 2 + 1;
2485
2513
 
2486
2514
  g_prefork_server = (lsapi_prefork_server *)malloc( sizeof( lsapi_prefork_server ) );
2487
2515
  if ( !g_prefork_server )
@@ -2596,9 +2624,14 @@ static void lsapi_sigchild( int signal )
2596
2624
  child_status = find_child_status( pid );
2597
2625
  if ( child_status )
2598
2626
  {
2627
+ if (child_status->m_connected)
2628
+ {
2629
+ if (s_busy_workers)
2630
+ __sync_fetch_and_sub(s_busy_workers, 1);
2631
+ child_status->m_connected = 0;
2632
+ }
2599
2633
  child_status->m_pid = 0;
2600
2634
  --g_prefork_server->m_iCurChildren;
2601
-
2602
2635
  }
2603
2636
  }
2604
2637
  while(( g_prefork_server->m_pChildrenStatusCur > g_prefork_server->m_pChildrenStatus )
@@ -2868,6 +2901,11 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re
2868
2901
  s_ppid = getppid();
2869
2902
  s_req_processed = 0;
2870
2903
  s_pChildStatus = child_status;
2904
+
2905
+ s_pChildStatus->m_connected = 1;
2906
+ if (s_busy_workers)
2907
+ __sync_fetch_and_add(s_busy_workers, 1);
2908
+
2871
2909
  lsapi_set_nblock( pReq->m_fd, 0 );
2872
2910
  if ( pReq->m_fdListen != -1 )
2873
2911
  {
@@ -2938,6 +2976,9 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
2938
2976
 
2939
2977
  LSAPI_Finish_r( pReq );
2940
2978
 
2979
+ if (s_max_busy_children > 0 && s_busy_workers
2980
+ && *s_busy_workers >= s_max_busy_children)
2981
+ lsapi_close_connection(pReq);
2941
2982
 
2942
2983
  if ( g_prefork_server )
2943
2984
  {
@@ -3006,7 +3047,13 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
3006
3047
  pReq->m_fd = lsapi_accept( pReq->m_fdListen );
3007
3048
  if ( pReq->m_fd != -1 )
3008
3049
  {
3050
+ if (s_pChildStatus)
3051
+ s_pChildStatus->m_connected = 1;
3052
+ if (s_busy_workers)
3053
+ __sync_fetch_and_add(s_busy_workers, 1);
3054
+
3009
3055
  fd = pReq->m_fd;
3056
+
3010
3057
  lsapi_set_nblock( fd, 0 );
3011
3058
  //init_conn_key( pReq->m_fd );
3012
3059
  if ( !s_keepListener )
@@ -3043,8 +3090,7 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq )
3043
3090
  ++s_req_processed;
3044
3091
  return 0;
3045
3092
  }
3046
- lsapi_close( pReq->m_fd );
3047
- pReq->m_fd = -1;
3093
+ lsapi_close_connection(pReq);
3048
3094
  LSAPI_Reset_r( pReq );
3049
3095
  }
3050
3096
  return -1;
@@ -3187,11 +3233,88 @@ static int lsapi_initSuEXEC(void)
3187
3233
  }
3188
3234
 
3189
3235
 
3236
+ static int lsapi_check_path(const char *p, char *final, int max_len)
3237
+ {
3238
+ char resolved_path[PATH_MAX+1];
3239
+ int len = 0;
3240
+ char *end, *temp;
3241
+ if (*p != '/')
3242
+ {
3243
+ if (getcwd(final, max_len) == NULL)
3244
+ return -1;
3245
+ len = strlen(final);
3246
+ *(final + len) = '/';
3247
+ ++len;
3248
+ }
3249
+ end = memccpy(&final[len], p, '\0', PATH_MAX - len);
3250
+ if (!end)
3251
+ {
3252
+ errno = EINVAL;
3253
+ return -1;
3254
+ }
3255
+ p = final;
3256
+ if (realpath(p, resolved_path) == NULL
3257
+ && errno != ENOENT && errno != EACCES)
3258
+ return -1;
3259
+ if (strncmp(resolved_path, "/etc/", 5) == 0)
3260
+ {
3261
+ errno = EPERM;
3262
+ return -1;
3263
+ }
3264
+ return 0;
3265
+ }
3266
+
3267
+
3268
+ static int lsapi_reopen_stderr2(const char *full_path)
3269
+ {
3270
+ int newfd = open(full_path, O_WRONLY | O_CREAT | O_APPEND, 0644);
3271
+ if (newfd == -1)
3272
+ {
3273
+ LSAPI_perror_r(NULL, "failed to open custom stderr log", full_path);
3274
+ return -1;
3275
+ }
3276
+ if (newfd != 2)
3277
+ {
3278
+ dup2(newfd, 2);
3279
+ close(newfd);
3280
+ dup2(2, 1);
3281
+ }
3282
+ if (s_pStderrLog && full_path != s_pStderrLog)
3283
+ {
3284
+ free(s_pStderrLog);
3285
+ s_pStderrLog = NULL;
3286
+ }
3287
+ s_pStderrLog = strdup(full_path);
3288
+ return 0;
3289
+ }
3290
+
3291
+
3292
+ static int lsapi_reopen_stderr(const char *p)
3293
+ {
3294
+ char full_path[PATH_MAX];
3295
+ if (s_uid == 0)
3296
+ return -1;
3297
+ if (lsapi_check_path(p, full_path, PATH_MAX) == -1)
3298
+ {
3299
+ LSAPI_perror_r(NULL, "invalid custom stderr log path", p);
3300
+ return -1;
3301
+ }
3302
+ return lsapi_reopen_stderr2(full_path);
3303
+ }
3304
+
3305
+
3190
3306
  int LSAPI_Init_Env_Parameters( fn_select_t fp )
3191
3307
  {
3192
3308
  const char *p;
3193
3309
  int n;
3194
3310
  int avoidFork = 0;
3311
+
3312
+ p = getenv("LSAPI_STDERR_LOG");
3313
+ if (p)
3314
+ {
3315
+ lsapi_reopen_stderr(p);
3316
+ }
3317
+
3195
3318
  p = getenv( "PHP_LSAPI_MAX_REQUESTS" );
3196
3319
  if ( !p )
3197
3320
  p = getenv( "LSAPI_MAX_REQS" );
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{ruby-lsapi}
3
- s.version = "4.3"
4
- s.date = %q{2017-03-06}
3
+ s.version = "4.4"
4
+ s.date = %q{2018-01-18}
5
5
  s.description = "This is a ruby extension for fast communication with LiteSpeed Web Server."
6
6
  s.summary = %q{A ruby extension for fast communication with LiteSpeed Web Server.}
7
7
  s.has_rdoc = false
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsapi
3
3
  version: !ruby/object:Gem::Version
4
- version: '4.3'
4
+ version: '4.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - LiteSpeed Technologies Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-06 00:00:00.000000000 Z
11
+ date: 2018-01-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This is a ruby extension for fast communication with LiteSpeed Web Server.
14
14
  email: info@litespeedtech.com
@@ -49,7 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
49
  version: '0'
50
50
  requirements: []
51
51
  rubyforge_project: ruby-lsapi
52
- rubygems_version: 2.4.5.1
52
+ rubygems_version: 2.2.5
53
53
  signing_key:
54
54
  specification_version: 4
55
55
  summary: A ruby extension for fast communication with LiteSpeed Web Server.