Beispiel #1
0
int fcgi_header_setoradd(struct fcgi_headers* headers, const char* name, const char* value) {
	int r = 0;
	if (!(r = fcgi_header_set(headers, name, value))) r = fcgi_header_add(headers, name, value);
	return r;
}
int fcgi_server_send_stdin_record(fcgi_request_t *fr, uint16_t request_id,
		void *record_buffer)
{
	apr_bucket_brigade *bb = apr_brigade_create(fr->r->pool,
			fr->r->connection->bucket_alloc);

	int seen_eos = 0, server_stopped_reading = 0;
	apr_status_t rv;

	do {
		apr_bucket *bucket;

		rv = ap_get_brigade(fr->r->input_filters, bb, AP_MODE_READBYTES,
				APR_BLOCK_READ, HUGE_STRING_LEN);

		if (rv != APR_SUCCESS) {
			ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, fr->r,
					"FastCGI: error reading request entity data");
			return HTTP_INTERNAL_SERVER_ERROR;
		}

		for (bucket = APR_BRIGADE_FIRST(bb);
				bucket != APR_BRIGADE_SENTINEL(bb);
				bucket = APR_BUCKET_NEXT(bucket))
		{
			const char *data;
			apr_size_t len;

			if (APR_BUCKET_IS_EOS(bucket)) {
				seen_eos = 1;
				break;
			}

			/* We can't do much with this. */
			if (APR_BUCKET_IS_FLUSH(bucket)) {
				continue;
			}

			/* if the FastCGI server stopped reading, we still must read to EOS. */
			if (server_stopped_reading) {
				continue;
			}

			/* read from client */
			apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);

			/* build FCGI_STDIN record
			 *
			 * A bucket can hold up to 8000 bytes. Since FastCGI packets can be
			 * up to 64K we don't have to worry about to much stdin data being
			 * read in one single iteration.
			 */
			int padding_length = fcgi_record_build((fcgi_header_t)record_buffer,
					request_id, FCGI_STDIN, len);

			/* send header data to the FastCGI server */
			ssize_t bytes_sent = socket_send(fr,
					record_buffer, FCGI_HEADER_LEN);

			if (bytes_sent == -1) {
				server_stopped_reading = 1;
				continue;
			}

			/* send stdin data to the FastCGI server */
			bytes_sent = socket_send(fr, (char *)data, len);

			if (bytes_sent == -1) {
				server_stopped_reading = 1;
				continue;
			}

			/* send padding to the FastCGI server */
			bytes_sent = socket_send(fr,
					((char *)record_buffer) + FCGI_HEADER_LEN + len,
					padding_length);

			if (bytes_sent == -1) {
				server_stopped_reading = 1;
				continue;
			}
		}

		apr_brigade_cleanup(bb);
	} while (!seen_eos);

	apr_brigade_cleanup(bb);

	/* build void FCGI_STDIN record */
	fcgi_header_set((fcgi_header_t)record_buffer, FCGI_VERSION_1, FCGI_STDIN, request_id, 0, 0);

	/* send data to the FastCGI server */
	ssize_t bytes_sent = socket_send(fr, record_buffer, FCGI_HEADER_LEN);

	if (bytes_sent == -1) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR, errno, fr->r,
				"FastCGI: failed to write to backend server (id=%u)", request_id);
		return HTTP_INTERNAL_SERVER_ERROR;
	}

	return OK;
}