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; }