- /* ready to read from cgi program */
- if( FD_ISSET(rfd[0], &reader) )
- {
- /* read data from child ... */
- if( (buflen = read(rfd[0], buf, sizeof(buf))) > 0 )
- {
- /* we have not pushed out headers yet, parse input */
- if( ! header_sent )
- {
- /* head buffer not full and no end yet */
- if( hdrlen < sizeof(hdr) )
- {
- bufoff = min(buflen, sizeof(hdr) - hdrlen);
- memcpy(&hdr[hdrlen], buf, bufoff);
- hdrlen += bufoff;
- }
- else
- {
- bufoff = 0;
- }
-
-
- /* try to parse header ... */
- if( (res = uh_cgi_header_parse(hdr, hdrlen, &hdroff)) != NULL )
- {
- /* write status */
- ensure_out(uh_http_sendf(cl, NULL,
- "HTTP/%.1f %03d %s\r\n"
- "Connection: close\r\n",
- req->version, res->statuscode,
- res->statusmsg));
-
- /* add Content-Type if no Location or Content-Type */
- if( !uh_cgi_header_lookup(res, "Location") &&
- !uh_cgi_header_lookup(res, "Content-Type")
- ) {
- ensure_out(uh_http_send(cl, NULL,
- "Content-Type: text/plain\r\n", -1));
- }
-
- /* if request was HTTP 1.1 we'll respond chunked */
- if( (req->version > 1.0) &&
- !uh_cgi_header_lookup(res, "Transfer-Encoding")
- ) {
- ensure_out(uh_http_send(cl, NULL,
- "Transfer-Encoding: chunked\r\n", -1));
- }
-
- /* write headers from CGI program */
- foreach_header(i, res->headers)
- {
- ensure_out(uh_http_sendf(cl, NULL, "%s: %s\r\n",
- res->headers[i], res->headers[i+1]));
- }
-
- /* terminate header */
- ensure_out(uh_http_send(cl, NULL, "\r\n", -1));
-
- /* push out remaining head buffer */
- if( hdroff < hdrlen )
- ensure_out(uh_http_send(cl, req, &hdr[hdroff], hdrlen - hdroff));
- }
-
- /* ... failed and head buffer exceeded */
- else if( hdrlen >= sizeof(hdr) )
- {
- ensure_out(uh_cgi_error_500(cl, req,
- "The CGI program generated an invalid response:\n\n"));
-
- ensure_out(uh_http_send(cl, req, hdr, hdrlen));
- }
-
- /* ... failed but free buffer space, try again */
- else
- {
- continue;
- }
-
- /* push out remaining read buffer */
- if( bufoff < buflen )
- ensure_out(uh_http_send(cl, req, &buf[bufoff], buflen - bufoff));
-
- header_sent = 1;
- continue;
- }