コード例 #1
0
ファイル: io.c プロジェクト: tinyserver/uwsgi
int uwsgi_proxy_nb(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffer *ub, size_t remains, int timeout) {

        int fd = uwsgi_connect(addr, 0, 1);
        if (fd < 0) {
		return -1;
        }

        int ret = uwsgi.wait_write_hook(fd, timeout);
        if (ret <= 0) {
		goto end;
        }

        // send the request (+ remaining data)
	if (ub) {
        	if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout)) {
			goto end;
        	}
	}

        // send the body
        while(remains > 0) {
                ssize_t rlen = 0;
                char *buf = uwsgi_request_body_read(wsgi_req, 8192, &rlen);
                if (!buf) {
			goto end;
                }
                if (buf == uwsgi.empty) break;
                // write data to the node
                if (uwsgi_write_true_nb(fd, buf, rlen, timeout)) {
			goto end;
                }
                remains -= rlen;
        }

        // read the response
        for(;;) {
                char buf[8192];
                ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, timeout);
                if (rlen > 0) {
                        if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) {
                                break;
                        }
                        continue;
                }
                break;
        }

	close(fd);
	return 0;
end:
	close(fd);
	return -1;
}
コード例 #2
0
ファイル: wstcp.c プロジェクト: unbit/uwsgi-wstcp
int uwsgi_wstcp(struct wsgi_request *wsgi_req) {
    if (uwsgi_parse_vars(wsgi_req)) return -1;

    // handshake the websocket connection
    if (uwsgi_websocket_handshake(wsgi_req, NULL, 0, NULL, 0, NULL, 0)) return -1;

    // async connect to the tcp server
    int fd = uwsgi_connect("127.0.0.1:9090", 0, 1);
    if (fd < 0) return -1;

    // wait for connection
    int ret = uwsgi.wait_write_hook(fd, 30);
    if (ret <= 0) {
        close(fd);
        return -1;
    }

    // ok we are connected, enter the main loop
    for(;;) {
        int ready_fd = -1;
        // wait for both websockets and tcp
        int ret = uwsgi.wait_read2_hook(wsgi_req->fd, fd, 30, &ready_fd);
        if (ret <= 0) break;
        // websocket message
        if (ready_fd == wsgi_req->fd) {
            // read websocket message
            struct uwsgi_buffer *ub = uwsgi_websocket_recv_nb(wsgi_req);
            if (!ub) break;
            // send to tcp
            if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, 30)) break;
        }
        // packet from tcp
        else if (ready_fd == fd) {
            char buf[8192];
            // read from the tcp socket
            ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, 30);
            if (rlen <= 0) break;
            // send to the websocket
            if (uwsgi_websocket_send_binary(wsgi_req, buf, rlen)) break;
        }
    }

    // end of the session
    close(fd);
    return UWSGI_OK;
}
コード例 #3
0
ファイル: router_fcgi.c プロジェクト: Variousss/uwsgi
static int fcgi_send(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffer *ub, int timeout) {
	int fd = uwsgi_connect(addr, 0, 1);
	if (fd < 0)
		return -1;

	int ret = uwsgi.wait_write_hook(fd, timeout);
	if (ret <= 0)
		goto error;

	if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout))
		goto error;

	return fd;

