static apr_status_t set_resource_limits(request_rec *r,
                                        apr_procattr_t *procattr)
{
#if defined(RLIMIT_CPU)  || defined(RLIMIT_NPROC) || \
    defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined (RLIMIT_AS)
    core_dir_config *conf =
        (core_dir_config *)ap_get_module_config(r->per_dir_config,
                                                &core_module);
    apr_status_t rv;

#ifdef RLIMIT_CPU
    rv = apr_procattr_limit_set(procattr, APR_LIMIT_CPU, conf->limit_cpu);
    ap_assert(rv == APR_SUCCESS); /* otherwise, we're out of sync with APR */
#endif
#if defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_AS)
    rv = apr_procattr_limit_set(procattr, APR_LIMIT_MEM, conf->limit_mem);
    ap_assert(rv == APR_SUCCESS); /* otherwise, we're out of sync with APR */
#endif
#ifdef RLIMIT_NPROC
    rv = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, conf->limit_nproc);
    ap_assert(rv == APR_SUCCESS); /* otherwise, we're out of sync with APR */
#endif

#endif /* if at least one limit defined */

    return APR_SUCCESS;
}
Exemplo n.º 2
0
h2_task *h2_task_create(conn_rec *slave, int stream_id,
                        const h2_request *req, h2_mplx *m,
                        h2_bucket_beam *input, 
                        apr_interval_time_t timeout,
                        apr_size_t output_max_mem)
{
    apr_pool_t *pool;
    h2_task *task;
    
    ap_assert(slave);
    ap_assert(req);

    apr_pool_create(&pool, slave->pool);
    task = apr_pcalloc(pool, sizeof(h2_task));
    if (task == NULL) {
        return NULL;
    }
    task->id          = "000";
    task->stream_id   = stream_id;
    task->c           = slave;
    task->mplx        = m;
    task->pool        = pool;
    task->request     = req;
    task->timeout     = timeout;
    task->input.beam  = input;
    task->output.max_buffer = output_max_mem;

    return task;
}
Exemplo n.º 3
0
static void watch_callback(AvahiWatch *w, int fd, AvahiWatchEvent event, void *userdata) {
    char c;
    ssize_t l;
    struct runtime_data *r = userdata;

    ap_assert(w);
    ap_assert(fd == sigterm_pipe_fds[0]);
    ap_assert(event == AVAHI_WATCH_IN);
    ap_assert(r);

    l = read(fd, &c, sizeof(c));
    ap_assert(l == sizeof(c));

    avahi_simple_poll_quit(r->simple_poll);
}
Exemplo n.º 4
0
static void service_callback(AVAHI_GCC_UNUSED AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) {
    struct service_data *j = userdata;

    switch (state) {
        case AVAHI_ENTRY_GROUP_UNCOMMITED:
        case AVAHI_ENTRY_GROUP_REGISTERING:
        case AVAHI_ENTRY_GROUP_ESTABLISHED:
            break;

        case AVAHI_ENTRY_GROUP_COLLISION: {

            char *n;
            ap_assert(j->chosen_name);

            n = avahi_alternative_service_name(j->chosen_name);
            ap_log_error(APLOG_MARK, APLOG_WARNING, 0, j->runtime->main_server, "Name collision on '%s', changing to '%s'", j->chosen_name, n);

            apr_pool_clear(j->pool);
            j->chosen_name = apr_pstrdup(j->pool, n);

            create_service(j);

            break;
        }

        case AVAHI_ENTRY_GROUP_FAILURE:
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, j->runtime->main_server, "Failed to register service: %s", avahi_strerror(avahi_client_errno(j->runtime->client)));
            break;
    }
}
Exemplo n.º 5
0
static int SSL_recvwithtimeout(BUFF *fb, char *buf, int len)
{
    int iostate = 1;
    fd_set fdset;
    struct timeval tv;
    int err = WSAEWOULDBLOCK;
    int rv;
    int sock = fb->fd_in;
    SSL *ssl;
    int retry;

    ssl = ap_ctx_get(fb->ctx, "ssl");

    if (!(tv.tv_sec = ap_check_alarm()))
        return (SSL_read(ssl, buf, len));

    rv = ioctlsocket(sock, FIONBIO, &iostate);
    iostate = 0;
    ap_assert(!rv);
    rv = SSL_read(ssl, buf, len);
    if (rv <= 0) {
        if (BIO_sock_should_retry(rv)) {
            do {
                retry = 0;
                FD_ZERO(&fdset);
                FD_SET((unsigned int)sock, &fdset);
                tv.tv_usec = 0;
                rv = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
                if (rv == SOCKET_ERROR)
                    err = WSAGetLastError();
                else if (rv == 0) {
                    ioctlsocket(sock, FIONBIO, &iostate);
                    ap_check_alarm();
                    WSASetLastError(WSAEWOULDBLOCK);
                    return (SOCKET_ERROR);
                }
                else {
                    rv = SSL_read(ssl, buf, len);
                    if (rv == SOCKET_ERROR) {
                        if (BIO_sock_should_retry(rv)) {
                          ap_log_error(APLOG_MARK,APLOG_DEBUG, NULL,
                                       "select claimed we could read, "
                                       "but in fact we couldn't. "
                                       "This is a bug in Windows.");
                          retry = 1;
                          Sleep(100);
                        }
                        else {
                            err = WSAGetLastError();
                        }
                    }
                }
            } while(retry);
        }
    }
    ioctlsocket(sock, FIONBIO, &iostate);
    if (rv == SOCKET_ERROR)
        WSASetLastError(err);
    return (rv);
}
Exemplo n.º 6
0
static int start_child_process(apr_pool_t *p, server_rec *server, struct global_config_data *d) {
    apr_proc_t* proc;
    apr_status_t status;

/*     ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "Spawning child pid=%lu", (unsigned long) getpid()); */

    proc = apr_palloc(p, sizeof(apr_proc_t));
    ap_assert(proc);

    switch (status = apr_proc_fork(proc, p)) {

        case APR_INCHILD:
            child_process(p, server, d);
            exit(1);
            /* never reached */
            break;

        case APR_INPARENT:
            apr_pool_note_subprocess(p, proc, APR_KILL_ONLY_ONCE);
/*             ap_log_error(APLOG_MARK, APLOG_NOTICE, status, server, "Child process %lu", (unsigned long) proc->pid); */

            break;

        default:
            ap_log_error(APLOG_MARK, APLOG_ERR, status, server, "apr_proc_fork() failed");
            return HTTP_INTERNAL_SERVER_ERROR;
    }

    return OK;
}
Exemplo n.º 7
0
void ap_init_scoreboard(void *shared_score)
{
    char *more_storage;
    int i;

    ap_calc_scoreboard_size();
    ap_scoreboard_image =
        calloc(1, sizeof(scoreboard) + server_limit * sizeof(worker_score *));
    more_storage = shared_score;
    ap_scoreboard_image->global = (global_score *)more_storage;
    more_storage += sizeof(global_score);
    ap_scoreboard_image->parent = (process_score *)more_storage;
    more_storage += sizeof(process_score) * server_limit;
    ap_scoreboard_image->servers =
        (worker_score **)((char*)ap_scoreboard_image + sizeof(scoreboard));
    for (i = 0; i < server_limit; i++) {
        ap_scoreboard_image->servers[i] = (worker_score *)more_storage;
        more_storage += thread_limit * sizeof(worker_score);
    }
    if (lb_limit) {
        ap_scoreboard_image->balancers = (lb_score *)more_storage;
        more_storage += lb_limit * sizeof(lb_score);
    }
    ap_assert(more_storage == (char*)shared_score + scoreboard_size);
    ap_scoreboard_image->global->server_limit = server_limit;
    ap_scoreboard_image->global->thread_limit = thread_limit;
    ap_scoreboard_image->global->lb_limit     = lb_limit;
}
Exemplo n.º 8
0
const h2_config *h2_config_sget(server_rec *s)
{
    h2_config *cfg = (h2_config *)ap_get_module_config(s->module_config, 
                                                       &http2_module);
    ap_assert(cfg);
    return cfg;
}
Exemplo n.º 9
0
static void create_all_services(struct runtime_data *r) {
    struct service_data *j;
    ap_assert(r);

    for (j = r->services; j; j = j->next)
        create_service(j);
}
Exemplo n.º 10
0
AP_DECLARE(void) ap_init_scoreboard(void *shared_score)
{
    char *more_storage;
    int i;

    ap_calc_scoreboard_size();
    ap_scoreboard_image =
        ap_calloc(1, sizeof(scoreboard) + server_limit * sizeof(worker_score *));
    more_storage = shared_score;
    ap_scoreboard_image->global = (global_score *)more_storage;
    more_storage += sizeof(global_score);
    ap_scoreboard_image->parent = (process_score *)more_storage;
    more_storage += sizeof(process_score) * server_limit;
    ap_scoreboard_image->servers =
        (worker_score **)((char*)ap_scoreboard_image + sizeof(scoreboard));
    for (i = 0; i < server_limit; i++) {
        ap_scoreboard_image->servers[i] = (worker_score *)more_storage;
        more_storage += thread_limit * sizeof(worker_score);
    }
    ap_assert(more_storage == (char*)shared_score + scoreboard_size);
    ap_scoreboard_image->global->server_limit = server_limit;
    ap_scoreboard_image->global->thread_limit = thread_limit;
    /*
     * ******* begin amiya 20140221 *******
     */
    //we initialize these in worker since ap_daemons_limit
    //is not defined until mpm_hook is run
    ap_scoreboard_image->global->running_maxclients = 0;
    ap_scoreboard_image->global->running_keepalivetimeout = 0;
    /*
     * ******* end amiya *******
     */
}
static int google_analytics_post_config(apr_pool_t *p, apr_pool_t *plog,
										apr_pool_t *ptemp, server_rec *s)
{
	regex_tag_exists = ap_pregcomp(p, tag_exists, (AP_REG_EXTENDED | AP_REG_ICASE | AP_REG_NOSUB));
	ap_assert(regex_tag_exists != NULL);

	pattern_body_end_tag = apr_strmatch_precompile(p, body_end_tag, 0);
	return OK;
}
Exemplo n.º 12
0
// helper function for sending dovecot authentication protocol handshake request
int send_handshake(apr_pool_t * p, request_rec * r, int sock)
{
	char * const handshake_data = apr_psprintf(p, "VERSION\t%u\t%u\n" "CPID\t%u\n", AUTH_PROTOCOL_MAJOR_VERSION, AUTH_PROTOCOL_MINOR_VERSION, (unsigned int)getpid());
	ap_assert(handshake_data != NULL);
	if (send(sock, handshake_data, strlen(handshake_data), 0) > 0) {
		return 1;
	} else {
		return 0;
	}
}
Exemplo n.º 13
0
static void *create_authn_dovecot_dir_config(apr_pool_t * p, char *d)
{
	authn_dovecot_config_rec * const conf = apr_pcalloc(p, sizeof(*conf));
	ap_assert(conf != NULL);

	conf->dovecotauthsocket = "/var/run/dovecot/auth-client";	/* just to illustrate the default really */
	conf->dovecotauthtimeout = 5;
	conf->authoritative = 1;	// by default we are authoritative
	return conf;
}
Exemplo n.º 14
0
void mpm_nt_eventlog_stderr_open(char *argv0, apr_pool_t *p)
{
    SECURITY_ATTRIBUTES sa;
    HANDLE hProc = GetCurrentProcess();
    HANDLE hPipeRead = NULL;
    HANDLE hPipeWrite = NULL;
    HANDLE hDup = NULL;
    DWORD  threadid;
    apr_file_t *eventlog_file;
    apr_file_t *stderr_file;

    display_name = argv0;

    /* Create a pipe to send stderr messages to the system error log.
     *
     * _dup2() duplicates the write handle inheritable for us.
     */
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = FALSE;
    CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0);
    ap_assert(hPipeRead && hPipeWrite);

    stderr_ready = CreateEvent(NULL, FALSE, FALSE, NULL);
    stderr_thread = CreateThread(NULL, 0, service_stderr_thread,
                                 (LPVOID) hPipeRead, 0, &threadid);
    ap_assert(stderr_ready && stderr_thread);

    WaitForSingleObject(stderr_ready, INFINITE);

    if ((apr_file_open_stderr(&stderr_file, p) 
             == APR_SUCCESS)
     && (apr_os_file_put(&eventlog_file, &hPipeWrite, APR_WRITE, p)
             == APR_SUCCESS))
        apr_file_dup2(stderr_file, eventlog_file, p);

    /* The code above _will_ corrupt the StdHandle...
     * and we must do so anyways.  We set this up only
     * after we initialized the posix stderr API.
     */
    ap_open_stderr_log(p);
}
Exemplo n.º 15
0
apr_int32_t util_timestring_to_seconds(char *string)
{
	
	char *character;
	apr_int32_t number = 0;

	if (string == NULL)		
		return 0;

	character = string;
	
	/* calculate number */
	while (apr_isdigit(*character) || apr_isspace(*character)) {
		if (apr_isdigit(*character)) {
			/* translate to number */
			unsigned digit = (unsigned) *character - (unsigned) '0';
			ap_assert(digit < 10);
			number = (number * (apr_int32_t) 10) + (apr_int32_t) digit; 
		}
		character += 1;
	}
	
	if (*character != '\0') {
		switch(*character) {
			case 'w':
			case 'W':
				number = number * SECONDS_IN_WEEK;
				break;
			case 'd':
			case 'D':
				number = number * SECONDS_IN_DAY;
				break;
			case 'h':
			case 'H':
				number = number * SECONDS_IN_HOUR;
				break;
			case 'm':
			case 'M':
				number = number * SECONDS_IN_MINUTE;
				break;
			case 's':
			case 'S':
			default:
				/* this is only here for clarity */
				number = number;
				break;
		}
	}
	
	if (number > MAX_CACHE_TIMEOUT)
		number = MAX_CACHE_TIMEOUT;
	return number;
}
Exemplo n.º 16
0
static void *create_server_config(apr_pool_t *p, AVAHI_GCC_UNUSED server_rec *s) {
    struct global_config_data *d;

    d = apr_palloc(p, sizeof(struct global_config_data));
    ap_assert(d);

    d->enabled = 0;
    d->user_dir = 1;
    d->vhost = 1;
    d->user_dir_path = "public_html";

    return d;
}
Exemplo n.º 17
0
static int set_nonblock(int fd) {
    int n;

    ap_assert(fd >= 0);

    if ((n = fcntl(fd, F_GETFL)) < 0)
        return -1;

    if (n & O_NONBLOCK)
        return 0;

    return fcntl(fd, F_SETFL, n|O_NONBLOCK);
}
Exemplo n.º 18
0
// helper function used for sending prepared data to socket for authorization against dovecot auth
int send_auth_request(apr_pool_t * p, request_rec * r, int sock, const char *user, const char *pass, char *remotehost)
{
	struct iovec concat[4];

	size_t const up_size = strlen(user) + strlen(pass) + 2;
	if (up_size > BUFFMAX - 1024) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication: User and pass length is over (or close) BUFFMAX=%i which is NOT allowed size=%u\n", BUFFMAX, (unsigned int)up_size);
		return 0;
	}
	size_t const eup_size = apr_base64_encode_len(up_size);
	char * const encoded_user_pass = (char *)apr_palloc(p, sizeof(char) * eup_size);
	ap_assert(encoded_user_pass != NULL);
	// this beautifull code snippet from bellow (concat blah blah) is needed for use of apr_pstrcatv
	// as without using apr_pstrcatv apr_pstrcat  will remove \0 which we need for creating base64 encoded user_pass combination...
	concat[0].iov_base = (void *)"\0";
	concat[0].iov_len = 1;
	concat[1].iov_base = (void *)user;
	concat[1].iov_len = strlen(user);
	concat[2].iov_base = (void *)"\0";
	concat[2].iov_len = 1;
	concat[3].iov_base = (void *)pass;
	concat[3].iov_len = strlen(pass);
	char * const user_pass = apr_pstrcatv(p, concat, 4, NULL);
	ap_assert(user_pass != NULL);
	apr_base64_encode(encoded_user_pass, user_pass, up_size);
	char * const data = apr_psprintf(p, "AUTH\t1\tPLAIN\tservice=apache\tnologin"	// local ip (lip) is hardcoded as we are using local unix socket anyway...
		"\tlip=127.0.0.1\trip=%s\tsecured\tresp=%s\n", remotehost, encoded_user_pass);
	ap_assert(data != NULL);
	size_t const d_size = strlen(data);
	if (send(sock, data, d_size, 0) > 0) {
		// scrub user credentials
		memset(user_pass, '\0', up_size);
		memset(encoded_user_pass, '\0', eup_size);
		memset(data, '\0', d_size);
		return 1;
	} else {
		return 0;
	}
}
Exemplo n.º 19
0
static apr_status_t h2_filter_slave_output(ap_filter_t* filter,
                                           apr_bucket_brigade* brigade)
{
    h2_task *task = h2_ctx_cget_task(filter->c);
    apr_status_t status;
    
    ap_assert(task);
    status = slave_out(task, filter, brigade);
    if (status != APR_SUCCESS) {
        h2_task_rst(task, H2_ERR_INTERNAL_ERROR);
    }
    return status;
}
Exemplo n.º 20
0
static void add_service(struct runtime_data *r, const char *host_name, uint16_t port, const char *location, const char *name, const char *types, int append_host_name, const char *txt_record) {
    struct service_data *d;
    char *w;
    ap_assert(r);

/*     ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "add_service: %s %s %s %s", host_name, location, name, txt_record); */

    d = apr_palloc(r->pool, sizeof(struct service_data));
    ap_assert(d);

    d->pool = NULL;
    d->runtime = r;
    d->host_name = apr_pstrdup(r->pool, host_name);
    d->port = port;
    d->location = apr_pstrdup(r->pool, location);
    d->name = apr_pstrdup(r->pool, name);
    d->append_host_name = append_host_name;
    d->chosen_name = NULL;

    d->types = apr_array_make(r->pool, 4, sizeof(char*));

    if (types)
        while (*(w = ap_getword_conf(r->pool, &types)) != 0)
            *(char**) apr_array_push(d->types) = w;

    d->txt_record = apr_array_make(r->pool, 4, sizeof(char*));

    if (txt_record)
        while (*(w = ap_getword_conf(r->pool, &txt_record)) != 0)
            *(char**) apr_array_push(d->txt_record) = w;

    d->group = NULL;

    d->next = r->services;
    r->services = d;

/*     ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "done"); */

}
Exemplo n.º 21
0
apr_status_t h2_conn_run(conn_rec *c)
{
    apr_status_t status;
    int mpm_state = 0;
    h2_session *session = h2_ctx_get_session(c);
    
    ap_assert(session);
    do {
        if (c->cs) {
            c->cs->sense = CONN_SENSE_DEFAULT;
            c->cs->state = CONN_STATE_HANDLER;
        }
    
        status = h2_session_process(session, async_mpm);
        
        if (APR_STATUS_IS_EOF(status)) {
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c, 
                          H2_SSSN_LOG(APLOGNO(03045), session, 
                          "process, closing conn"));
            c->keepalive = AP_CONN_CLOSE;
        }
        else {
            c->keepalive = AP_CONN_KEEPALIVE;
        }
        
        if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state)) {
            break;
        }
    } while (!async_mpm
             && c->keepalive == AP_CONN_KEEPALIVE 
             && mpm_state != AP_MPMQ_STOPPING);

    if (c->cs) {
        switch (session->state) {
            case H2_SESSION_ST_INIT:
            case H2_SESSION_ST_IDLE:
            case H2_SESSION_ST_BUSY:
            case H2_SESSION_ST_WAIT:
                c->cs->state = CONN_STATE_WRITE_COMPLETION;
                break;
            case H2_SESSION_ST_CLEANUP:
            case H2_SESSION_ST_DONE:
            default:
                c->cs->state = CONN_STATE_LINGER;
            break;
        }
    }

    return APR_SUCCESS;
}
Exemplo n.º 22
0
static char *extract_ip(apr_array_header_t *arr, apr_array_header_t *proxy_ips, int recursive) {
    int i;
    char **ips = (char **)arr->elts;
    int len = arr->nelts;
    ap_assert(len >= 0);

    if (!recursive) return ips[len-1];
    for (i = len-1; i >= 0; i--) {
        if (!is_in_array(ips[i], proxy_ips)) {
            return ips[i];
        }
    }
    return ips[0];
}
Exemplo n.º 23
0
static void reset_services(struct runtime_data *r) {
    struct service_data *j;

    ap_assert(r);

    for (j = r->services; j; j = j->next) {
        if (j->group)
            avahi_entry_group_reset(j->group);

        if (j->pool)
            apr_pool_clear(j->pool);

        j->chosen_name = NULL;
    }
}
Exemplo n.º 24
0
static void set_and_comp_regexp(cookie_dir_rec *dcfg,
                                apr_pool_t *p,
                                const char *cookie_name)
{
    int danger_chars = 0;
    const char *sp = cookie_name;

    /* The goal is to end up with this regexp,
     * ^cookie_name=([^;,]+)|[;,][ \t]+cookie_name=([^;,]+)
     * with cookie_name obviously substituted either
     * with the real cookie name set by the user in httpd.conf, or with the
     * default COOKIE_NAME. */

    /* Anyway, we need to escape the cookie_name before pasting it
     * into the regex
     */
    while (*sp) {
        if (!apr_isalnum(*sp)) {
            ++danger_chars;
        }
        ++sp;
    }

    if (danger_chars) {
        char *cp;
        cp = apr_palloc(p, sp - cookie_name + danger_chars + 1); /* 1 == \0 */
        sp = cookie_name;
        cookie_name = cp;
        while (*sp) {
            if (!apr_isalnum(*sp)) {
                *cp++ = '\\';
            }
            *cp++ = *sp++;
        }
        *cp = '\0';
    }

    dcfg->regexp_string = apr_pstrcat(p, "^",
                                      cookie_name,
                                      "=([^;,]+)|[;,][ \t]*",
                                      cookie_name,
                                      "=([^;,]+)", NULL);

    dcfg->regexp = ap_pregcomp(p, dcfg->regexp_string, AP_REG_EXTENDED);
    ap_assert(dcfg->regexp != NULL);
}
Exemplo n.º 25
0
/* Called whenever the client or server state changes */
static void client_callback(AvahiClient *c, AvahiClientState state, void *userdata) {
    struct runtime_data *r = userdata;

    ap_assert(r);

    r->client = c;

/*     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->main_server, "client_callback(%u)", state); */

    switch (state) {
        case AVAHI_CLIENT_S_RUNNING:
            create_all_services(r);
            break;

        case AVAHI_CLIENT_S_COLLISION:
            reset_services(r);
            break;

        case AVAHI_CLIENT_FAILURE:

            if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) {
                int error;

                free_services(r);
                avahi_client_free(r->client);

                if ((r->client = avahi_client_new(avahi_simple_poll_get(r->simple_poll), AVAHI_CLIENT_NO_FAIL, client_callback, r, &error)))
                    break;

                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "avahi_client_new() failed: %s", avahi_strerror(error));
            } else
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->main_server, "Client failure: %s", avahi_strerror(avahi_client_errno(c)));

            avahi_simple_poll_quit(r->simple_poll);

            break;

        case AVAHI_CLIENT_S_REGISTERING:
        case AVAHI_CLIENT_CONNECTING:
            /* do nothing */
            break;
    }

}
Exemplo n.º 26
0
static apr_status_t h2_filter_parse_h1(ap_filter_t* f, apr_bucket_brigade* bb)
{
    h2_task *task = h2_ctx_cget_task(f->c);
    apr_status_t status;
    
    ap_assert(task);
    /* There are cases where we need to parse a serialized http/1.1 
     * response. One example is a 100-continue answer in serialized mode
     * or via a mod_proxy setup */
    while (bb && !task->output.sent_response) {
        status = h2_from_h1_parse_response(task, f, bb);
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, f->c,
                      "h2_task(%s): parsed response", task->id);
        if (APR_BRIGADE_EMPTY(bb) || status != APR_SUCCESS) {
            return status;
        }
    }
    
    return ap_pass_brigade(f->next, bb);
}
Exemplo n.º 27
0
apr_status_t h2_slave_run_pre_connection(conn_rec *slave, apr_socket_t *csd)
{
    if (slave->keepalives == 0) {
        /* Simulate that we had already a request on this connection. Some
         * hooks trigger special behaviour when keepalives is 0. 
         * (Not necessarily in pre_connection, but later. Set it here, so it
         * is in place.) */
        slave->keepalives = 1;
        /* We signal that this connection will be closed after the request.
         * Which is true in that sense that we throw away all traffic data
         * on this slave connection after each requests. Although we might
         * reuse internal structures like memory pools.
         * The wanted effect of this is that httpd does not try to clean up
         * any dangling data on this connection when a request is done. Which
         * is unneccessary on a h2 stream.
         */
        slave->keepalive = AP_CONN_CLOSE;
        return ap_run_pre_connection(slave, csd);
    }
    ap_assert(slave->output_filters);
    return APR_SUCCESS;
}
Exemplo n.º 28
0
static SOCKET remove_job(void)
{
    joblist *job;
    SOCKET sock;

    WaitForSingleObject(allowed_globals.jobsemaphore, INFINITE);
    apr_thread_mutex_lock(allowed_globals.jobmutex);

    if (shutdown_in_progress && !allowed_globals.jobhead) {
        apr_thread_mutex_unlock(allowed_globals.jobmutex);
        return (INVALID_SOCKET);
    }
    job = allowed_globals.jobhead;
    ap_assert(job);
    allowed_globals.jobhead = job->next;
    if (allowed_globals.jobhead == NULL)
        allowed_globals.jobtail = NULL;
    apr_thread_mutex_unlock(allowed_globals.jobmutex);
    sock = job->sock;
    free(job);

    return (sock);
}
Exemplo n.º 29
0
static void save_req_info(request_rec *r)
{
    /* to save for the request:
     * r->the_request + 
     * foreach header:
     *   '|' + header field
     */
    int len = strlen(r->the_request);
    char *ch;
    ap_table_do(count_headers, &len, r->headers_in, NULL);

    request_plus_headers = ap_palloc(r->pool, len + 2 /* 2 for the '\n' + '\0' at end */);
    ch = request_plus_headers;
    strcpy(ch, r->the_request);
    ch += strlen(ch);

    ap_table_do(copy_headers, &ch, r->headers_in, NULL);
    *ch = '\n';
    *(ch + 1) = '\0';

    ap_assert(ch == request_plus_headers + len);

    ap_register_cleanup(r->pool, NULL, clear_req_info, ap_null_cleanup);
}
Exemplo n.º 30
0
static apr_status_t do_pattmatch(ap_filter_t *f, apr_bucket *inb,
                                 apr_bucket_brigade *mybb,
                                 apr_pool_t *pool)
{
    int i;
    int force_quick = 0;
    ap_regmatch_t regm[AP_MAX_REG_MATCH];
    apr_size_t bytes;
    apr_size_t len;
    const char *buff;
    struct ap_varbuf vb;
    apr_bucket *b;
    apr_bucket *tmp_b;

    subst_dir_conf *cfg =
    (subst_dir_conf *) ap_get_module_config(f->r->per_dir_config,
                                             &substitute_module);
    subst_pattern_t *script;

    APR_BRIGADE_INSERT_TAIL(mybb, inb);
    ap_varbuf_init(pool, &vb, 0);

    script = (subst_pattern_t *) cfg->patterns->elts;
    /*
     * Simple optimization. If we only have one pattern, then
     * we can safely avoid the overhead of flattening
     */
    if (cfg->patterns->nelts == 1) {
       force_quick = 1;
    }
    for (i = 0; i < cfg->patterns->nelts; i++) {
        for (b = APR_BRIGADE_FIRST(mybb);
             b != APR_BRIGADE_SENTINEL(mybb);
             b = APR_BUCKET_NEXT(b)) {
            if (APR_BUCKET_IS_METADATA(b)) {
                /*
                 * we should NEVER see this, because we should never
                 * be passed any, but "handle" it just in case.
                 */
                continue;
            }
            if (apr_bucket_read(b, &buff, &bytes, APR_BLOCK_READ)
                    == APR_SUCCESS) {
                int have_match = 0;
                vb.strlen = 0;
                if (script->pattern) {
                    const char *repl;
                    /*
                     * space_left counts how many bytes we have left until the
                     * line length reaches max_line_length.
                     */
                    apr_size_t space_left = cfg->max_line_length;
                    apr_size_t repl_len = strlen(script->replacement);
                    while ((repl = apr_strmatch(script->pattern, buff, bytes)))
                    {
                        have_match = 1;
                        /* get offset into buff for pattern */
                        len = (apr_size_t) (repl - buff);
                        if (script->flatten && !force_quick) {
                            /*
                             * We are flattening the buckets here, meaning
                             * that we don't do the fast bucket splits.
                             * Instead we copy over what the buckets would
                             * contain and use them. This is slow, since we
                             * are constanting allocing space and copying
                             * strings.
                             */
                            if (vb.strlen + len + repl_len > cfg->max_line_length)
                                return APR_ENOMEM;
                            ap_varbuf_strmemcat(&vb, buff, len);
                            ap_varbuf_strmemcat(&vb, script->replacement, repl_len);
                        }
                        else {
                            /*
                             * The string before the match but after the
                             * previous match (if any) has length 'len'.
                             * Check if we still have space for this string and
                             * the replacement string.
                             */
                            if (space_left < len + repl_len)
                                return APR_ENOMEM;
                            space_left -= len + repl_len;
                            /*
                             * We now split off the string before the match
                             * as its own bucket, then isolate the matched
                             * string and delete it.
                             */
                            SEDRMPATBCKT(b, len, tmp_b, script->patlen);
                            /*
                             * Finally, we create a bucket that contains the
                             * replacement...
                             */
                            tmp_b = apr_bucket_transient_create(script->replacement,
                                      script->replen,
                                      f->r->connection->bucket_alloc);
                            /* ... and insert it */
                            APR_BUCKET_INSERT_BEFORE(b, tmp_b);
                        }
                        /* now we need to adjust buff for all these changes */
                        len += script->patlen;
                        bytes -= len;
                        buff += len;
                    }
                    if (have_match) {
                        if (script->flatten && !force_quick) {
                            /* XXX: we should check for AP_MAX_BUCKETS here and
                             * XXX: call ap_pass_brigade accordingly
                             */
                            char *copy = ap_varbuf_pdup(pool, &vb, NULL, 0,
                                                        buff, bytes, &len);
                            tmp_b = apr_bucket_pool_create(copy, len, pool,
                                                           f->r->connection->bucket_alloc);
                            APR_BUCKET_INSERT_BEFORE(b, tmp_b);
                            apr_bucket_delete(b);
                            b = tmp_b;
                        }
                        else {
                            /*
                             * We want the behaviour to be predictable.
                             * Therefore we try to always error out if the
                             * line length is larger than the limit,
                             * regardless of the content of the line. So,
                             * let's check if the remaining non-matching
                             * string does not exceed the limit.
                             */
                            if (space_left < b->length)
                                return APR_ENOMEM;
                        }
                    }
                }
                else if (script->regexp) {
                    int left = bytes;
                    const char *pos = buff;
                    char *repl;
                    apr_size_t space_left = cfg->max_line_length;
                    while (!ap_regexec_len(script->regexp, pos, left,
                                       AP_MAX_REG_MATCH, regm, 0)) {
                        apr_status_t rv;
                        have_match = 1;
                        if (script->flatten && !force_quick) {
                            /* check remaining buffer size */
                            /* Note that the last param in ap_varbuf_regsub below
                             * must stay positive. If it gets 0, it would mean
                             * unlimited space available. */
                            if (vb.strlen + regm[0].rm_so >= cfg->max_line_length)
                                return APR_ENOMEM;
                            /* copy bytes before the match */
                            if (regm[0].rm_so > 0)
                                ap_varbuf_strmemcat(&vb, pos, regm[0].rm_so);
                            /* add replacement string, last argument is unsigned! */
                            rv = ap_varbuf_regsub(&vb, script->replacement, pos,
                                                  AP_MAX_REG_MATCH, regm,
                                                  cfg->max_line_length - vb.strlen);
                            if (rv != APR_SUCCESS)
                                return rv;
                        }
                        else {
                            apr_size_t repl_len;
                            /* acount for string before the match */
                            if (space_left <= regm[0].rm_so)
                                return APR_ENOMEM;
                            space_left -= regm[0].rm_so;
                            rv = ap_pregsub_ex(pool, &repl,
                                               script->replacement, pos,
                                               AP_MAX_REG_MATCH, regm,
                                               space_left);
                            if (rv != APR_SUCCESS)
                                return rv;
                            repl_len = strlen(repl);
                            space_left -= repl_len;
                            len = (apr_size_t) (regm[0].rm_eo - regm[0].rm_so);
                            SEDRMPATBCKT(b, regm[0].rm_so, tmp_b, len);
                            tmp_b = apr_bucket_transient_create(repl, repl_len,
                                                f->r->connection->bucket_alloc);
                            APR_BUCKET_INSERT_BEFORE(b, tmp_b);
                        }
                        /*
                         * reset to past what we just did. pos now maps to b
                         * again
                         */
                        pos += regm[0].rm_eo;
                        left -= regm[0].rm_eo;
                    }
                    if (have_match && script->flatten && !force_quick) {
                        char *copy;
                        /* Copy result plus the part after the last match into
                         * a bucket.
                         */
                        copy = ap_varbuf_pdup(pool, &vb, NULL, 0, pos, left,
                                              &len);
                        tmp_b = apr_bucket_pool_create(copy, len, pool,
                                           f->r->connection->bucket_alloc);
                        APR_BUCKET_INSERT_BEFORE(b, tmp_b);
                        apr_bucket_delete(b);
                        b = tmp_b;
                    }
                }
                else {
                    ap_assert(0);
                    continue;
                }
            }
        }
        script++;
    }
    ap_varbuf_free(&vb);
    return APR_SUCCESS;
}