// destroy a peer
int uwsgi_cr_peer_del(struct corerouter_peer *peer) {
	// first of all check if we need to run a flush procedure
	if (peer->flush && !peer->is_flushing) {
		peer->is_flushing = 1;
		// on success, suspend the execution
		if (peer->flush(peer) > 0) return -1;
	}
	struct corerouter_peer *prev = peer->prev;
	struct corerouter_peer *next = peer->next;

	if (prev) {
		prev->next = peer->next;
	}

	if (next) {
		next->prev = peer->prev;
	}

	if (peer == peer->session->peers) {
		peer->session->peers = peer->next;
	}

	uwsgi_cr_peer_reset(peer);

	if (peer->in) {
		uwsgi_buffer_destroy(peer->in);
	}

	// main_peer bring the output buffer from backend peers
	if (peer->out && peer->out_need_free) {
		uwsgi_buffer_destroy(peer->out);
	}
	free(peer);
	return 0;
}
示例#2
0
文件: ssi.c 项目: Algy/uwsgi
static int uwsgi_routing_func_ssi(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){

	struct uwsgi_buffer *ub = NULL;

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

        struct uwsgi_buffer *ub_filename = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
        if (!ub_filename) goto end;

	struct uwsgi_buffer *ub_ssi = uwsgi_buffer_from_file(ub_filename->buf);
	uwsgi_buffer_destroy(ub_filename);
	if (!ub_ssi) goto end;

	ub = uwsgi_ssi_parse(wsgi_req, ub_ssi->buf, ub_ssi->pos);
	uwsgi_buffer_destroy(ub_ssi);
	if (!ub) goto end;

        if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto end;
        if (uwsgi_response_add_content_length(wsgi_req, ub->pos)) goto end;
        if (uwsgi_response_add_content_type(wsgi_req, "text/html", 9)) goto end;

        uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
	
end:
	if (ub) uwsgi_buffer_destroy(ub);
        return UWSGI_ROUTE_BREAK;
}
示例#3
0
//each protocol has its header generator
int uwsgi_response_add_header(struct wsgi_request *wsgi_req, char *key, uint16_t key_len, char *value, uint16_t value_len) {

	if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size || wsgi_req->write_errors) return -1;

	struct uwsgi_string_list *rh = uwsgi.remove_headers;
	while(rh) {
		if (!uwsgi_strnicmp(key, key_len, rh->value, rh->len)) {
			return 0;
		}
		rh = rh->next;
	}
	rh = wsgi_req->remove_headers;
	while(rh) {
		if (!uwsgi_strnicmp(key, key_len, rh->value, rh->len)) {
			return 0;
		}
		rh = rh->next;
	}

	if (!wsgi_req->headers) {
		wsgi_req->headers = uwsgi_buffer_new(uwsgi.page_size);
		wsgi_req->headers->limit = UMAX16;
	}

	struct uwsgi_buffer *hh = wsgi_req->socket->proto_add_header(wsgi_req, key, key_len, value, value_len);
	if (!hh) { wsgi_req->write_errors++ ; return -1;}
	if (uwsgi_buffer_append(wsgi_req->headers, hh->buf, hh->pos)) goto error;
	wsgi_req->header_cnt++;
	uwsgi_buffer_destroy(hh);
	return 0;
error:
	uwsgi_buffer_destroy(hh);
	wsgi_req->write_errors++;
	return -1;
}
示例#4
0
文件: ssi.c 项目: Algy/uwsgi
static int uwsgi_ssi_request(struct wsgi_request *wsgi_req) {
	struct uwsgi_buffer *ub = NULL;

	if (uwsgi_parse_vars(wsgi_req)) {
                return -1;
        }

	if (!wsgi_req->document_root_len || !wsgi_req->path_info_len) {
		uwsgi_log("[uwsgi-ssi] DOCUMENT_ROOT and PATH_INFO must be defined !!!\n");
		uwsgi_500(wsgi_req);
		return UWSGI_OK;
	}

	char *filename = uwsgi_concat3n(wsgi_req->document_root, wsgi_req->document_root_len, "/", 1, wsgi_req->path_info, wsgi_req->path_info_len);
	size_t filename_len = wsgi_req->document_root_len + 1 + wsgi_req->path_info_len;
	
	// we expand the path for future security implementations
	char *real_filename = uwsgi_expand_path(filename, filename_len, NULL);
	free(filename);
	if (!real_filename) {
		uwsgi_404(wsgi_req);
		return UWSGI_OK;
	}

	struct uwsgi_buffer *ub_ssi = uwsgi_buffer_from_file(real_filename);
	free(real_filename);
	if (!ub_ssi) {
		uwsgi_500(wsgi_req);
		return UWSGI_OK;
	}

	ub = uwsgi_ssi_parse(wsgi_req, ub_ssi->buf, ub_ssi->pos);
	uwsgi_buffer_destroy(ub_ssi);
	if (!ub) {
               	uwsgi_500(wsgi_req);
		return UWSGI_OK;
	}
	// prepare headers
       	if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) {
               	uwsgi_500(wsgi_req);
               	goto end;
       	}
       	// content_length
       	if (uwsgi_response_add_content_length(wsgi_req, ub->pos)) {
               	uwsgi_500(wsgi_req);
               	goto end;
       	}
       	// content_type
       	if (uwsgi_response_add_content_type(wsgi_req, "text/html", 9)) {
               	uwsgi_500(wsgi_req);
               	goto end;
       	}

	uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