error:
	close(fd);
	return -1;
}
コード例 #4
0
ファイル: cgi_plugin.c プロジェクト: vine/uwsgi
static int uwsgi_cgi_run(struct wsgi_request *wsgi_req, char *docroot, size_t docroot_len, char *full_path, char *helper, char *path_info, char *script_name, int is_a_file, int discard_base) {

	int cgi_pipe[2];
	int post_pipe[2];
	int nargs = 0;
	int waitpid_status;
	int i;
	char **argv;

	char *command = full_path;

	if (is_a_file) {
                command = docroot;
        }

	if (pipe(cgi_pipe)) {
		uwsgi_error("uwsgi_cgi_run()/pipe()");
		return UWSGI_OK;
	}

	if (pipe(post_pipe)) {
		close(cgi_pipe[0]);
		close(cgi_pipe[1]);
		uwsgi_error("uwsgi_cgi_run()/pipe()");
		return UWSGI_OK;
	}

	pid_t cgi_pid = fork();

	if (cgi_pid < 0) {
		uwsgi_error("uwsgi_cgi_run()/fork()");
		close(cgi_pipe[0]);
		close(cgi_pipe[1]);
		close(post_pipe[0]);
		close(post_pipe[1]);
		return UWSGI_OK;
	}

	if (cgi_pid > 0) {

		close(cgi_pipe[1]);
		close(post_pipe[0]);

		uwsgi_socket_nb(cgi_pipe[0]);
		uwsgi_socket_nb(post_pipe[1]);

		// ok start sending post data...
		size_t remains = wsgi_req->post_cl;
		while(remains > 0) {
                	ssize_t rlen = 0;
                	char *buf = uwsgi_request_body_read(wsgi_req, 8192, &rlen);
                	if (!buf) {
				goto clear2;
                	}
                	if (buf == uwsgi.empty) break;
                	// write data to the node
                	if (uwsgi_write_true_nb(post_pipe[1], buf, rlen, uc.timeout)) {
				goto clear2;
                	}
                	remains -= rlen;
        	}

		// wait for data
		char *buf = uwsgi_malloc(uc.buffer_size);

		int completed = uwsgi_cgi_parse(wsgi_req, cgi_pipe[0], buf, uc.buffer_size);
		if (completed < 0) {
			uwsgi_log("invalid CGI response !!!\n");
			kill_on_error
			goto clear;
		}
コード例 #5
0
ファイル: router_memcached.c プロジェクト: AGoodId/uwsgi
static int uwsgi_routing_func_memcached(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
	// this is the buffer for the memcached response
	char buf[MEMCACHED_BUFSIZE];
	size_t i;
	char last_char = 0;

	struct uwsgi_router_memcached_conf *urmc = (struct uwsgi_router_memcached_conf *) ur->data2;

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

	struct uwsgi_buffer *ub_key = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urmc->key, urmc->key_len);
        if (!ub_key) return UWSGI_ROUTE_BREAK;

	int fd = uwsgi_connect(urmc->addr, 0, 1);
	if (fd < 0) { uwsgi_buffer_destroy(ub_key) ; goto end; }

        // wait for connection;
        int ret = uwsgi.wait_write_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
        if (ret <= 0) {
		uwsgi_buffer_destroy(ub_key) ;
		close(fd);
		goto end;
        }

	// build the request and send it
	char *cmd = uwsgi_concat3n("get ", 4, ub_key->buf, ub_key->pos, "\r\n", 2);
	if (uwsgi_write_true_nb(fd, cmd, 6+ub_key->pos, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT])) {
		uwsgi_buffer_destroy(ub_key);
		free(cmd);
		close(fd);
		goto end;
	}
	uwsgi_buffer_destroy(ub_key);
	free(cmd);

	// ok, start reading the response...
	// first we need to get a full line;
	size_t found = 0;
	size_t pos = 0;
	for(;;) {
		ssize_t len = read(fd, buf + pos, MEMCACHED_BUFSIZE - pos);
		if (len > 0) {
			pos += len;
			goto read;
		}
		if (len < 0) {
			if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait;
		}
		close(fd);
		goto end;
wait:
		ret = uwsgi.wait_read_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
		// when we have a chunk try to read the first line
		if (ret > 0) {
			len = read(fd, buf + pos, MEMCACHED_BUFSIZE - pos);
			if (len > 0) {
				pos += len;
				goto read;
			}
		}
		close(fd);
		goto end;
read:
		for(i=0;i<pos;i++) {
			if (last_char == '\r' && buf[i] == '\n') {
				found = i-1;
				break;
			}
			last_char = buf[i];
		}
		if (found) break;
	}

	// ok parse the first line
	size_t response_size = memcached_firstline_parse(buf, found);

	if (response_size == 0) {
		close(fd);
		goto end;
	}

	if (urmc->type_num == 1) {
		if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) { close(fd); goto end; }
		if (uwsgi_response_add_content_type(wsgi_req, urmc->content_type, urmc->content_type_len)) { close(fd); goto end; }
		if (uwsgi_response_add_content_length(wsgi_req, response_size)) { close(fd); goto end; }
	}
	size_t remains = pos-(found+2);
	if (remains >= response_size) {
		uwsgi_response_write_body_do(wsgi_req, buf+found+2, response_size);
		close(fd);
		goto end;
	}

	// send what we have
	if (uwsgi_response_write_body_do(wsgi_req, buf+found+2, remains)) {
		close(fd);
		goto end;
	}

	// and now start reading til the output is consumed
	response_size -= remains;
	while(response_size > 0) {
		ssize_t len = read(fd, buf, UMIN(MEMCACHED_BUFSIZE, response_size));
		if (len > 0) goto write;
		if (len < 0) {
                        if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) goto wait2;
                }
		goto error;
wait2:
		ret = uwsgi.wait_read_hook(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
		if (ret > 0) {
                        len = read(fd, buf, UMIN(MEMCACHED_BUFSIZE, response_size));
			if (len > 0) goto write;
		}
		goto error;
write:
		if (uwsgi_response_write_body_do(wsgi_req, buf, len)) {
			goto error;
        	}
		response_size -= len;
	}

	close(fd);
	return UWSGI_ROUTE_BREAK;

error:
	close(fd);
	
end:
	if (ur->custom)
        	return UWSGI_ROUTE_NEXT;

	return UWSGI_ROUTE_BREAK;
}