Browse Source

Finish the FastCGI backend

Bump liberty, also fixing SCGI.
Přemysl Janouch 3 months ago
parent
commit
d883f4cc71
Signed by: Přemysl Janouch <p@janouch.name> GPG Key ID: A0420B94F92B9493
2 changed files with 75 additions and 81 deletions
  1. 74
    80
      demo-json-rpc-server.c
  2. 1
    1
      liberty

+ 74
- 80
demo-json-rpc-server.c View File

@@ -194,6 +194,8 @@ fcgi_request_new (void)
194 194
 
195 195
 	self->hdr_parser = fcgi_nv_parser_make ();
196 196
 	self->hdr_parser.output = &self->headers;
197
+
198
+	self->output_buffer = str_make ();
197 199
 	return self;
198 200
 }
199 201
 
@@ -208,40 +210,6 @@ fcgi_request_destroy (struct fcgi_request *self)
208 210
 	free (self);
209 211
 }
210 212
 
211
-static void
212
-fcgi_request_push_params
213
-	(struct fcgi_request *self, const void *data, size_t len)
214
-{
215
-	if (self->state != FCGI_REQUEST_PARAMS)
216
-	{
217
-		// TODO: probably reject the request
218
-		return;
219
-	}
220
-
221
-	if (len)
222
-		fcgi_nv_parser_push (&self->hdr_parser, data, len);
223
-	else
224
-	{
225
-		// TODO: probably check the state of the header parser
226
-		// TODO: request_start() can return false, end the request here?
227
-		(void) self->muxer->request_start_cb (self);
228
-		self->state = FCGI_REQUEST_STDIN;
229
-	}
230
-}
231
-
232
-static void
233
-fcgi_request_push_stdin
234
-	(struct fcgi_request *self, const void *data, size_t len)
235
-{
236
-	if (self->state != FCGI_REQUEST_STDIN)
237
-	{
238
-		// TODO: probably reject the request
239
-		return;
240
-	}
241
-
242
-	self->muxer->request_push_cb (self, data, len);
243
-}
244
-
245 213
 static void
246 214
 fcgi_request_flush (struct fcgi_request *self)
247 215
 {
@@ -294,36 +262,62 @@ fcgi_request_finish (struct fcgi_request *self)
294 262
 	self->muxer->requests[self->request_id] = NULL;
295 263
 	fcgi_request_destroy (self);
296 264
 
297
-	// TODO: tear down (shut down) the connection.  This is called from:
298
-	//
299
-	//   1. client_fcgi_request_push <- request_push_cb
300
-	//     <- fcgi_request_push_stdin <- fcgi_muxer_on_stdin
301
-	//     <- fcgi_muxer_on_message <- fcgi_parser_push <- fcgi_muxer_push
302
-	//     <- client_fcgi_push <- client_read_loop
303
-	//     => in this case no close_cb may be called
304
-	//     -> need to pass a false boolean aaall the way up,
305
-	//        then client_fcgi_finalize eventually cleans up the rest
306
-	//
307
-	//   2. client_fcgi_request_close_cb <- request_finish
308
-	//     => our direct caller must call fcgi_muxer::close_cb
309
-	//     -> not very nice to delegate it there
310 265
 	return !should_close;
311 266
 }
312 267
 
268
+static bool
269
+fcgi_request_push_params
270
+	(struct fcgi_request *self, const void *data, size_t len)
271
+{
272
+	if (self->state != FCGI_REQUEST_PARAMS)
273
+	{
274
+		print_debug ("FastCGI: expected %s, got %s",
275
+			STRINGIFY (FCGI_STDIN), STRINGIFY (FCGI_PARAMS));
276
+		return false;
277
+	}
278
+
279
+	if (len)
280
+		fcgi_nv_parser_push (&self->hdr_parser, data, len);
281
+	else
282
+	{
283
+		if (self->hdr_parser.state != FCGI_NV_PARSER_NAME_LEN)
284
+			print_debug ("FastCGI: request headers seem to be cut off");
285
+
286
+		self->state = FCGI_REQUEST_STDIN;
287
+		if (!self->muxer->request_start_cb (self))
288
+			return fcgi_request_finish (self);
289
+	}
290
+	return true;
291
+}
292
+
293
+static bool
294
+fcgi_request_push_stdin
295
+	(struct fcgi_request *self, const void *data, size_t len)
296
+{
297
+	if (self->state != FCGI_REQUEST_STDIN)
298
+	{
299
+		print_debug ("FastCGI: expected %s, got %s",
300
+			STRINGIFY (FCGI_PARAMS), STRINGIFY (FCGI_STDIN));
301
+		return false;
302
+	}
303
+
304
+	return self->muxer->request_push_cb (self, data, len);
305
+}
306
+
313 307
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
314 308
 