end:
	if (ub) {
		uwsgi_buffer_destroy(ub);
	}
	return UWSGI_OK;
}
示例#5
0
文件: plugin.c 项目: Algy/uwsgi
// metricinc/metricdec/metricmul/metricdiv/metricset
static int uwsgi_routing_func_metricmath(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){

        struct uwsgi_router_metric_conf *urmc = (struct uwsgi_router_metric_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 = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urmc->name, urmc->name_len);
        if (!ub) return UWSGI_ROUTE_BREAK;

        struct uwsgi_buffer *ub_val = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urmc->value, urmc->value_len);
        if (!ub_val) {
               	uwsgi_buffer_destroy(ub);
               	return UWSGI_ROUTE_BREAK;
        }
	int64_t num = strtol(ub_val->buf, NULL, 10);
        uwsgi_buffer_destroy(ub_val);

        if (urmc->func(ub->buf, NULL, num)) {
                uwsgi_buffer_destroy(ub);
                return UWSGI_ROUTE_BREAK;
        }
        uwsgi_buffer_destroy(ub);
        return UWSGI_ROUTE_NEXT;
}
示例#6
0
// be tolerant on errors
static int uwsgi_routing_func_cache_store(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
	struct uwsgi_router_cache_conf *urcc = (struct uwsgi_router_cache_conf *) ur->data2;

	// overwrite previous run
	if (wsgi_req->cache_it) {
		uwsgi_buffer_destroy(wsgi_req->cache_it);
		wsgi_req->cache_it = NULL;		
	}

	if (wsgi_req->cache_it_to) {
		uwsgi_buffer_destroy(wsgi_req->cache_it_to);
		wsgi_req->cache_it_to = NULL;		
	}

	// build key and name
        char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
        uint16_t *subject_len = (uint16_t *)  (((char *)(wsgi_req))+ur->subject_len);

        wsgi_req->cache_it = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urcc->key, urcc->key_len);
        if (!wsgi_req->cache_it) return UWSGI_ROUTE_NEXT;
	
	if (urcc->name) {
		wsgi_req->cache_it_to = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urcc->name, urcc->name_len);
		if (!wsgi_req->cache_it_to) {
			uwsgi_buffer_destroy(wsgi_req->cache_it);
			wsgi_req->cache_it = NULL;
		}
	}

	wsgi_req->cache_it_expires = urcc->expires;

	return UWSGI_ROUTE_NEXT;
	
}
示例#7
0
// destroy a peer
void uwsgi_cr_peer_del(struct corerouter_peer *peer) {
	struct corerouter_peer *prev = peer->prev;
	struct corerouter_peer *next = peer->next;

	if (prev) {
		prev->next = peer->next;
	}

	if (next) {
		next->prev = peer->prev;
	}

	if (peer == peer->session->peers) {
		peer->session->peers = peer->next;
	}

	uwsgi_cr_peer_reset(peer);

	if (peer->in) {
		uwsgi_buffer_destroy(peer->in);
	}

	// main_peer bring the output buffer from backend peers
	if (peer->out && peer->out_need_free) {
		uwsgi_buffer_destroy(peer->out);
	}
	free(peer);
}
示例#8
0
static int uwsgi_routing_func_rewrite(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {

	char *tmp_qs = NULL;

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

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

	uint16_t path_info_len = ub->pos;
	uint16_t query_string_len = 0;
	
	char *query_string = memchr(ub->buf, '?', ub->pos);
	if (query_string) {
		path_info_len = query_string - ub->buf;
		query_string++;
		query_string_len = ub->pos - (path_info_len + 1);
		if (wsgi_req->query_string_len > 0) {
			tmp_qs = uwsgi_concat4n(query_string, query_string_len, "&", 1, wsgi_req->query_string, wsgi_req->query_string_len, "", 0);
			query_string = tmp_qs;
			query_string_len = strlen(query_string);
		}	
	}
	// over engineering, could be required in the future...
	else {
		if (wsgi_req->query_string_len > 0) {
			query_string = wsgi_req->query_string;
			query_string_len = wsgi_req->query_string_len;
		}
		else {
			query_string = "";
		}
	}

	char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, ub->buf, path_info_len);
        if (!ptr) goto clear;

	// set new path_info
	wsgi_req->path_info = ptr;
	wsgi_req->path_info_len = path_info_len;

	ptr = uwsgi_req_append(wsgi_req, "QUERY_STRING", 12, query_string, query_string_len);
	if (!ptr) goto clear;

	// set new query_string
	wsgi_req->query_string = ptr;
	wsgi_req->query_string_len = query_string_len;

	uwsgi_buffer_destroy(ub);
	if (tmp_qs) free(tmp_qs);
	if (ur->custom)
		return UWSGI_ROUTE_CONTINUE;
	return UWSGI_ROUTE_NEXT;

clear:
	uwsgi_buffer_destroy(ub);
	if (tmp_qs) free(tmp_qs);
	return UWSGI_ROUTE_BREAK;
}
示例#9
0
static int uwsgi_routing_func_cache(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){

	struct uwsgi_router_cache_conf *urcc = (struct uwsgi_router_cache_conf *) ur->data2;

	if (!uwsgi.cache_max_items) return UWSGI_ROUTE_NEXT;

	char *c_k = NULL;
	uint16_t c_k_len = 0;
	struct uwsgi_buffer *ub = NULL;
	int k_need_free = 0;

	if (urcc->key) {
		char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
        	uint16_t *subject_len = (uint16_t *)  (((char *)(wsgi_req))+ur->subject_len);

        	c_k = uwsgi_regexp_apply_ovec(*subject, *subject_len, urcc->key, urcc->key_len, ur->ovector, ur->ovn);
		c_k_len = strlen(c_k);
		k_need_free = 1;
	}
	else {
		char **key = (char **) (((char *) wsgi_req) + urcc->var_offset);
        	uint16_t *keylen = (uint16_t *) (((char *) wsgi_req) + urcc->var_offset_len);
		c_k = *key;
		c_k_len = *keylen;
	}

	uint64_t valsize = 0;
	char *value = uwsgi_cache_get(c_k, c_k_len, &valsize);
	if (value) {
		ub = uwsgi_buffer_new(uwsgi.page_size);
		if (urcc->type_num == 1) {
			wsgi_req->status = 200;
			if (uwsgi_buffer_append(ub, "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Type: ", 50)) goto error;
			if (uwsgi_buffer_append(ub, urcc->content_type, urcc->content_type_len)) goto error;
			if (uwsgi_buffer_append(ub, "\r\nContent-Length: ", 18 )) goto error;
			if (uwsgi_buffer_num64(ub, valsize)) goto error;
			if (uwsgi_buffer_append(ub, "\r\n\r\n", 4 )) goto error;
			wsgi_req->headers_size += wsgi_req->socket->proto_write_header(wsgi_req, ub->buf, ub->pos);
			uwsgi_buffer_destroy(ub);
			wsgi_req->header_cnt = 3;		
		}
		// body only
		wsgi_req->response_size += wsgi_req->socket->proto_write(wsgi_req, value, valsize);
		if (k_need_free) free(c_k);
		if (ur->custom)
			return UWSGI_ROUTE_NEXT;
		return UWSGI_ROUTE_BREAK;
	}
	if (k_need_free) free(c_k);
	
	return UWSGI_ROUTE_NEXT;
error:
	uwsgi_buffer_destroy(ub);
	if (k_need_free) free(c_k);
	return UWSGI_ROUTE_BREAK;
}
示例#10
0
文件: exceptions.c 项目: burhan/uwsgi
struct uwsgi_buffer *uwsgi_exception_handler_object(struct wsgi_request *wsgi_req) {
	struct uwsgi_buffer *ub = uwsgi_buffer_new(4096);
	if (uwsgi_buffer_append_keyval(ub, "vars", 4, wsgi_req->buffer,wsgi_req->uh->pktsize)) goto error;
	if (uwsgi.p[wsgi_req->uh->modifier1]->backtrace) {
                struct uwsgi_buffer *bt = uwsgi.p[wsgi_req->uh->modifier1]->backtrace(wsgi_req);
		if (bt) {
			if (uwsgi_buffer_append_keyval(ub, "backtrace", 9, bt->buf, bt->pos)) {
				uwsgi_buffer_destroy(bt);
				goto error;
			} 
			uwsgi_buffer_destroy(bt);
		}
	}
	
