apr_status_t round_robin_get_next_url()

in flood_round_robin.c [956:1067]


apr_status_t round_robin_get_next_url(request_t **request, profile_t *profile)
{
    round_robin_profile_t *rp;
    request_t *r;

    rp = (round_robin_profile_t*)profile;

    /* FIXME: precompute request_t in profile_init */
    r = apr_pcalloc(rp->pool, sizeof(request_t));
    r->pool = rp->pool;

    if (rp->url[rp->current_url].requesttemplate)
    {
        r->uri = parse_param_string(rp, 
                                    rp->url[rp->current_url].requesttemplate);
    }
    else
        r->uri = rp->url[rp->current_url].url;
      
    r->method = rp->url[rp->current_url].method;

    /* We're created by calloc, so no need to set payload to be null or
     * payloadsize to be 0. 
     */
    if (rp->url[rp->current_url].payload)
    {
        r->payload = rp->url[rp->current_url].payload;
        r->payloadsize = strlen(rp->url[rp->current_url].payload);
    }
    else if (rp->url[rp->current_url].payloadtemplate)
    {
        r->payload = parse_param_string(rp, 
                                    rp->url[rp->current_url].payloadtemplate);
        r->payloadsize = strlen(r->payload);
    }

    if (rp->url[rp->current_url].contenttype)
    {
        r->contenttype = parse_param_string(rp, rp->url[rp->current_url].contenttype);
        r->contenttypesize = strlen(r->contenttype);
    }

    /* If they want a sleep, do it now. */
    if (rp->url[rp->current_url].predelay) {
        apr_int64_t real_predelay = rp->url[rp->current_url].predelay;

        /* If the delay has a precision, adjust the
         * delay by some random fraction of the precision here */
        if (rp->url[rp->current_url].predelayprecision) {
            /* FIXME: this should be more portable, like apr_generate_random_bytes() */
            float factor = -1.0 + (2.0*rand()/(RAND_MAX+1.0));
            real_predelay += rp->url[rp->current_url].predelayprecision * factor;
        }

        /* we can only delay positive times, can't go back in time :( */
        if (real_predelay < 0)
            real_predelay = 0;

        /* only bother going to sleep if we generated a delay */
        if (real_predelay > 0)
            apr_sleep(real_predelay);

    }

    r->parsed_uri = apr_palloc(rp->pool, sizeof(apr_uri_t));

    if (rp->baseurl != NULL) {
        r->uri = apr_pstrcat(rp->pool, rp->baseurl, r->uri, NULL);
    }

    apr_uri_parse(rp->pool, r->uri, r->parsed_uri);
    if (r->parsed_uri->scheme == NULL || r->parsed_uri->hostname == NULL) {
        apr_file_printf(local_stderr, "Misformed URL '%s'\n", r->uri);
        exit (APR_EGENERAL);
    }
    if (r->parsed_uri->hostname[0] == '\0') {
        apr_file_printf(local_stderr,
                        "Misformed URL '%s' -- can't find valid hostname.\n",
                        r->uri);
        exit (APR_EGENERAL);
    }
    /* this schouldn't be hardcoded, but... :) */
    if (apr_strnatcmp (r->parsed_uri->scheme, "http") != APR_SUCCESS
        && apr_strnatcmp (r->parsed_uri->scheme, "https") != APR_SUCCESS) {
        apr_file_printf(local_stderr,
                        "Wrong URL scheme '%s' -- only 'http' and 'https' schemes are supported.\n",
                        r->parsed_uri->scheme);
        exit (APR_EGENERAL);
    }
    if (r->parsed_uri->user != NULL || r->parsed_uri->password != NULL) {
        apr_file_printf(local_stderr,
                        "Misformed URL -- auth data schould be outside URL -- please see docs.\n");
        exit (APR_EGENERAL);
    }
    if (!r->parsed_uri->port)
    {
        r->parsed_uri->port = 
                         apr_uri_port_of_scheme(r->parsed_uri->scheme);
    }
    if (!r->parsed_uri->path) /* If / is not there, be nice.  */
        r->parsed_uri->path = "/";

    r->parsed_proxy_uri = rp->proxy_url;

#ifdef PROFILE_DEBUG
    apr_file_printf(local_stdout, "Generating request to: %s\n", r->uri);
#endif /* PROFILE_DEBUG */

    *request = r;

    return APR_SUCCESS;
}