コード例 #1
0
ファイル: highlander.c プロジェクト: timburks/highland
/* Call the callback function for the page */
int handle_dynamic(
	http_server srv,
	dynamic_page p,
	http_request req,
	http_response response,
	meta_error e)
{
	int status = HTTP_200_OK;
	http_version version;

	assert(NULL != p);

	version = request_get_version(req);
	if(!fs_can_run(srv, req, p)) {
		response_set_status(response, HTTP_406_NOT_ACCEPTABLE);
		return set_http_error(e, HTTP_406_NOT_ACCEPTABLE);
	}
	else {
		response_set_version(response, version);
		response_set_last_modified(response, time(NULL));

		/* Run the dynamic function. It is supposed to return 0 for OK,
		 * but we accept any legal HTTP status code. Illegal status codes
		 * are mapped to 500.
		 */
		if( (status = dynamic_run(p, req, response)))
			status = http_status_code(status) ? status : HTTP_500_INTERNAL_SERVER_ERROR;
		else
			status = HTTP_200_OK;

		response_set_status(response, status);
		return 1;
	}
}
コード例 #2
0
ファイル: util.c プロジェクト: snimmagadda/http
int
proxy_connect(int fd, struct url *url)
{
	char	buf[MAX_LINE];
	ssize_t	r;

	r = writeline(fd,
	    "CONNECT %s:%s HTTP/1.0\r\n"
	    "Host: %s\r\n"
	    "User-Agent: %s\r\n"
	    "%s%s"
	    "\r\n",
	    url->host,
	    url->port,
	    url->host,
	    ua,
	    url->basic_auth[0] ? "Proxy-Authorization: Basic " : "",
	    url->basic_auth[0] ? url->basic_auth : "");

	if (r == -1)
		return -1;

	if (readline(fd, buf, sizeof buf) <= 0) {
		warnx("proxy_connect: Failed to get proxy response");
		return -1;
	}

	if (http_status_code(buf) != 200)
		errx(1, "proxy_connect: Failed CONNECT to %s:%s\n",
		    url->host, url->port);

	return 0;
}
コード例 #3
0
ファイル: highlander.c プロジェクト: timburks/highland
/**
 * Call this function if the request ended in some kind of HTTP error.
 * Typical errors are 404 not found, 400 bad request. 
 * Do not call it for other errors.
 * 
 * The function sends the proper HTTP headers back to the client 
 * if possible. It also logs the error to the servers log file.
 */