	if (uwsgi.p[wsgi_req->uh->modifier1]->exception_class) {
		struct uwsgi_buffer *ec = uwsgi.p[wsgi_req->uh->modifier1]->exception_class(wsgi_req);
		if (ec) {
			if (uwsgi_buffer_append_keyval(ub, "class", 5, ec->buf, ec->pos)) {
				uwsgi_buffer_destroy(ec);
				goto error;
			}
			uwsgi_buffer_destroy(ec);
		}
	}

	if (uwsgi.p[wsgi_req->uh->modifier1]->exception_msg) {
                struct uwsgi_buffer *em = uwsgi.p[wsgi_req->uh->modifier1]->exception_msg(wsgi_req);
                if (em) {
                        if (uwsgi_buffer_append_keyval(ub, "msg", 3, em->buf, em->pos)) {
                                uwsgi_buffer_destroy(em);
                                goto error;
                        }
                        uwsgi_buffer_destroy(em);
                }
        }

	if (uwsgi.p[wsgi_req->uh->modifier1]->exception_repr) {
                struct uwsgi_buffer *er = uwsgi.p[wsgi_req->uh->modifier1]->exception_repr(wsgi_req);
                if (er) {
                        if (uwsgi_buffer_append_keyval(ub, "repr", 4, er->buf, er->pos)) {
                                uwsgi_buffer_destroy(er);
                                goto error;
                        }
                        uwsgi_buffer_destroy(er);
                }
        }

	if (uwsgi_buffer_append_keynum(ub, "unix", 4, uwsgi_now())) goto error;
	if (uwsgi_buffer_append_keynum(ub, "wid", 3, uwsgi.mywid)) goto error;
	if (uwsgi_buffer_append_keynum(ub, "pid", 3, uwsgi.mypid)) goto error;
	if (uwsgi_buffer_append_keynum(ub, "core", 4, wsgi_req->async_id)) goto error;
	if (uwsgi_buffer_append_keyval(ub, "node", 4, uwsgi.hostname, uwsgi.hostname_len)) goto error;

