Example #1
0
static BOOL SendResponseHeaderEx(isapi_cid *cid, const char *stat,
                                 const char *head, DWORD statlen,
                                 DWORD headlen)
{
    int termarg;
    char *termch;

    if (!stat || statlen == 0 || !*stat) {
        stat = "Status: 200 OK";
    }
    else {
        char *newstat;
        newstat = ap_palloc(cid->r->pool, statlen + 9);
        strcpy(newstat, "Status: ");
        ap_cpystrn(newstat + 8, stat, statlen + 1);
        stat = newstat;
    }

    if (!head || headlen == 0 || !*head) {
        head = "\r\n";
    }
    else
    {
        if (head[headlen]) {
            /* Whoops... not NULL terminated */
            head = ap_pstrndup(cid->r->pool, head, headlen);
        }
    }

    /* Parse them out, or die trying */
    cid->status = ap_scan_script_header_err_strs(cid->r, NULL, &termch,
                                                 &termarg, stat, head, NULL);
    cid->ecb->dwHttpStatusCode = cid->r->status;

    /* All the headers should be set now */
    ap_send_http_header(cid->r);

    /* Any data left should now be sent directly,
     * it may be raw if headlen was provided.
     */
    if (termch && (termarg == 1)) {
        if (headlen == -1 && *termch)
            ap_rputs(termch, cid->r);
        else if (headlen > (size_t) (termch - head))
            ap_rwrite(termch, headlen - (termch - head), cid->r);
    }

    if (cid->status == HTTP_INTERNAL_SERVER_ERROR)
        return FALSE;
    return TRUE;
}
/* copied from mod_cgi.c and slightly modified
 * to work with fcgi_record types */
static
int fcgi_server_parse_headers(fcgi_request_t *fr, uint16_t request_id,
		char **data)
{
	request_rec *r = fr->r;
	int ret, termarg;

	if ((ret = ap_scan_script_header_err_strs(r, NULL, (const char **)data, &termarg, *data, NULL))) {
		/*
		 * ret could be HTTP_NOT_MODIFIED in the case that the CGI script
		 * does not set an explicit status and ap_meets_conditions, which
		 * is called by ap_scan_script_header_err_brigade, detects that
		 * the conditions of the requests are met and the response is
		 * not modified.
		 * In this case set r->status and return OK in order to prevent
		 * running through the error processing stack as this would
		 * break with mod_cache, if the conditions had been set by
		 * mod_cache itself to validate a stale entity.
		 * BTW: We circumvent the error processing stack anyway if the
		 * CGI script set an explicit status code (whatever it is) and
		 * the only possible values for ret here are:
		 *
		 * HTTP_NOT_MODIFIED          (set by ap_meets_conditions)
		 * HTTP_PRECONDITION_FAILED   (set by ap_meets_conditions)
		 * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the
		 * processing of the response of the CGI script, e.g broken headers
		 * or a crashed CGI process).
		 */
		if (ret == HTTP_NOT_MODIFIED) {
			r->status = ret;
			return OK;
		}

		return ret;
	}

	const char *location = apr_table_get(r->headers_out, "Location");

#if 0
	if (location && r->status == 200) {
		/* For a redirect whether internal or not, discard any
		 * remaining stdout from the script, and log any remaining
		 * stderr output, as normal. */
		discard_script_output(bb);
		apr_brigade_destroy(bb);
		apr_file_pipe_timeout_set(script_err, r->server->timeout);
		log_script_err(r, script_err);
	}
#endif

	if (location && location[0] == '/' && r->status == 200) {
		/* This redirect needs to be a GET no matter what the original
		 * method was.
		 */
		r->method = apr_pstrdup(r->pool, "GET");
		r->method_number = M_GET;

		/* We already read the message body (if any), so don't allow
		 * the redirected request to think it has one.  We can ignore
		 * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR.
		 */
		apr_table_unset(r->headers_in, "Content-Length");

		ap_internal_redirect_handler(location, r);
		return OK;
	}

	else if (location && r->status == 200) {
		/* XX Note that if a script wants to produce its own Redirect
		 * body, it now has to explicitly *say* "Status: 302"
		 */
		return HTTP_MOVED_TEMPORARILY;
	}
}