예제 #1
0
static void mainvr_connection_upgrade(liVRequest *vr, liStream *backend_drain, liStream *backend_source) {
	liConnection* con = li_connection_from_vrequest(vr);
	LI_FORCE_ASSERT(NULL != con);

	if (con->response_headers_sent || NULL != con->out.source) {
		li_connection_error(con);
		return;
	}
	if (CORE_OPTION(LI_CORE_OPTION_DEBUG_REQUEST_HANDLING).boolean) {
		VR_DEBUG(vr, "%s", "connection upgrade: write response headers");
	}
	con->response_headers_sent = TRUE;
	con->info.keep_alive = FALSE;
	li_response_send_headers(vr, con->out.out, NULL, TRUE);
	con->state = LI_CON_STATE_UPGRADED;
	vr->response.transfer_encoding = 0;
	li_connection_update_io_wait(con);

	li_stream_disconnect_dest(&con->in);
	con->in.out->is_closed = FALSE;

	li_stream_connect(&con->in, backend_drain);
	li_stream_connect(backend_source, &con->out);

	li_vrequest_reset(con->mainvr, TRUE);

	if (NULL != con->in.source) {
		li_chunkqueue_steal_all(con->out.out, backend_drain->out);
	}
	con->info.out_queue_length = con->out.out->length;

	li_stream_notify(&con->out);
	li_stream_notify(&con->in);
}
예제 #2
0
static liHandlerResult openssl_setenv(liVRequest *vr, gpointer param, gpointer *context) {
	liConnection *con;
	openssl_connection_ctx *conctx;
	SSL *ssl;
	X509 *x0=NULL, *x1=NULL;
	guint params = GPOINTER_TO_UINT(param);

	UNUSED(context);

	if (!(con = li_connection_from_vrequest(vr))
		|| !(con->srv_sock && con->srv_sock->new_cb == openssl_con_new)
		|| !(conctx = con->con_sock.data)
		|| !(ssl = li_openssl_filter_ssl(conctx->ssl_filter)))
		return LI_HANDLER_GO_ON;

	if ((params & SE_CLIENT) && (x1 || (x1 = SSL_get_peer_certificate(ssl))))
		openssl_setenv_X509_add_entries(vr, x1, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
	if ((params & SE_CLIENT_CERT) && (x1 || (x1 = SSL_get_peer_certificate(ssl))))
		openssl_setenv_X509_add_PEM(vr, x1, CONST_STR_LEN("SSL_CLIENT_CERT"));
	if ((params & SE_SERVER) && (x0 || (x0 = SSL_get_certificate(ssl))))
		openssl_setenv_X509_add_entries(vr, x0, CONST_STR_LEN("SSL_SERVER_S_DN_"));
	if ((params & SE_SERVER_CERT) && (x0 || (x0 = SSL_get_certificate(ssl))))
		openssl_setenv_X509_add_PEM(vr, x0, CONST_STR_LEN("SSL_SERVER_CERT"));

	/* only peer increases ref count */
	if (x1) X509_free(x1);

	return LI_HANDLER_GO_ON;
}
예제 #3
0
static liThrottleState* mainvr_throttle_in(liVRequest *vr) {
	liConnection* con = li_connection_from_vrequest(vr);
	LI_FORCE_ASSERT(NULL != con);

	return con->con_sock.callbacks->throttle_in(con);
}
예제 #4
0
static void mainvr_handle_response_error(liVRequest *vr) {
	liConnection* con = li_connection_from_vrequest(vr);
	LI_FORCE_ASSERT(NULL != con);

	li_connection_error(con);
}
예제 #5
0
static GString *al_format_log(liVRequest *vr, al_data *ald, GArray *format) {
	GString *str = g_string_sized_new(255);
	liResponse *resp = &vr->response;
	liRequest *req = &vr->request;
	liPhysical *phys = &vr->physical;

	for (guint i = 0; i < format->len; i++) {
		GString *tmp_gstr2 = NULL;
		gchar *tmp_str = NULL;
		guint len = 0;

		al_format_entry *e = &g_array_index(format, al_format_entry, i);
		if (e->type == AL_ENTRY_FORMAT) {
			switch (e->format.type) {
			case AL_FORMAT_PERCENT:
				g_string_append_c(str, '%');
				break;
			case AL_FORMAT_REMOTE_ADDR:
				g_string_append_len(str, GSTR_LEN(vr->coninfo->remote_addr_str));
				break;
			case AL_FORMAT_LOCAL_ADDR:
				g_string_append_len(str, GSTR_LEN(vr->coninfo->local_addr_str));
				break;
			case AL_FORMAT_BYTES_RESPONSE:
				li_string_append_int(str, vr->vr_out->bytes_out);
				break;
			case AL_FORMAT_BYTES_RESPONSE_CLF:
				if (vr->vr_out->bytes_out)
					li_string_append_int(str, vr->vr_out->bytes_out);
				else
					g_string_append_c(str, '-');
				break;
			case AL_FORMAT_DURATION_MICROSECONDS:
				li_string_append_int(str, (CUR_TS(vr->wrk) - vr->ts_started) * 1000 * 1000);
				break;
			case AL_FORMAT_ENV:
				tmp_gstr2 = li_environment_get(&vr->env, GSTR_LEN(e->key));
				if (tmp_gstr2)
					al_append_escaped(str, tmp_gstr2);
				else
					g_string_append_c(str, '-');
				break;
			case AL_FORMAT_FILENAME:
				if (phys->path->len)
					g_string_append_len(str, GSTR_LEN(phys->path));
				else
					g_string_append_c(str, '-');
				break;
			case AL_FORMAT_REQUEST_HEADER:
				li_http_header_get_all(vr->wrk->tmp_str, req->headers, GSTR_LEN(e->key));
				if (vr->wrk->tmp_str->len)
					al_append_escaped(str, vr->wrk->tmp_str);
				else
					g_string_append_c(str, '-');
				break;
			case AL_FORMAT_METHOD:
				g_string_append_len(str, GSTR_LEN(req->http_method_str));
				break;
			case AL_FORMAT_RESPONSE_HEADER:
				li_http_header_get_all(vr->wrk->tmp_str, resp->headers, GSTR_LEN(e->key));
				if (vr->wrk->tmp_str->len)
					al_append_escaped(str, vr->wrk->tmp_str);
				else
					g_string_append_c(str, '-');
				break;
			case AL_FORMAT_LOCAL_PORT:
				switch (vr->coninfo->local_addr.addr->plain.sa_family) {
				case AF_INET: li_string_append_int(str, ntohs(vr->coninfo->local_addr.addr->ipv4.sin_port)); break;
				#ifdef HAVE_IPV6
				case AF_INET6: li_string_append_int(str, ntohs(vr->coninfo->local_addr.addr->ipv6.sin6_port)); break;
				#endif
				default: g_string_append_c(str, '-'); break;
				}
				break;
			case AL_FORMAT_QUERY_STRING:
				if (req->uri.query->len)
					al_append_escaped(str, req->uri.query);
				else
					g_string_append_c(str, '-');
				break;
			case AL_FORMAT_FIRST_LINE:
				g_string_append_len(str, GSTR_LEN(req->http_method_str));
				g_string_append_c(str, ' ');
				al_append_escaped(str, req->uri.raw_orig_path);
				g_string_append_c(str, ' ');
				tmp_str = li_http_version_string(req->http_version, &len);
				g_string_append_len(str, tmp_str, len);
				break;
			case AL_FORMAT_STATUS_CODE:
				li_string_append_int(str, resp->http_status);
				break;
			case AL_FORMAT_TIME:
				/* todo: implement format string */
				tmp_gstr2 = li_worker_current_timestamp(vr->wrk, LI_LOCALTIME, ald->ts_ndx);
				g_string_append_len(str, GSTR_LEN(tmp_gstr2));
				break;
			case AL_FORMAT_DURATION_SECONDS:
				li_string_append_int(str, CUR_TS(vr->wrk) - vr->ts_started);
				break;
			case AL_FORMAT_AUTHED_USER:
				tmp_gstr2 = li_environment_get(&vr->env, CONST_STR_LEN("REMOTE_USER"));
				if (tmp_gstr2)
					g_string_append_len(str, GSTR_LEN(tmp_gstr2));
				else
					g_string_append_c(str, '-');
				break;
			case AL_FORMAT_PATH:
				g_string_append_len(str, GSTR_LEN(req->uri.path));
				break;
			case AL_FORMAT_SERVER_NAME:
				if (CORE_OPTIONPTR(LI_CORE_OPTION_SERVER_NAME).string)
					g_string_append_len(str, GSTR_LEN(CORE_OPTIONPTR(LI_CORE_OPTION_SERVER_NAME).string));
				else
					g_string_append_len(str, GSTR_LEN(req->uri.host));
				break;
			case AL_FORMAT_HOSTNAME:
				if (req->uri.host->len)
					g_string_append_len(str, GSTR_LEN(req->uri.host));
				else
					g_string_append_c(str, '-');
				break;
			case AL_FORMAT_CONNECTION_STATUS: {
					/* was request completed? */
					liConnection *con = li_connection_from_vrequest(vr); /* try to get a connection object */

					if (con && (con->in->is_closed && con->raw_out->is_closed && 0 == con->raw_out->length)) {
						g_string_append_c(str, 'X');
					} else {
						g_string_append_c(str, vr->coninfo->keep_alive ? '+' : '-');
					}
				}
				break;
			case AL_FORMAT_BYTES_IN:
				li_string_append_int(str, vr->coninfo->stats.bytes_in);
				break;
			case AL_FORMAT_BYTES_OUT:
				li_string_append_int(str, vr->coninfo->stats.bytes_out);
				break;
			default:
				/* not implemented:
				{ 'C', FALSE, AL_FORMAT_COOKIE }
				{ 't', FALSE, AL_FORMAT_TIME }, (partially implemented)
				*/
				g_string_append_c(str, '?');
				break;
			}
		} else {
			/* append normal string */
			g_string_append_len(str, GSTR_LEN(e->key));
		}
	}

	return str;
}
예제 #6
0
static liThrottleState* mainvr_throttle_out(liVRequest *vr) {
	liConnection* con = li_connection_from_vrequest(vr);
	assert(NULL != con);

	return con->con_sock.callbacks->throttle_out(con);
}