	return ub;
	
error:
	uwsgi_buffer_destroy(ub);
	return NULL;
}
示例#11
0
文件: writer.c 项目: JuanS/uwsgi
// status could be NNN or NNN message
int uwsgi_response_prepare_headers(struct wsgi_request *wsgi_req, char *status, uint16_t status_len) {

	if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size || status_len < 3 || wsgi_req->write_errors) return -1;

	if (!wsgi_req->headers) {
		wsgi_req->headers = uwsgi_buffer_new(uwsgi.page_size);
		wsgi_req->headers->limit = UMAX16;
	}

	// reset the buffer (could be useful for rollbacks...)
	wsgi_req->headers->pos = 0;
	// reset headers count
	wsgi_req->header_cnt = 0;
	struct uwsgi_buffer *hh = NULL;
	wsgi_req->status = uwsgi_str3_num(status);
#ifdef UWSGI_ROUTING
	// apply error routes
	if (uwsgi_apply_error_routes(wsgi_req) == UWSGI_ROUTE_BREAK) {
		// from now on ignore write body requests...
		wsgi_req->ignore_body = 1;
		return -1;
	}
	wsgi_req->is_error_routing = 0;
#endif
	if (status_len <= 4) {
		char *new_sc = NULL;
		size_t new_sc_len = 0;
		uint16_t sc_len = 0;
		const char *sc = uwsgi_http_status_msg(status, &sc_len);
		if (sc) {
			new_sc = uwsgi_concat3n(status, 3, " ", 1, (char *)sc, sc_len);
			new_sc_len = 4+sc_len;
		}
		else {	
			new_sc = uwsgi_concat2n(status, 3, " Unknown", 8);
			new_sc_len = 11;
		}
		hh = wsgi_req->socket->proto_prepare_headers(wsgi_req, new_sc, new_sc_len);
		free(new_sc);
	}
	else {
		hh = wsgi_req->socket->proto_prepare_headers(wsgi_req, status, status_len);
	}
	if (!hh) {wsgi_req->write_errors++; return -1;}
        if (uwsgi_buffer_append(wsgi_req->headers, hh->buf, hh->pos)) goto error;
        uwsgi_buffer_destroy(hh);
        return 0;
error:
        uwsgi_buffer_destroy(hh);
	wsgi_req->write_errors++;
	return -1;
}
示例#12
0
文件: expires.c 项目: Algy/uwsgi
static int uwsgi_routing_func_expires(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){

        struct uwsgi_router_expires_conf *urec = (struct uwsgi_router_expires_conf *) ur->data2;

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

	uint64_t expires = 0;

	if (urec->filename) {

        	struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urec->filename, urec->filename_len);
        	if (!ub) return UWSGI_ROUTE_BREAK;

		struct stat st;
		if (stat(ub->buf, &st)) {
			uwsgi_buffer_destroy(ub);
			return UWSGI_ROUTE_BREAK;
		}

		expires = st.st_mtime;
		uwsgi_buffer_destroy(ub);

	}
	else if (urec->unixt) {
		struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urec->unixt, urec->unixt_len);
                if (!ub) return UWSGI_ROUTE_BREAK;

		expires = strtoul(ub->buf, NULL, 10);
		uwsgi_buffer_destroy(ub);
	}

	if (urec->value) {
		struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urec->value, urec->value_len);
		if (!ub) return UWSGI_ROUTE_BREAK;

		expires += atoi(ub->buf);
        	uwsgi_buffer_destroy(ub);
	}

	char expires_str[7 + 2 + 31];
        int len = uwsgi_http_date((time_t) expires, expires_str + 9);
        if (!len) return UWSGI_ROUTE_BREAK;

	memcpy(expires_str, "Expires: ", 9);

	uwsgi_additional_header_add(wsgi_req, expires_str, 9 + len);

        return UWSGI_ROUTE_NEXT;
}
示例#13
0
void hr_session_ssl_close(struct corerouter_session *cs) {
	hr_session_close(cs);
	struct http_session *hr = (struct http_session *) cs;
	if (hr->ssl_client_dn) {
                OPENSSL_free(hr->ssl_client_dn);
        }

        if (hr->ssl_cc) {
                free(hr->ssl_cc);
        }

        if (hr->ssl_bio) {
                BIO_free(hr->ssl_bio);
        }

        if (hr->ssl_client_cert) {
                X509_free(hr->ssl_client_cert);
        }

#ifdef UWSGI_SPDY
	if (hr->spdy_ping) {
		uwsgi_buffer_destroy(hr->spdy_ping);
	}
	if (hr->spdy) {
		deflateEnd(&hr->spdy_z_in);
		deflateEnd(&hr->spdy_z_out);
	}
#endif

	// clear the errors (otherwise they could be propagated)
	hr_ssl_clear_errors();
        SSL_free(hr->ssl);
}
示例#14
0
文件: ssi.c 项目: Algy/uwsgi
// cache command (uWSGI specific)
static struct uwsgi_buffer *ssi_cmd_cache(struct wsgi_request *wsgi_req, struct uwsgi_ssi_arg *argv, int argc) {
        size_t var_len = 0;
        char *var = uwsgi_ssi_get_arg(argv, argc, "key", 3, &var_len);
        if (!var || var_len == 0) return NULL;