static void handle_http_error(
	http_server srv,
	connection conn,
	http_request req,
	int error)
{
	http_version v;
	assert(http_status_code(error));

	v = request_get_version(req);
	send_status_code(conn, error, v);
	http_server_add_logentry(srv, conn, req, error, 0);
}
コード例 #4
0
ファイル: router_fcgi.c プロジェクト: Variousss/uwsgi
static int uwsgi_routing_func_fcgi(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
	struct uwsgi_buffer *ub = NULL, *headers = NULL;
	int ret = UWSGI_ROUTE_BREAK;
	int inbody = 0;

	// mark a route request
        wsgi_req->via = UWSGI_VIA_ROUTE;

	char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
        uint16_t *subject_len = (uint16_t *)  (((char *)(wsgi_req))+ur->subject_len);

	struct uwsgi_buffer *ub_addr = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
	if (!ub_addr) return UWSGI_ROUTE_BREAK;

	// convert the wsgi_request to an fcgi request
	ub = uwsgi_to_fastcgi(wsgi_req, ur->custom ? FCGI_AUTHORIZER : FCGI_RESPONDER);

	if (!ub) {
		uwsgi_log("unable to generate fcgi request for %s\n", ub_addr->buf);
		uwsgi_buffer_destroy(ub_addr);
                return UWSGI_ROUTE_BREAK;
	}

	int fd = 0;

	fd = fcgi_send(wsgi_req, ub_addr->buf, ub, uwsgi.socket_timeout);
	uwsgi_buffer_destroy(ub);
	ub = NULL;

	if (fd == -1) {
		uwsgi_log("error routing request to fcgi server %s\n", ub_addr->buf);
		goto end;
	}

	headers = uwsgi_buffer_new(uwsgi.page_size);
	char buf[8192];
	char *ptr = buf;//, *rptr = NULL;
	ssize_t left = 0, n = 0, p = 0;
	int oversized = 0, done = 0;


	for (;;) {
                int r = uwsgi_waitfd(fd, uwsgi.socket_timeout);
                if (r <= 0) goto end;

		ssize_t rlen = 0;
		/* Amount left in buffer is not a full record header, so we
		 * need to fudge the next read to append to the current buffer. */
		if ((sizeof(buf) - (ptr - buf) - left) < 8) {
			memmove(buf, ptr, left);
			ptr = buf;
		}

		if ((!done || !left) && (sizeof(buf) - (ptr - buf) - left) > 0) {
			rlen = read(fd, ptr + left, sizeof(buf) - (ptr - buf) - left);

			if (rlen < 0)
				break;
			if (rlen == 0)
				done = 1;
		}

		if (done && !left) {
			uwsgi_log("[fastcgi] %s: truncated response\n", ub_addr->buf);
			goto end;
		}

		if (oversized) { /* n more bytes left in stdout record */
			if (uwsgi_response_write_body_do(wsgi_req, (char *) ptr, n > rlen ? rlen : n))
				goto end;

			if (n > rlen) {
				n -= rlen;
				ptr = buf;
				left = 0;
				continue;
			} else if (n == rlen) {
				oversized = 0;
				left = 0;
				ptr = buf;
				continue;
			} else {
				ptr += n;
				left = rlen - n;
				oversized = 0;
				continue;
			}
		} else {
			left += rlen;
		}

		while (left >= 8 && !oversized) {
			if (p) {
				if (left >= p) {
					left -= p;
					ptr += p;
					p = 0;
					continue;
				}
			}

			if (ptr[0] != 1) { /* version */
				uwsgi_log("[fastcgi] %s: unexpected protocol version %u\n", ub_addr->buf, (unsigned int) ptr[0]);
				goto end;
			}
			if (ptr[2] != 0 || ptr[3] != 1) { /* reqid */
				uwsgi_log("[fastcgi] %s: unexpected request id %d\n", ub_addr->buf, (int) ptr[3]);
				goto end;
			}
			n = (int)((unsigned char *)ptr)[4] << 8 | (int)((unsigned char *)ptr)[5];
			p = (int)((unsigned char *)ptr)[6];

			int type = ptr[1];
			ptr += 8;
			left -= 8;
			switch (type) {
			case FCGI_END_REQUEST:
				break;

			case FCGI_STDERR:
				uwsgi_log("[fastcgi] %s: stderr: %*s\n", ub_addr->buf, (int) (n > left ? left : n), ptr);
				if ((n + p) > left) {
					uwsgi_log("[fastcgi] %s: short record, (%d + %d) < %d\n", ub_addr->buf, (int) n, (int) p, (int) left);
					goto end;
				}
				ptr += (n + p);
				left -= (n + p);
				break;

			case FCGI_STDOUT:
				if (n == 0)
					goto end;

				if (!inbody) {
					ssize_t now = n < left ? n : left;
					if (uwsgi_buffer_append(headers, (char *) ptr, now))
						goto end;

					// check if we have a full HTTP response
					if (uwsgi_is_full_http(headers)) {
						inbody = 1;
						if (ur->custom && http_status_code(headers->buf, headers->pos) == 200) {
							ret = UWSGI_ROUTE_NEXT;
							/* XXX - add Variable headers */
							goto end;
						} else {
							uwsgi_blob_to_response(wsgi_req, headers->buf, headers->pos);
						}
						uwsgi_buffer_destroy(headers);
						headers = NULL;
					} else {
						/* we can't buffer > sizeof(buf) of headers - shouldn't be
						 * needed anyway. */
						if (n > left) {
							uwsgi_log("[fastcgi] %s: headers too long (%d)\n", ub_addr->buf, (int) n);
							goto end;
						}
					}

					ptr += now;
					left -= now;
					n -= now;
				}

				if (n) {
					ssize_t nleft = n > left ? left : n; /* min(left in buffer, record size) */
					if (uwsgi_response_write_body_do(wsgi_req, (char *) ptr, nleft))
						goto end;
					n -= nleft;
					left -= nleft;
					ptr += nleft;

					if (n > left) { /* more data in this record */
						oversized = 1;
						left = 0;
						ptr = buf;
						continue;
					}
				}

				break;

			default:
				uwsgi_log("[fastcgi] %s: unknown record type %d\n", ub_addr->buf, (int) ptr[1]);
				goto end;
			}
		}

		if (left == 0)
			ptr = buf;
	}

end:
	if (fd) close(fd);
	if (ub) uwsgi_buffer_destroy(ub);
	if (ub_addr) uwsgi_buffer_destroy(ub_addr);
	if (headers) uwsgi_buffer_destroy(headers);
	return ret;
}
コード例 #5
0
static int
webid_auth_checker(request_rec *r) {
    int is_initial_req, req_access, req_method, ret;
    const char *req_dest;

    request_rec *r_dest;
    apr_uri_t apr_uri;

    if (r->filename == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                      "Module bug?  Request filename is missing for URI %s", r->uri);
        return http_status_code(r, OK);
    }

    if (r->user == NULL || strlen(r->user) == 0) {
        return http_status_code(r, HTTP_FORBIDDEN);
    }

    // req_access: Read, Write, or Control
    is_initial_req = ap_is_initial_req(r);
    req_access = WEBID_ACCESS_INVALID;
    req_method = (AP_METHOD_BIT << r->method_number);

    if (is_initial_req && r->method_number == M_COPY) {
        // allow COPY of a readonly source URI
        // - target URI check happens by subrequest
        req_access = WEBID_ACCESS_READ;

    } else if (req_method == (req_method & WEBID_M_READ)) {
        // check the acl:Read method bitmask
        req_access = WEBID_ACCESS_READ;

    } else if (req_method == (req_method & WEBID_M_WRITE)) {
        // check the acl:Write method bitmask
        // - writes to ACL URIs are acl:Control (handled internally)
        req_access = WEBID_ACCESS_WRITE;

    } else {
        // unhandled methods require acl:Control
        req_access = WEBID_ACCESS_CONTROL;
    }

    ret = HTTP_FORBIDDEN;

    if (is_initial_req && (r->method_number == M_COPY || r->method_number == M_MOVE)) {
        req_dest = apr_table_get(r->headers_in, "Destination");
        if (req_dest == NULL) {
            const char *nscp_host = apr_table_get(r->headers_in, "Host");
            const char *nscp_path = apr_table_get(r->headers_in, "New-uri");
            if (nscp_host != NULL && nscp_path != NULL)
                req_dest = apr_psprintf(r->pool, "http://%s%s", nscp_host, nscp_path);
        }
        if (req_dest != NULL) {
            if ((apr_uri_parse(r->pool, req_dest, &apr_uri) == APR_SUCCESS) &&
                (apr_uri.scheme != NULL && strcmp(apr_uri.scheme, ap_http_scheme(r)) == 0) &&
                (apr_uri.hostname != NULL && strcmp(apr_uri.hostname, ap_get_server_name(r)) == 0)) {
                req_dest = apr_uri_unparse(r->pool, &apr_uri, APR_URI_UNP_OMITSITEPART);
                r_dest = ap_sub_req_method_uri(r->method, req_dest, r, NULL);
                if ((ret = check_request_acl(r, req_access)) == OK)
                    ret = check_request_acl(r_dest, WEBID_ACCESS_WRITE);
            } else {
                ret = HTTP_BAD_GATEWAY;
            }
        }
    } else {
        ret = check_request_acl(r, req_access);
    }

    return http_status_code(r, ret);
}