Synthesize EOF events in SCGI
This commit is contained in:
		@@ -1544,6 +1544,8 @@ struct request_handler
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/// Handle incoming data.  "len == 0" means EOF.
 | 
						/// Handle incoming data.  "len == 0" means EOF.
 | 
				
			||||||
	/// Returns false if there is no more processing to be done.
 | 
						/// Returns false if there is no more processing to be done.
 | 
				
			||||||
 | 
						// FIXME: the EOF may or may not be delivered when request is cut short,
 | 
				
			||||||
 | 
						//   we should fix FastCGI not to deliver it on CONTENT_LENGTH mismatch
 | 
				
			||||||
	bool (*push_cb) (struct request *request, const void *data, size_t len);
 | 
						bool (*push_cb) (struct request *request, const void *data, size_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Destroy the handler's data stored in the request object
 | 
						/// Destroy the handler's data stored in the request object
 | 
				
			||||||
@@ -1655,7 +1657,8 @@ request_handler_json_rpc_push
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: check buf.len against CONTENT_LENGTH; if it's less, then the
 | 
						// TODO: check buf.len against CONTENT_LENGTH; if it's less, then the
 | 
				
			||||||
	//   client hasn't been successful in transferring all of its data
 | 
						//   client hasn't been successful in transferring all of its data.
 | 
				
			||||||
 | 
						//   See also comment on request_handler::push_cb.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct str response = str_make ();
 | 
						struct str response = str_make ();
 | 
				
			||||||
	str_append (&response, "Status: 200 OK\n");
 | 
						str_append (&response, "Status: 200 OK\n");
 | 
				
			||||||
@@ -2202,6 +2205,7 @@ struct client_scgi
 | 
				
			|||||||
	struct client client;               ///< Parent class
 | 
						struct client client;               ///< Parent class
 | 
				
			||||||
	struct scgi_parser parser;          ///< SCGI stream parser
 | 
						struct scgi_parser parser;          ///< SCGI stream parser
 | 
				
			||||||
	struct request request;             ///< Request (only one per connection)
 | 
						struct request request;             ///< Request (only one per connection)
 | 
				
			||||||
 | 
						unsigned long remaining_content;    ///< Length of input data to be seen
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@@ -2223,6 +2227,12 @@ static bool
 | 
				
			|||||||
client_scgi_on_headers_read (void *user_data)
 | 
					client_scgi_on_headers_read (void *user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct client_scgi *self = user_data;
 | 
						struct client_scgi *self = user_data;
 | 
				
			||||||
 | 
						const char *cl = str_map_find (&self->parser.headers, "CONTENT_LENGTH");
 | 
				
			||||||
 | 
						if (!cl || !xstrtoul (&self->remaining_content, cl, 10))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							print_debug ("SCGI request with invalid or missing CONTENT_LENGTH");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return request_start (&self->request, &self->parser.headers);
 | 
						return request_start (&self->request, &self->parser.headers);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2230,11 +2240,19 @@ static bool
 | 
				
			|||||||
client_scgi_on_content (void *user_data, const void *data, size_t len)
 | 
					client_scgi_on_content (void *user_data, const void *data, size_t len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct client_scgi *self = user_data;
 | 
						struct client_scgi *self = user_data;
 | 
				
			||||||
 | 
						if (len > self->remaining_content)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							print_debug ("SCGI request got more data than CONTENT_LENGTH");
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// We're in a slight disagreement with the specification since
 | 
				
			||||||
 | 
						// this tries to write output before it has read all the input
 | 
				
			||||||
 | 
						if (!request_push (&self->request, data, len))
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// XXX: do we have to count CONTENT_LENGTH and supply our own EOF?
 | 
						// Signalise end of input to the request handler
 | 
				
			||||||
	//   If we do produce our own EOF, we should probably make sure we don't
 | 
						return (self->remaining_content -= len) != 0
 | 
				
			||||||
	//   send it twice in a row.
 | 
							|| request_push (&self->request, NULL, 0);
 | 
				
			||||||
	return request_push (&self->request, data, len);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user