315
-typedef void (*fcgi_muxer_handler_fn)
309
+typedef bool (*fcgi_muxer_handler_fn)
316 310
 	(struct fcgi_muxer *, const struct fcgi_parser *);
317 311
 
318
-static void
312
+static bool
319 313
 fcgi_muxer_on_get_values
320 314
 	(struct fcgi_muxer *self, const struct fcgi_parser *parser)
321 315
 {
322 316
 	if (parser->request_id != FCGI_NULL_REQUEST_ID)
323 317
 	{
324
-		print_debug ("FastCGI: ignoring invalid %s message",
318
+		print_debug ("FastCGI: invalid %s message",
325 319
 			STRINGIFY (FCGI_GET_VALUES));
326
-		return;
320
+		return false;
327 321
 	}
328 322
 
329 323
 	struct str_map values   = str_map_make (free);
@@ -357,9 +351,10 @@ fcgi_muxer_on_get_values
357 351
 
358 352
 	str_map_free (&values);
359 353
 	str_map_free (&response);
354
+	return true;
360 355
 }
361 356
 
362
-static void
357
+static bool
363 358
 fcgi_muxer_on_begin_request
364 359
 	(struct fcgi_muxer *self, const struct fcgi_parser *parser)
365 360
 {
@@ -375,16 +370,17 @@ fcgi_muxer_on_begin_request
375 370
 
376 371
 	if (!success)
377 372
 	{
378
-		print_debug ("FastCGI: ignoring invalid %s message",
373
+		print_debug ("FastCGI: invalid %s message",
379 374
 			STRINGIFY (FCGI_BEGIN_REQUEST));
380
-		return;
375
+		return false;
381 376
 	}
382 377
 
383 378
 	struct fcgi_request *request = self->requests[parser->request_id];
384 379
 	if (parser->request_id == FCGI_NULL_REQUEST_ID || request)
385 380
 	{
386
-		// TODO: fail
387
-		return;
381
+		print_debug ("FastCGI: unusable request ID in %s message",
382
+			STRINGIFY (FCGI_BEGIN_REQUEST));
383
+		return false;
388 384
 	}
389 385
 
390 386
 	// We can only act as a responder, reject everything else up front
@@ -392,7 +388,7 @@ fcgi_muxer_on_begin_request
392 388
 	{
393 389
 		fcgi_muxer_send_end_request (self,
394 390
 			parser->request_id, 0, FCGI_UNKNOWN_ROLE);
395
-		return;
391
+		return true;
396 392
 	}
397 393
 
398 394
 	if (parser->request_id >= N_ELEMENTS (self->requests)
@@ -400,7 +396,7 @@ fcgi_muxer_on_begin_request
400 396
 	{
401 397
 		fcgi_muxer_send_end_request (self,
402 398
 			parser->request_id, 0, FCGI_OVERLOADED);
403
-		return;
399
+		return true;
404 400
 	}
405 401
 
406 402
 	request = fcgi_request_new ();
@@ -410,9 +406,10 @@ fcgi_muxer_on_begin_request
410 406
 
411 407
 	self->requests[parser->request_id] = request;
412 408
 	self->active_requests++;
409
+	return true;
413 410
 }
414 411
 
415
-static void
412
+static bool
416 413
 fcgi_muxer_on_abort_request
417 414
 	(struct fcgi_muxer *self, const struct fcgi_parser *parser)
418 415
 {
@@ -421,15 +418,13 @@ fcgi_muxer_on_abort_request
421 418
 	{
422 419
 		print_debug ("FastCGI: received %s for an unknown request",
423 420
 			STRINGIFY (FCGI_ABORT_REQUEST));
424
-		return;
421
+		return true;  // We might have just rejected it
425 422
 	}
426 423
 
427
-	// TODO: abort the request: let it somehow produce FCGI_END_REQUEST,
428
-	// make sure to send an stdout EOF record
429
-	// TODO: and if that was not a FCGI_KEEP_CONN request, close the transport
424
+	return fcgi_request_finish (request);
430 425
 }
431 426
 
432
-static void
427
+static bool
433 428
 fcgi_muxer_on_params (struct fcgi_muxer *self, const struct fcgi_parser *parser)
434 429
 {
435 430
 	struct fcgi_request *request = self->requests[parser->request_id];
@@ -437,14 +432,15 @@ fcgi_muxer_on_params (struct fcgi_muxer *self, const struct fcgi_parser *parser)
437 432
 	{
438 433
 		print_debug ("FastCGI: received %s for an unknown request",
439 434
 			STRINGIFY (FCGI_PARAMS));
440
-		return;
435
+		return true;  // We might have just rejected it
441 436
 	}
442 437
 
443
-	fcgi_request_push_params (request,
438
+	// This may immediately finish and delete the request, but that's fine
439
+	return fcgi_request_push_params (request,
444 440
 		parser->content.str, parser->content.len);
445 441
 }
446 442
 
447
-static void
443
+static bool
448 444
 fcgi_muxer_on_stdin (struct fcgi_muxer *self, const struct fcgi_parser *parser)
449 445
 {
450 446
 	struct fcgi_request *request = self->requests[parser->request_id];
@@ -452,15 +448,15 @@ fcgi_muxer_on_stdin (struct fcgi_muxer *self, const struct fcgi_parser *parser)
452 448
 	{
453 449
 		print_debug ("FastCGI: received %s for an unknown request",
454 450
 			STRINGIFY (FCGI_STDIN));
455
-		return;
451
+		return true;  // We might have just rejected it
456 452
 	}
457 453
 
458 454
 	// At the end of the stream, a zero-length record is received
459
-	fcgi_request_push_stdin (request,
455
+	return fcgi_request_push_stdin (request,
460 456
 		parser->content.str, parser->content.len);
461 457
 }
462 458
 
463
-static void
459
+static bool
464 460
 fcgi_muxer_on_message (const struct fcgi_parser *parser, void *user_data)
465 461
 {
466 462
 	struct fcgi_muxer *self = user_data;
@@ -468,8 +464,7 @@ fcgi_muxer_on_message (const struct fcgi_parser *parser, void *user_data)
468 464
 	if (parser->version != FCGI_VERSION_1)
469 465
 	{
470 466
 		print_debug ("FastCGI: unsupported version %d", parser->version);
471
-		// TODO: also return false to stop processing on protocol error?
472
-		return;
467
+		return false;
473 468
 	}
474 469
 
475 470
 	static const fcgi_muxer_handler_fn handlers[] =
@@ -489,10 +484,10 @@ fcgi_muxer_on_message (const struct fcgi_parser *parser, void *user_data)
489 484
 		uint8_t content[8] = { parser->type };
490 485
 		fcgi_muxer_send (self, FCGI_UNKNOWN_TYPE, parser->request_id,
491 486
 			content, sizeof content);
492
-		return;
487
+		return true;
493 488
 	}
494 489
 
495
-	handler (self, parser);
490
+	return handler (self, parser);
496 491
 }
497 492
 
498 493
 static void
@@ -520,10 +515,10 @@ fcgi_muxer_free (struct fcgi_muxer *self)
520 515
 	fcgi_parser_free (&self->parser);
521 516
 }
522 517
 
523
-static void
518
+static bool
524 519
 fcgi_muxer_push (struct fcgi_muxer *self, const void *data, size_t len)
525 520
 {
526
-	fcgi_parser_push (&self->parser, data, len);
521
+	return fcgi_parser_push (&self->parser, data, len);
527 522
 }
528 523
 
529 524
 /// @}
@@ -1574,7 +1569,7 @@ struct request
1574 1569
 	/// Callback to write some CGI response data to the output
1575 1570
 	void (*write_cb) (struct request *, const void *data, size_t len);
1576 1571
 
1577
-	/// Callback to close the connection.
1572
+	/// Callback to close the CGI response, simulates end of program execution.
1578 1573
 	/// CALLING THIS MAY CAUSE THE REQUEST TO BE DESTROYED.
1579 1574
 	void (*close_cb) (struct request *);
1580 1575
 };
@@ -1967,7 +1962,7 @@ client_destroy (struct client *self)
1967 1962
 static void
1968 1963
 client_write (struct client *self, const void *data, size_t len)
1969 1964
 {
1970
-	if (!soft_assert (!self->flushing))
1965
+	if (!soft_assert (!self->flushing) || len == 0)
1971 1966
 		return;
1972 1967
 
1973 1968
 	struct write_req *req = xcalloc (1, sizeof *req);
@@ -2206,8 +2201,7 @@ static bool
2206 2201
 client_fcgi_push (struct client *client, const void *data, size_t len)
2207 2202
 {
2208 2203
 	FIND_CONTAINER (self, client, struct client_fcgi, client);
2209
-	fcgi_muxer_push (&self->muxer, data, len);
2210
-	return true;
2204
+	return fcgi_muxer_push (&self->muxer, data, len);
2211 2205
 }
2212 2206
 
2213 2207
 static void

+ 1
- 1
liberty

@@ -1 +1 @@
1
-Subproject commit 9494e8e2affcd08b791d3ecf68985a8a3a310e55
1
+Subproject commit bca7167d037d857448cb18243425d7c61de3bdd5

Loading…
Cancel
Save