	size_t cache_len = 0;
	char *cache = uwsgi_ssi_get_arg(argv, argc, "name", 4, &cache_len);
        char *cache_name = NULL;

	if (cache && cache_len) {
		cache_name = uwsgi_concat2n(cache, cache_len, "", 0);
	}

	uint64_t rlen = 0;
	char *value = uwsgi_cache_magic_get(var, var_len, &rlen, NULL, cache_name);
	if (cache_name) free(cache_name);
	struct uwsgi_buffer *ub = NULL;
	if (value) {
        	ub = uwsgi_buffer_new(rlen);
		if (uwsgi_buffer_append(ub, value, rlen)) {
			free(value);
			uwsgi_buffer_destroy(ub);
			return NULL;
		}
		free(value);
	}

        return ub;
}
示例#15
0
static int uwsgi_ssh_routing(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
	// ssh://username[:password]@127.0.0.1:2222/tmp/foo.txt,username[:password]@127.0.0.1:2222/tmp/foobis.txt

	char *remote_url = NULL;

	char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
	uint16_t *subject_len = (uint16_t *)  (((char *)(wsgi_req))+ur->subject_len);
	struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
	if (!ub) {
		uwsgi_error("uwsgi_ssh_routing()/uwsgi_routing_translate()");
		remote_url = ur->data;
	} else {
		remote_url = ub->buf;
	}

	remote_url = uwsgi_concat2(remote_url, ",");
	char *remote_pointer = remote_url;
	char *comma = NULL;
	struct uwsgi_ssh_mountpoint *usm = uwsgi_calloc(sizeof(struct uwsgi_ssh_mountpoint));
	int return_status = -1;

	while ((comma = strchr(remote_url, ',')) != NULL) {
		*comma = 0;

		if (uwsgi_ssh_url_parser(remote_url, &usm)) {
			uwsgi_log("[SSH] skipping malformed route %s\n", remote_url);
			return_status = 500;
			continue;
		}

		if (!(return_status = uwsgi_ssh_request_file(
					wsgi_req,
					usm->path,
					usm
		)))
		{
			goto end;
		} else {
			uwsgi_log("[SSH] route %s to %s returned %d. Engaging fail-over mechanism (if any)...\n",
				usm->remote, usm->path, return_status);
		}

		remote_url = comma + 1;
	}

	switch (return_status) {
		case 404:
			uwsgi_404(wsgi_req);
			break;

		case 500:
		default:
			uwsgi_500(wsgi_req);
	}

end:
	free(remote_pointer);
	uwsgi_buffer_destroy(ub);
	return UWSGI_OK;
}
示例#16
0
static int uwsgi_routing_func_cache(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){

	struct uwsgi_router_cache_conf *urcc = (struct uwsgi_router_cache_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 = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urcc->key, urcc->key_len);
        if (!ub) return UWSGI_ROUTE_BREAK;

	uint64_t valsize = 0;
	char *value = uwsgi_cache_magic_get(ub->buf, ub->pos, &valsize, urcc->name);
	uwsgi_buffer_destroy(ub);
	if (value) {
		if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto error;
		if (uwsgi_response_add_content_type(wsgi_req, urcc->content_type, urcc->content_type_len)) goto error;
		if (uwsgi_response_add_content_length(wsgi_req, valsize)) goto error;
		uwsgi_response_write_body_do(wsgi_req, value, valsize);
		free(value);
		if (ur->custom)
			return UWSGI_ROUTE_NEXT;
		return UWSGI_ROUTE_BREAK;
	}
	
	return UWSGI_ROUTE_NEXT;
error:
	free(value);
	return UWSGI_ROUTE_BREAK;
}
示例#17
0
文件: https.c 项目: burhan/uwsgi
void hr_session_ssl_close(struct corerouter_session *cs) {
	hr_session_close(cs);
	struct http_session *hr = (struct http_session *) cs;
	if (hr->ssl_client_dn) {
                OPENSSL_free(hr->ssl_client_dn);
        }

        if (hr->ssl_cc) {
                free(hr->ssl_cc);
        }

        if (hr->ssl_bio) {
                BIO_free(hr->ssl_bio);
        }

        if (hr->ssl_client_cert) {
                X509_free(hr->ssl_client_cert);
        }

#ifdef UWSGI_SPDY
	if (hr->spdy_ping) {
		uwsgi_buffer_destroy(hr->spdy_ping);
	}
	if (hr->spdy) {
		deflateEnd(&hr->spdy_z_in);
		deflateEnd(&hr->spdy_z_out);
	}
#endif

        SSL_free(hr->ssl);
}
示例#18
0
static void stats_pusher_dogstatsd(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {

  if (!uspi->configured) {
    struct dogstatsd_node *sn = uwsgi_calloc(sizeof(struct dogstatsd_node));
    char *comma = strchr(uspi->arg, ',');
    if (comma) {
      sn->prefix = comma+1;
      sn->prefix_len = strlen(sn->prefix);
      *comma = 0;
    }
    else {
      sn->prefix = "uwsgi";
      sn->prefix_len = 5;
    }

    char *colon = strchr(uspi->arg, ':');
    if (!colon) {
      uwsgi_log("invalid dd address %s\n", uspi->arg);
      if (comma) *comma = ',';
      free(sn);
      return;
    }
    sn->addr_len = socket_to_in_addr(uspi->arg, colon, 0, &sn->addr.sa_in);

    sn->fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sn->fd < 0) {
      uwsgi_error("stats_pusher_dogstatsd()/socket()");
      if (comma) *comma = ',';
                        free(sn);
                        return;
    }
    uwsgi_socket_nb(sn->fd);
    if (comma) *comma = ',';
    uspi->data = sn;
    uspi->configured = 1;
  }

  // we use the same buffer for all of the packets
  struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
  struct uwsgi_metric *um = uwsgi.metrics;
  while(um) {
    uwsgi_rlock(uwsgi.metrics_lock);
    // ignore return value
    if (um->type == UWSGI_METRIC_GAUGE) {
      dogstatsd_send_metric(ub, uspi, um->name, um->name_len, *um->value, "|g");
    }
    else {
      dogstatsd_send_metric(ub, uspi, um->name, um->name_len, *um->value, "|c");
    }
    uwsgi_rwunlock(uwsgi.metrics_lock);
    if (um->reset_after_push){
      uwsgi_wlock(uwsgi.metrics_lock);
      *um->value = um->initial_value;
      uwsgi_rwunlock(uwsgi.metrics_lock);
    }
    um = um->next;
  }
  uwsgi_buffer_destroy(ub);
}
示例#19
0
文件: writer.c 项目: JuanS/uwsgi
//each protocol has its header generator
static int uwsgi_response_add_header_do(struct wsgi_request *wsgi_req, char *key, uint16_t key_len, char *value, uint16_t value_len) {
        if (!wsgi_req->headers) {
                wsgi_req->headers = uwsgi_buffer_new(uwsgi.page_size);
                wsgi_req->headers->limit = UMAX16;
        }

        struct uwsgi_buffer *hh = wsgi_req->socket->proto_add_header(wsgi_req, key, key_len, value, value_len);
        if (!hh) { wsgi_req->write_errors++ ; return -1;}
        if (uwsgi_buffer_append(wsgi_req->headers, hh->buf, hh->pos)) goto error;
        wsgi_req->header_cnt++;
        uwsgi_buffer_destroy(hh);
        return 0;
error:
        uwsgi_buffer_destroy(hh);
        wsgi_req->write_errors++;
        return -1;
}
示例#20
0
int uwsgi_routing_func_uwsgi_remote(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {

	struct uwsgi_header *uh = (struct uwsgi_header *) ur->data;
	char *addr = ur->data + sizeof(struct uwsgi_header);
	
	// mark a route request
        wsgi_req->status = -17;

	// append appid
	if (ur->data2_len > 0) {
		uwsgi_req_append(wsgi_req, "UWSGI_APPID", 11, ur->data2, ur->data2_len);
	}

	// ok now if have offload threads, directly use them
        if (wsgi_req->socket->can_offload) {
		struct uwsgi_buffer *ub = uwsgi_buffer_new(4 + wsgi_req->uh.pktsize);
		if (ub) {
			uh->pktsize = wsgi_req->uh.pktsize;
			if (uwsgi_buffer_append(ub, (char *) uh, 4)) goto bad;
			if (uwsgi_buffer_append(ub, wsgi_req->buffer, uh->pktsize)) goto bad;
                	if (!uwsgi_offload_request_net_do(wsgi_req, addr, ub)) {
                        	wsgi_req->status = -30;
                        	return UWSGI_ROUTE_BREAK;
                	}
bad:
			uwsgi_buffer_destroy(ub);
		}
        }


	int uwsgi_fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0);
	if (uwsgi_fd < 0) {
		uwsgi_log("unable to connect to host %s\n", addr);
		return UWSGI_ROUTE_NEXT;
	}

	int post_fd = wsgi_req->poll.fd;
	if (wsgi_req->async_post) {
		post_fd = fileno((FILE*)wsgi_req->async_post);
	}

	if (uwsgi_send_message(uwsgi_fd, uh->modifier1, uh->modifier2, wsgi_req->buffer, wsgi_req->uh.pktsize, post_fd, wsgi_req->post_cl, 0) < 0) {
		uwsgi_log("unable to send uwsgi request to host %s", addr);
		return UWSGI_ROUTE_NEXT;
	}

	ssize_t ret = uwsgi_pipe(uwsgi_fd, wsgi_req->poll.fd, 0);
	if (ret > 0) {
		wsgi_req->response_size += ret;
	}
	else {
		uwsgi_log("unable to manage uwsgi route response for %s\n", addr);
	}

	close(uwsgi_fd);
	return UWSGI_ROUTE_BREAK;

}
示例#21
0
文件: xslt.c 项目: AGoodId/uwsgi
static int uwsgi_routing_func_xslt(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){

        struct uwsgi_router_xslt_conf *urxc = (struct uwsgi_router_xslt_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_doc = NULL;
	struct uwsgi_buffer *ub_stylesheet = NULL;
	struct uwsgi_buffer *ub_params = NULL;
	struct uwsgi_buffer *ub_content_type = NULL;

	ub_doc = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->doc, urxc->doc_len);
	if (!ub_doc) goto end;
	ub_stylesheet = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->stylesheet, urxc->stylesheet_len);
	if (!ub_stylesheet) goto end;

	if (urxc->params) {
		ub_params = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->params, urxc->params_len);
		if (!ub_params) goto end;
	}

	if (urxc->content_type) {
		ub_content_type = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->content_type, urxc->content_type_len);
		if (!ub_content_type) goto end;
	}

	int rlen;
        char *output = uwsgi_xslt_apply( ub_doc->buf, ub_stylesheet->buf, ub_params ? ub_params->buf : NULL, &rlen);
	if (!output) goto end;

        if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto end;
        if (uwsgi_response_add_content_length(wsgi_req, rlen)) goto end;
        if (uwsgi_response_add_content_type(wsgi_req, urxc->content_type, urxc->content_type_len)) goto end;

        uwsgi_response_write_body_do(wsgi_req, output, rlen);
	xmlFree(output);

end:
	if (ub_doc) uwsgi_buffer_destroy(ub_doc);
	if (ub_stylesheet) uwsgi_buffer_destroy(ub_stylesheet);
	if (ub_params) uwsgi_buffer_destroy(ub_params);
	if (ub_content_type) uwsgi_buffer_destroy(ub_content_type);
        return UWSGI_ROUTE_BREAK;
}
示例#22
0
文件: websockets.c 项目: apoh/uwsgi
static int uwsgi_websocket_send_do(struct wsgi_request *wsgi_req, char *msg, size_t len) {
	struct uwsgi_buffer *ub = uwsgi_websocket_message(msg, len);
	if (!ub) return -1;

	ssize_t ret = uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
	uwsgi_buffer_destroy(ub);
	return ret;
	
}
示例#23
0
文件: rack_plugin.c 项目: Algy/uwsgi
static struct uwsgi_buffer *uwsgi_ruby_exception_msg(struct wsgi_request *wsgi_req) {
	VALUE err = rb_errinfo();
	VALUE e = rb_funcall(err, rb_intern("message"), 0, 0);
	struct uwsgi_buffer *ub = uwsgi_buffer_new(RSTRING_LEN(e));
	if (uwsgi_buffer_append(ub, RSTRING_PTR(e), RSTRING_LEN(e))) {
		uwsgi_buffer_destroy(ub);
		return NULL;
	}
	return ub;
}
示例#24
0
文件: rack_plugin.c 项目: Algy/uwsgi
static struct uwsgi_buffer *uwsgi_ruby_exception_class(struct wsgi_request *wsgi_req) {
	VALUE err = rb_errinfo();
        VALUE e = rb_class_name(rb_class_of(err));
        struct uwsgi_buffer *ub = uwsgi_buffer_new(RSTRING_LEN(e));
        if (uwsgi_buffer_append(ub, RSTRING_PTR(e), RSTRING_LEN(e))) {
                uwsgi_buffer_destroy(ub);
                return NULL;
        }
        return ub;
}
示例#25
0
// this is the function called by all request plugins to send chunks to the client
int uwsgi_response_write_body_do(struct wsgi_request *wsgi_req, char *buf, size_t len) {

	if (wsgi_req->write_errors) return -1;

	if (!wsgi_req->headers_sent) {
		int ret = uwsgi_response_write_headers_do(wsgi_req);
                if (ret == UWSGI_OK) goto sendbody;
                if (ret == UWSGI_AGAIN) return UWSGI_AGAIN;
		wsgi_req->write_errors++;
                return -1;
	}

sendbody:

	if (len == 0) return UWSGI_OK;

	for(;;) {
		int ret = wsgi_req->socket->proto_write(wsgi_req, buf, len);
		if (ret < 0) {
			if (!uwsgi.ignore_write_errors) {
				uwsgi_error("uwsgi_response_write_body_do()");
			}
			wsgi_req->write_errors++;
			return -1;
		}
		if (ret == UWSGI_OK) {
			break;
		}
		ret = uwsgi_wait_write_req(wsgi_req);			
		if (ret < 0) { wsgi_req->write_errors++; return -1;}
                if (ret == 0) {
                        uwsgi_log("uwsgi_response_write_body_do() TIMEOUT !!!\n");
                        wsgi_req->write_errors++;
                        return -1;
                }
	}

	wsgi_req->response_size += wsgi_req->write_pos;
	// reset for the next write
        wsgi_req->write_pos = 0;

	// now we need to check if the chunk must be stored
	if (wsgi_req->cache_it) {
		if (!wsgi_req->cached_response) {
			wsgi_req->cached_response = uwsgi_buffer_new(len);
		}
		// if we are unable to append the buffer, we just stop caching it
		if (uwsgi_buffer_append(wsgi_req->cached_response, buf, len)) {
			uwsgi_buffer_destroy(wsgi_req->cache_it);
			wsgi_req->cache_it = NULL;
		}
	}

	return UWSGI_OK;	
}
示例#26
0
static int uwsgi_routing_func_rpc_blob(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
        int ret = -1;
        // this is the list of args
        char *argv[UMAX8];
        // this is the size of each argument
        uint16_t argvs[UMAX8];
        // this is a placeholder for tmp uwsgi_buffers
        struct uwsgi_buffer *ubs[UMAX8];

        char **r_argv = (char **) ur->data2;
        uint16_t *r_argvs = (uint16_t *) ur->data3;

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

        uint64_t i;
        for(i=0;i<ur->custom;i++) {
                ubs[i] = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, r_argv[i], r_argvs[i]);
                if (!ubs[i]) goto end;
                argv[i] = ubs[i]->buf;
                argvs[i] = ubs[i]->pos;
        }

        // ok we now need to check it it is a local call or a remote one
        char *func = uwsgi_str(ur->data);
        char *remote = NULL;
        char *at = strchr(func, '@');
        if (at) {
                *at = 0;
                remote = at+1;
        }
        uint16_t size;
        char *response = uwsgi_do_rpc(remote, func, ur->custom, argv, argvs, &size);
        free(func);
        if (!response) goto end;

        ret = UWSGI_ROUTE_NEXT;

	// optimization
	if (!wsgi_req->headers_sent) {
        	if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) {free(response) ; goto end;}
        	if (uwsgi_response_add_connection_close(wsgi_req)) {free(response) ; goto end;}
	}
        uwsgi_response_write_body_do(wsgi_req, response, size);
        free(response);

end:
        for(i=0;i<ur->custom;i++) {
                if (ubs[i] != NULL) {
                        uwsgi_buffer_destroy(ubs[i]);
                }
        }
        return ret;
}
示例#27
0
// status could be NNN or NNN message
int uwsgi_response_prepare_headers(struct wsgi_request *wsgi_req, char *status, uint16_t status_len) {

	if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size || status_len < 3 || wsgi_req->write_errors) return -1;

	if (!wsgi_req->headers) {
		wsgi_req->headers = uwsgi_buffer_new(uwsgi.page_size);
		wsgi_req->headers->limit = UMAX16;
	}

	// reset the buffer (could be useful for rollbacks...)
	wsgi_req->headers->pos = 0;
	struct uwsgi_buffer *hh = NULL;
	if (status_len <= 4) {
		char *new_sc = NULL;
		size_t new_sc_len = 0;
		uint16_t sc_len = 0;
		const char *sc = uwsgi_http_status_msg(status, &sc_len);
		if (sc) {
			new_sc = uwsgi_concat3n(status, 3, " ", 1, (char *)sc, sc_len);
			new_sc_len = 4+sc_len;
		}
		else {	
			new_sc = uwsgi_concat2n(status, 3, " Unknown", 8);
			new_sc_len = 11;
		}
		hh = wsgi_req->socket->proto_prepare_headers(wsgi_req, new_sc, new_sc_len);
		free(new_sc);
	}
	else {
		hh = wsgi_req->socket->proto_prepare_headers(wsgi_req, status, status_len);
	}
	if (!hh) {wsgi_req->write_errors++; return -1;}
        if (uwsgi_buffer_append(wsgi_req->headers, hh->buf, hh->pos)) goto error;
        uwsgi_buffer_destroy(hh);
	wsgi_req->status = uwsgi_str3_num(status);
        return 0;
error:
        uwsgi_buffer_destroy(hh);
	wsgi_req->write_errors++;
	return -1;
}
示例#28
0
int uwsgi_routing_func_static(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {

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

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

	uwsgi_file_serve(wsgi_req, ub->buf, ub->pos, NULL, 0, 1);
	uwsgi_buffer_destroy(ub);
	return UWSGI_ROUTE_BREAK;
}
示例#29
0
文件: rack_plugin.c 项目: Algy/uwsgi
static struct uwsgi_buffer *uwsgi_ruby_exception_repr(struct wsgi_request *wsgi_req) {
	struct uwsgi_buffer *ub_class = uwsgi_ruby_exception_class(wsgi_req);
	if (!ub_class) return NULL;

	struct uwsgi_buffer *ub_msg = uwsgi_ruby_exception_msg(wsgi_req);
	if (!ub_msg) {
		uwsgi_buffer_destroy(ub_class);
		return NULL;
	}

	struct uwsgi_buffer *ub = uwsgi_buffer_new(ub_class->pos + 3 + ub_msg->pos);
	if (uwsgi_buffer_append(ub, ub_msg->buf, ub_msg->pos)) goto error;
	if (uwsgi_buffer_append(ub, " (", 2)) goto error;
	if (uwsgi_buffer_append(ub, ub_class->buf, ub_class->pos)) goto error;
	if (uwsgi_buffer_append(ub, ")", 1)) goto error;

	uwsgi_buffer_destroy(ub_class);
	uwsgi_buffer_destroy(ub_msg);

	return ub;


error:
	uwsgi_buffer_destroy(ub_class);
	uwsgi_buffer_destroy(ub_msg);
	uwsgi_buffer_destroy(ub);
	return NULL;

}
示例#30
0
文件: ssi.c 项目: Algy/uwsgi
// printenv command
static struct uwsgi_buffer *ssi_cmd_printenv(struct wsgi_request *wsgi_req, struct uwsgi_ssi_arg *argv, int argc) {
        struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
	int i;
	for (i = 0; i < wsgi_req->var_cnt; i += 2) {
        	if (uwsgi_buffer_append(ub, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len)) goto error;
		if (uwsgi_buffer_append(ub, "=", 1)) goto error;
        	if (uwsgi_buffer_append(ub, wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len)) goto error;
		if (uwsgi_buffer_append(ub, "\n", 1)) goto error;
	}

        return ub;
error:
	uwsgi_buffer_destroy(ub);
	return NULL;
};