Exemple #1
1
static PyObject *parse_qs(PyObject *self, PyObject *args, PyObject *kw)
{

    PyObject *pairs, *dict;
    int i, n, len, lsize;
    char *qs;
    int keep_blank_values = 0;
    int strict_parsing = 0; /* XXX not implemented */
    char *keywords[] = { "qs", "keep_blank_values", "strict_parsing", 0 };
    
    if (! PyArg_ParseTupleAndKeywords(args, kw, "s|ii", keywords, &qs, &keep_blank_values, 
                           &strict_parsing)) 
        return NULL; /* error */

    /* split query string by '&' and ';' into a list of pairs */
    /* PYTHON 2.5: 'PyList_New' uses Py_ssize_t for input parameters */ 
    pairs = PyList_New(0);
    if (pairs == NULL)
        return NULL;

    i = 0;
    len = strlen(qs);

    while (i < len) {

        PyObject *pair;
        char *cpair;
        int j = 0;

        /* PYTHON 2.5: 'PyString_FromStringAndSize' uses Py_ssize_t for input parameters */ 
        pair = PyString_FromStringAndSize(NULL, len);
        if (pair == NULL)
            return NULL;

        /* split by '&' or ';' */
        cpair = PyString_AS_STRING(pair);
        while ((qs[i] != '&') && (qs[i] != ';') && (i < len)) {
            /* replace '+' with ' ' */
            cpair[j] = (qs[i] == '+') ? ' ' : qs[i];
            i++;
            j++;
        }

        if (j) {
            /* PYTHON 2.5: '_PyString_Resize' uses Py_ssize_t for input parameters */ 
            _PyString_Resize(&pair, j);
            if (pair)
                PyList_Append(pairs, pair);
        }

        Py_XDECREF(pair);
        i++;
    }

    /*
     * now we have a list of "abc=def" string (pairs), let's split 
     * them all by '=' and put them in a dictionary.
     */
    
    dict = PyDict_New();
    if (dict == NULL)
        return NULL;

    /* PYTHON 2.5: 'PyList_Size' uses Py_ssize_t for input parameters */ 
    lsize = PyList_Size(pairs);
    n = 0;

    while (n < lsize) {

        PyObject *pair, *key, *val;
        char *cpair, *ckey, *cval;
        int k, v;

        pair = PyList_GET_ITEM(pairs, n);
        cpair = PyString_AS_STRING(pair);

        len = strlen(cpair);
        /* PYTHON 2.5: 'PyString_FromStringAndSize' uses Py_ssize_t for input parameters */ 
        key = PyString_FromStringAndSize(NULL, len);
        if (key == NULL) 
            return NULL;
        /* PYTHON 2.5: 'PyString_FromStringAndSize' uses Py_ssize_t for input parameters */ 
        val = PyString_FromStringAndSize(NULL, len);
        if (val == NULL) 
            return NULL;

        ckey = PyString_AS_STRING(key);
        cval = PyString_AS_STRING(val);

        i = 0;
        k = 0;
        v = 0;
        while (i < len) {
            if (cpair[i] != '=') {
                ckey[k] = cpair[i];
                k++;
                i++;
            }
            else {
                i++;      /* skip '=' */
                while (i < len) {
                    cval[v] = cpair[i];
                    v++;
                    i++;
                }
            }
        }

        ckey[k] = '\0';
        cval[v] = '\0';

        if (keep_blank_values || (v > 0)) {

            ap_unescape_url(ckey);
            ap_unescape_url(cval);

            /* PYTHON 2.5: '_PyString_Resize' uses Py_ssize_t for input parameters */ 
            _PyString_Resize(&key, strlen(ckey));
            /* PYTHON 2.5: '_PyString_Resize' uses Py_ssize_t for input parameters */ 
            _PyString_Resize(&val, strlen(cval));

            if (key && val) {

                ckey = PyString_AS_STRING(key);
                cval = PyString_AS_STRING(val);
        
                if (PyMapping_HasKeyString(dict, ckey)) {
                    PyObject *list;
                    list = PyDict_GetItem(dict, key);
                    PyList_Append(list, val);
                    /* PyDict_GetItem is a borrowed ref, no decref */
                }
                else {
                    PyObject *list;
                    list = Py_BuildValue("[O]", val);
                    PyDict_SetItem(dict, key, list);
                    Py_DECREF(list);
                }
            }
        }

        Py_XDECREF(key);
        Py_XDECREF(val);

        n++;
    }

    Py_DECREF(pairs);
    return dict;
}
static void
argstr_to_table(apr_pool_t *p, char *str, apr_table_t *parms)
{
    char *key;
    char *value;
    char *strtok_state;

    key = apr_strtok(str, "&", &strtok_state);
    while (key) {
        value = strchr(key, '=');
        if (value) {
            *value = '\0';      /* Split the string in two */
            value++;            /* Skip passed the = */
        }
        else {
            value = "1";
        }
        ap_unescape_url(key);
        ap_unescape_url(value);
        apr_table_set(parms, key, value);
        /*
         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
         "Found query arg: %s = %s", key, value);
         */
        key = apr_strtok(NULL, "&", &strtok_state);
    }
}
Exemple #3
0
/* parse parameter */
static apr_hash_t *parse_parameter(request_rec *r) {
    char *str = apr_pstrdup(r->pool, r->args);
    if( str == NULL ) {
        return NULL;
    }
    
    apr_hash_t *hash = NULL;
    const char *del = "&";
    char *items, *last, *st;
    hash = apr_hash_make(r->pool);

    // set hash
    for ( items = apr_strtok(str, del, &last); items != NULL; items = apr_strtok(NULL, del, &last) ){
        st = strchr(items, '=');
        if (st) {
            *st++ = '\0';
            ap_unescape_url(items);
            ap_unescape_url(st);
        } else {
            st = "";
            ap_unescape_url(items);
        }
        apr_hash_set( hash, items, APR_HASH_KEY_STRING, st );
    }
    return hash;
}
/**
 * Nomalize charset in HTTP request line and HTTP header(s).
 * Returns 0 on success, -1 (non-zero) on error.
 *
 * FIXME: Should handle/consider partial success?
 *
 * @param  r Apache request object structure
 * @param cd Conversion descriptor, made by iconv_open(3).
 */
static int
iconv_header(request_rec *r, iconv_t cd) {

  char *buff;
  char *keys[] = { "Destination", NULL };
  int   i;

  /* Normalize encoding in HTTP request line */
  ap_unescape_url(r->unparsed_uri);
  if ((buff = iconv_string(r, cd, r->unparsed_uri,
			   strlen(r->unparsed_uri))) == NULL)
    return -1;
  ap_parse_uri(r, buff);
  ap_getparents(r->uri); /* normalize given path for security */

  /* Normalize encoding in HTTP request header(s) */
  for (i = 0 ; keys[i] ; i++) {
    if ((buff = (char *)ap_table_get(r->headers_in, keys[i])) != NULL) {
      ap_unescape_url(buff);
      if ((buff = iconv_string(r, cd, buff, strlen(buff))) == NULL)
	return -1;
      ap_table_set(r->headers_in, keys[i], buff);
    }
  }

  return 0;
}
Exemple #5
0
/**
 * Copied from httpd/trunk/modules/cluster/mod_heartbeat.c.
 *
 * Copyright 2009 The Apache Software Foundation.
 *
 * The following function is licensed under the Apache
 * License, Version 2.0. See COPYING for more details.
 */
static void qs_to_table(const char *input, apr_table_t *parms,
                        apr_pool_t *p)
{
    char *key;
    char *value;
    char *query_string;
    char *strtok_state;

    if (input == NULL) {
        return;
    }

    query_string = apr_pstrdup(p, input);

    key = apr_strtok(query_string, "&", &strtok_state);
    while (key) {
        value = strchr(key, '=');
        if (value) {
            *value = '\0';      /* Split the string in two */
            value++;            /* Skip passed the = */
        }
        else {
            value = "1";
        }
        ap_unescape_url(key);
        ap_unescape_url(value);
        apr_table_set(parms, key, value);
        /*
           ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
           "Found query arg: %s = %s", key, value);
         */
        key = apr_strtok(NULL, "&", &strtok_state);
    }
}
Exemple #6
0
static apr_hash_t *parse_form_from_string(request_rec *r, char *args) {
  apr_hash_t *form;
  /*  apr_array_header_t *values = NULL;*/
  char *pair;
  char *eq;
  const char *delim = "&";
  char *last;
  char *values;

  if(args == NULL) {
    return NULL;
  }

  form = apr_hash_make(r->pool);
  
  /* Split the input on '&' */
  for (pair = apr_strtok(args, delim, &last); pair != NULL;
       pair = apr_strtok(NULL, delim, &last)) {
    for (eq = pair; *eq; ++eq) {
      if (*eq == '+') {
	*eq = ' ';
      }
    }

    /* split into key value and unescape it */
    eq = strchr(pair, '=');
    
    if(eq) {
      *eq++ = '\0';
      ap_unescape_url(pair);
      ap_unescape_url(eq);
    } else {
      eq = "";
      ap_unescape_url(pair);
    }

    /* Store key/value pair in out form hash. Given that there
     * may be many values for the same key, we store values
     * in an array (which we'll have to create the first
     * time we encounter the key in question).
     */
    values = apr_hash_get(form, pair, APR_HASH_KEY_STRING);
    if(values != NULL) {
      values = apr_pstrcat(r->pool, values, "&", eq, NULL);
      /*      values = apr_array_make(r->pool, 1, sizeof(const char*));
	      apr_hash_set(form, pair, APR_HASH_KEY_STRING, values);*/
    } else {
      values = apr_pstrdup(r->pool, eq);
    }
    apr_hash_set(form, pair, APR_HASH_KEY_STRING, values);
  }

  return form;
  
}
Exemple #7
0
static void cwx_parse_args(CWX_CONNECT* conn){
    char *begin = NULL;
    char const *mid = NULL;
    char const *end =NULL;
    char* args = conn->m_args;
    CWX_KEY_VALUE* key_value;
    unsigned int key_len = 0;
    unsigned int data_len = 0;
    conn->m_args_head = NULL;
    conn->m_args_tail =NULL;
    if (!args) return;
    
    begin = args;
    mid = strchr(begin, '=');
    while(mid){
        key_value = (CWX_KEY_VALUE*)apr_pcalloc(conn->m_request->pool, sizeof(CWX_KEY_VALUE));
        //get key
        while(*begin == '&') begin++;
        key_len = mid - begin;
        key_value->m_key = (char*)apr_pcalloc(conn->m_request->pool, key_len+1);
        key_value->m_lowerkey = (char*)apr_pcalloc(conn->m_request->pool, key_len+1);
        memcpy(key_value->m_key, begin, key_len);
        key_value->m_key[key_len] = 0x00;
        ap_unescape_url(key_value->m_key);
        cwx_trim(key_value->m_key);
        strcpy(key_value->m_lowerkey, key_value->m_key);
        cwx_tolower(key_value->m_lowerkey);
        //get data
        mid++;
        end = strchr(mid, '&');
        if (0 == end)
            data_len = strlen(mid);
        else
            data_len = end - mid;
        key_value->m_value = (char*)apr_pcalloc(conn->m_request->pool, data_len+1);
        memcpy(key_value->m_value, mid, data_len);
        key_value->m_value[data_len] = 0x00;
        ap_unescape_url(key_value->m_value);
        //add to the 
        key_value->m_next = NULL;
        if (!conn->m_args_head){
            conn->m_args_head = conn->m_args_tail = key_value;
        }else{
            conn->m_args_tail->m_next = key_value;
            conn->m_args_tail = key_value;
        }
        if (end){
            begin = end+1;
            mid = strchr(begin, '=');
        }else{
            break;
        }
    }
}
Exemple #8
0
static int twms_handler(request_rec *r)

{
  twms_dir_conf *dcfg;
  const char *data;
  const char *val;
  apr_table_t *tab;
  apr_file_t *fh;
  apr_size_t nsend;
  apr_finfo_t info;


  if ((r->method_number != M_GET )||(r->args==0)) return DECLINED;
  data=r->args;
  // scfg=ap_get_module_config(r->server->module_config,&twms_module);
  dcfg=ap_get_module_config(r->per_dir_config,&twms_module);
  if (!dcfg) return DECLINED; // Does this ever happen?

  if (!ap_strstr(data,"GetTileService")) return DECLINED;
  // Do we have a config for this directory

//  ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"TWMS_handler: args %s, path %s scfg %x dcfg %x dir %s conf %s",
//    data,r->parsed_uri.path,scfg,dcfg,dcfg->path,dcfg->Config);
  if (!dcfg->Config) return DECLINED;


  // This is overkill here, but it works
  tab=apr_table_make(r->pool,0);

  while (*data && (val=ap_getword(r->pool, &data, '&'))) {
    char *key=apr_pstrdup(r->pool,ap_getword(r->pool, &val, '='));
    char *ival=apr_pstrdup(r->pool,val);
    ap_unescape_url(key);ap_unescape_url(ival);
    apr_table_merge(tab,key,ival);
  }

  if (!(val=apr_table_get(tab,"request"))) return DECLINED;
  if (apr_strnatcmp(val,"GetTileService")) return DECLINED;

  if (APR_SUCCESS!=apr_file_open(&fh,apr_pstrcat(r->pool,dcfg->path,dcfg->Config,0),
      APR_READ,APR_OS_DEFAULT,r->pool)) {
    ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"TWMS file can't be read");
    return HTTP_CONFLICT;
  }
  ap_log_error(APLOG_MARK,APLOG_ERR,0,r->server,"TWMS Sending GTS file");
  apr_file_info_get(&info,APR_FINFO_SIZE,fh);

  ap_set_content_type(r,"text/xml");
  ap_send_fd(fh,r,0,info.size,&nsend);

  apr_file_close(fh);
  return OK;
}
/* This is the special environment used for running the "exec cmd="
 *   variety of SSI directives.
 */
static void add_ssi_vars(request_rec *r)
{
    apr_table_t *e = r->subprocess_env;

    if (r->path_info && r->path_info[0] != '\0') {
        request_rec *pa_req;

        apr_table_setn(e, "PATH_INFO", ap_escape_shell_cmd(r->pool,
                                                           r->path_info));

        pa_req = ap_sub_req_lookup_uri(ap_escape_uri(r->pool, r->path_info),
                                       r, NULL);
        if (pa_req->filename) {
            apr_table_setn(e, "PATH_TRANSLATED",
                           apr_pstrcat(r->pool, pa_req->filename,
                                       pa_req->path_info, NULL));
        }
        ap_destroy_sub_req(pa_req);
    }

    if (r->args) {
        char *arg_copy = apr_pstrdup(r->pool, r->args);

        apr_table_setn(e, "QUERY_STRING", r->args);
        ap_unescape_url(arg_copy);
        apr_table_setn(e, "QUERY_STRING_UNESCAPED",
                       ap_escape_shell_cmd(r->pool, arg_copy));
    }
}
/* Parse x-www-url-formencoded args */
apr_table_t *parse_args(request_rec *r, char *args) {

  char* pair;
  char* last = NULL;
  char* eq;
  char *delim = "&";

  apr_table_t *vars = apr_table_make(r->pool, 10);
  for (pair = apr_strtok(r->args, delim, &last); pair; pair = apr_strtok(NULL, delim, &last)) {

    for (eq = pair; *eq; ++eq)
      if (*eq == '+')
        *eq = ' ';

    ap_unescape_url(pair);
    eq = strchr(pair, '=');
    if (eq) {
      *eq++ = 0;
      apr_table_merge(vars, pair, eq);
    } else {
      apr_table_merge(vars, pair, "");
    }

  }

  return vars;

}
Exemple #11
0
static void split_to_parms(ApacheRequest *req, const char *data)
{
    request_rec *r = req->r;
    const char *val;

    while (*data && (val = my_urlword(r->pool, &data))) {
	const char *key = ap_getword(r->pool, &val, '=');

	req_plustospace((char*)key);
	ap_unescape_url((char*)key);
	req_plustospace((char*)val);
	ap_unescape_url((char*)val);

	ap_table_add(req->parms, key, val);
    }

}
/* This is our simple query decoding function. Should be improved but for now
 * it works...
 */
static int
mapserver_decode_args (apr_pool_t *p, char *args,
                       char ***ParamNames, char ***ParamValues)
{
  char **argv = NULL;
  int    i;
  int    n;
  int    argc = 0;
  char  *sep;

  /* alloc the name/value pointer list */
  argv = (char**) apr_pcalloc (p, (WMS_MAX_ARGS + 1) * 2 * sizeof (char*));
  *ParamNames  = argv;
  *ParamValues = argv + WMS_MAX_ARGS + 1;
  /* No arguments? Then we're done */
  if (!args) return 0;

  argv [0] = args;

  /* separate the arguments */
  for (i = 1, n = 0; args [n] && (i < WMS_MAX_ARGS); n++)
    if (args [n] == '&') {
      argv [i++] = args + n + 1;
      args [n  ] = '\0';
    }

  /* eleminate empty args */
  for (n = 0, i = 0; argv [i]; i++)
    if (*(argv [i]) != '\0')
      argv [n++] = argv [i];
    else
      argv [i  ] = NULL;

  /* argument count is the number of non-zero arguments! */
  argc = n;

  /* split the name/value pairs */
  for (i = 0; argv [i]; i++) {
    sep = strchr (argv [i], '=');
    if (!sep) continue;
    *sep = '\0';
    argv [i + WMS_MAX_ARGS + 1] = (char*) apr_pstrdup (p, sep + 1);

    if (ap_unescape_url (argv [i + WMS_MAX_ARGS + 1]) == HTTP_BAD_REQUEST) {
      ap_log_error (APLOG_MARK, APLOG_ERR, 0, NULL,
                    "%s: malformed URI, couldn't unescape parm %s",
                    __func__, argv [i]);

      argv [i + WMS_MAX_ARGS + 1] = NULL;
    } else {
      plustospace (argv [i + WMS_MAX_ARGS + 1]);
    }
  }
  return argc;
}
/* Look through 'Cookie' header for indicated cookie; extract it
 * and URL-unescape it. Return the cookie on success, NULL on failure. */
static char * extract_cookie(request_rec *r, const char *szCookie_name)
{
    const char *szRaw_cookie, *szRaw_cookie_start = NULL, *szRaw_cookie_end;
    char *szCookie;
    int i;

    /* get cookie string */
    szRaw_cookie = apr_table_get(r->headers_in, "Cookie");
    if (!szRaw_cookie)
    	return 0;

    /* loop to search cookie name in cookie header */
    do {
    	/* search cookie name in cookie string */
    	if ((szRaw_cookie = strstr(szRaw_cookie, szCookie_name)) == 0)
    	    return 0;
        szRaw_cookie_start = szRaw_cookie;
    	/* search '=' */
    	if ((szRaw_cookie = strchr(szRaw_cookie, '=')) == 0)
    	    return 0;
    } while (strncmp(szCookie_name, szRaw_cookie_start, szRaw_cookie - szRaw_cookie_start) != 0);

    /* skip '=' */
    szRaw_cookie++;

    /* search end of cookie name value: ';' or end of cookie strings */
    if ((szRaw_cookie_end = strchr(szRaw_cookie, ';')) == 0 && (szRaw_cookie_end = strchr(szRaw_cookie, '\0')) == 0)
	   return 0;

    /* dup the value string found in apache pool and set the result pool ptr to szCookie ptr */
    if ((szCookie = apr_pstrndup(r->pool, szRaw_cookie, szRaw_cookie_end-szRaw_cookie)) == 0)
	   return 0;
    /* unescape the value string */
    if (ap_unescape_url(szCookie) != 0)
	   return 0;

    /* be extra paranoid about the cookie value, reject if no md5sum */
    if (!(strlen(szCookie) == 32 || strlen(szCookie)== 43))
	   return 0;
    for (i = 0; i < 32; i++) {
        if (szCookie[i] == '_')
            continue;
    	if (szCookie[i] >= '0' && szCookie[i] <= '9')
    	    continue;
    	if (szCookie[i] >= 'a' && szCookie[i] <= 'f')
    	    continue;
    	return 0;
    }

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, ERRTAG "Cleaned Cookie: %s ", szCookie);
    return szCookie;
}
static apr_status_t default_build_command(const char **cmd, const char ***argv,
                                          request_rec *r, apr_pool_t *p,
                                          cgi_exec_info_t *e_info)
{
    int numwords, x, idx;
    char *w;
    const char *args = NULL;

    if (e_info->process_cgi) {
        *cmd = r->filename;
        /* Do not process r->args if they contain an '=' assignment
         */
        if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) {
            args = r->args;
        }
    }

    if (!args) {
        numwords = 1;
    }
    else {
        /* count the number of keywords */
        for (x = 0, numwords = 2; args[x]; x++) {
            if (args[x] == '+') {
                ++numwords;
            }
        }
    }
    /* Everything is - 1 to account for the first parameter
     * which is the program name.
     */
    if (numwords > APACHE_ARG_MAX - 1) {
        numwords = APACHE_ARG_MAX - 1;    /* Truncate args to prevent overrun */
    }
    *argv = apr_palloc(p, (numwords + 2) * sizeof(char *));
    (*argv)[0] = *cmd;
    for (x = 1, idx = 1; x < numwords; x++) {
        w = ap_getword_nulls(p, &args, '+');
        ap_unescape_url(w);
        (*argv)[idx++] = ap_escape_shell_cmd(p, w);
    }
    (*argv)[idx] = NULL;

    return APR_SUCCESS;
}
static int light_search_handler(request_rec *r, softbot_handler_rec *s)
{
    int rv = 0;
    int i = 0;

    init_server(r, s);

	set_con_config(r->server);
	msg_record_init(&s->msg);

	rv = sb_run_qp_init();
    if(rv != SUCCESS && rv != DECLINE) {
	    MSG_RECORD(&s->msg, error, "qp init failed");
        return FAIL;
    }

	if(apr_table_get(s->parameters_in, "q") == NULL ||
			strlen(apr_table_get(s->parameters_in, "q")) == 0) {
	    MSG_RECORD(&s->msg, error, "query is null, must use http get method");
        return FAIL;
	}

	ap_unescape_url((char *)apr_table_get(s->parameters_in, "q"));

    rv = sb_run_qp_init_request(&qp_request, 
                                (char *)apr_table_get(s->parameters_in, "q"));
    if(rv != SUCCESS) {
	    s->msg = qp_request.msg;
        error("can not init request");
        return FAIL;
    }

    rv = sb_run_qp_init_response(&qp_response);
    if(rv != SUCCESS) {
	    s->msg = qp_request.msg;
        error("can not init request");
        return FAIL;
    }

	timelog("sb_run_qp_light_search start");
	rv = sb_run_qp_light_search(&qp_request, &qp_response);
	timelog("sb_run_qp_light_search finish");
	if (rv != SUCCESS) {
	    s->msg = qp_request.msg;
		error("sb_run_qp_light_search failed: query[%s]", qp_request.query);
		return FAIL;
	}

	ap_set_content_type(r, "x-softbotd/binary");

	timelog("send_result_start");

	// 0. node id - 0 ~ 16 
	ap_rwrite(&(this_node_id), sizeof(uint32_t), r);

	// 1. 총 검색건수 
	ap_rwrite(&(qp_response.search_result), sizeof(uint32_t), r);

	// 2. 전송 검색건수
	ap_rwrite(&(qp_response.vdl->cnt), sizeof(uint32_t), r);

	// 3. 검색 단어 리스트
	ap_rwrite(qp_response.parsed_query, sizeof(qp_response.parsed_query), r);

	debug("search_result[%u], send_cnt[%u], parsed_query[%s]", 
			qp_response.search_result,
			qp_response.vdl->cnt,
			qp_response.parsed_query);

    // 4. 검색결과 전송
    for(i = 0; i < qp_response.vdl->cnt; i++) {
		virtual_document_t* vd = &(qp_response.vdl->data[i]);
   
        print_virtual_document(vd);

		ap_rwrite((void*)&vd->id, sizeof(uint32_t), r);

		ap_rwrite((void*)&vd->relevance, sizeof(uint32_t), r);

		ap_rwrite((void*)&vd->dochit_cnt, sizeof(uint32_t), r);

		ap_rwrite((void*)vd->dochits, sizeof(doc_hit_t)*vd->dochit_cnt, r);

		ap_rwrite(&(this_node_id), sizeof(uint32_t), r);
		debug("send node_id[%0X]", this_node_id);
    
	    ap_rwrite((void*)vd->docattr, sizeof(docattr_t), r);
    }

    timelog("send_result_finish");

	s->msg = qp_request.msg;
	sb_run_qp_finalize_search(&qp_request, &qp_response);
	timelog("qp_finalize");

	return SUCCESS;
}
static int preprocess_handler(request_rec *r, softbot_handler_rec *s)
{
    int i = 0;
    int num_of_node = 0;
    QueryNode qnodes[MAX_QUERY_NODES];
	char content_type[SHORT_STRING_SIZE+1];

	if(apr_table_get(s->parameters_in, "q") == NULL ||
			strlen(apr_table_get(s->parameters_in, "q")) == 0) {
	    MSG_RECORD(&s->msg, error, "Parameter 'q' is null or has zero length. query is null."
									" You have to input a valid query or use GET method instead of POST.");
        return FAIL;
	}

	ap_unescape_url((char *)apr_table_get(s->parameters_in, "q"));

    num_of_node = sb_run_preprocess(word_db, (char *)apr_table_get(s->parameters_in, "q"), 
                                    MAX_QUERY_STRING_SIZE, qnodes, MAX_QUERY_NODES);
        
	snprintf( content_type, SHORT_STRING_SIZE, "text/xml; charset=%s", default_charset);
	ap_set_content_type(r, content_type);
	ap_rprintf(r, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", default_charset);

	ap_rprintf(r, "<xml>\n");

    for ( i=0; i<num_of_node; i++) {
        if (qnodes[i].type == OPERAND) {
			ap_rprintf(r, 
                    "<node type=\"OPERAND\">\n"
					  "<word>\n" 
						"<string>%s</string>\n"
						"<id>%u</id>\n" 
					  "</word>\n"
					  "<field>%s</field>\n"
					  "<opParam>%d</opParam>\n" 
					  "<weight>%f</weight>\n" 
					  "<original_word>%s</original_word>\n"
                    "</node>\n",
                    qnodes[i].word_st.string,
                    qnodes[i].word_st.id,
                    sb_strbin(qnodes[i].field, sizeof(qnodes[i].field)),
                    qnodes[i].opParam,
					qnodes[i].weight,
					qnodes[i].original_word);
        }
        else {
			ap_rprintf(r, 
                    "<node type=\"OPERATOR\">\n"
					  "<operator>%s</operator>\n"
					  "<num_of_operands>%d</num_of_operands>\n"
					  "<opParam>%d</opParam>\n" 
					  "<weight>%f</weight>\n" 
					  "<original_word>%s</original_word>\n"
                    "</node>\n",
                    gOperatorNames[qnodes[i].operator],
                    qnodes[i].num_of_operands,
                    qnodes[i].opParam,
					qnodes[i].weight,
					qnodes[i].original_word);
        }
    }
	ap_rprintf(r, "</xml>\n");
    return SUCCESS;
}
static int search_handler(request_rec *r, softbot_handler_rec *s)
{
    int rv = 0;
    int i = 0, j = 0, cmt_idx = 0, deleted_cnt = 0;
	struct timeval tv;
	uint32_t start_time = 0, end_time = 0;
	char content_type[SHORT_STRING_SIZE+1];

    init_server(r, s);

	if ( print_elapsed_time ) {
		gettimeofday(&tv, NULL);
		start_time = tv.tv_sec*1000 + tv.tv_usec/1000;
	}

	msg_record_init(&s->msg);
	set_con_config(r->server);

	rv = sb_run_qp_init();
    if(rv != SUCCESS && rv != DECLINE) {
	    MSG_RECORD(&s->msg, error, "qp init failed");
        return FAIL;
    }

	if(apr_table_get(s->parameters_in, "q") == NULL ||
			strlen(apr_table_get(s->parameters_in, "q")) == 0) {
	    MSG_RECORD(&s->msg, error, "Parameter 'q' is null or has zero length. query is null."
									" You have to input a valid query or use GET method instead of POST.");
        return FAIL;
	}

	ap_unescape_url((char *)apr_table_get(s->parameters_in, "q"));

    rv = sb_run_qp_init_request(&qp_request, 
                                (char *)apr_table_get(s->parameters_in, "q"));
    if(rv != SUCCESS) {
        error("can not init request");
		s->msg = qp_request.msg;
        return FAIL;
    }

    rv = sb_run_qp_init_response(&qp_response);
    if(rv != SUCCESS) {
        error("can not init request");
        return FAIL;
    }

	//2. get result
	timelog("full_search_start");
	rv = sb_run_qp_full_search(&qp_request, &qp_response);
	timelog("full_search_finish");
	if (rv != SUCCESS) {
		error("sb_run_qp_full_search failed: query[%s]", qp_request.query);
		s->msg = qp_request.msg;
		return FAIL;
	}

    if ( qp_request.is_delete ) {
        int i = 0;
        int j = 0;
        int is_recovery = 0;

        if( qp_request.select_list.cnt > 0 &&
            qp_request.select_list.field[0].name[0] == '0' ) {

            info("recovery deleted document");
            is_recovery = 1;
        }

		for(i = 0; i < qp_response.vdl->cnt; i++) {
			for(j = 0; j < qp_response.vdl->data[i].dochit_cnt; j++) {
				int rv = 0;
				uint32_t docid = qp_response.vdl->data[i].dochits[j].id;
				docattr_t* docattr = NULL;

				debug("delete docid[%u]", docid);

				rv = sb_run_docattr_ptr_get(docid, &docattr);
				if ( rv < 0 ) {
					error("cannot get docattr of docid[%u]", docid);
					continue;
				}

                if( is_recovery ) {
				    rv = sb_run_docattr_set_docattr_function(docattr, "Delete", "0");
                } else {
				    rv = sb_run_docattr_set_docattr_function(docattr, "Delete", "1");
                }

				if ( rv < 0 ) {
					error("cannot delete docid[%u]", docid);
					continue;
				}

                deleted_cnt++;
			}
        }
	}

	if ( print_elapsed_time ) {
		gettimeofday(&tv, NULL);
		end_time = tv.tv_sec*1000 + tv.tv_usec/1000;
	}

	timelog("send_result_start");

	snprintf( content_type, SHORT_STRING_SIZE, "text/xml; charset=%s", default_charset);
	ap_set_content_type(r, content_type);
	ap_rprintf(r, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", default_charset);

	ap_rprintf(r, 
			"<xml>\n"
			"<status>1</status>\n" 
			"<query><![CDATA[%s]]></query>\n"
			"<parsed_query><![CDATA[%s]]></parsed_query>\n"
			"<result_count>%d</result_count>\n", 
			qp_request.query, 
			qp_response.parsed_query,
            qp_response.search_result);

    if ( qp_request.is_delete ) {
	    ap_rprintf(r, 
	            "<deleted_count>%d</deleted_count>\n", 
                deleted_cnt);
    }

	if(server_id[0] == '\0') {
	    ap_rprintf(r, "<server_id><![CDATA[%s]]></server_id>\n", get_ipaddress(r->pool));
	} else {
	    ap_rprintf(r, "<server_id><![CDATA[%s]]></server_id>\n", server_id);
	}

	/* elapsed time */
	if ( print_elapsed_time ) {
		ap_rprintf(r, "<elapsed_time>%u</elapsed_time>\n", end_time - start_time);
	}

    /* group result */
    ap_rprintf(r, "<groups count=\"%d\">\n", qp_response.groupby_result_vid.rules.cnt);
	print_group(r, &qp_response.groupby_result_vid);
    ap_rprintf(r, "</groups>\n");

	/*
    ap_rprintf(r, "<groups type=\"did\">\n");
	print_group(r, &qp_response.groupby_result_did);
    ap_rprintf(r, "</groups>\n");
	*/

    if( qp_request.is_delete ) {

    } else {
		/* each result */
		ap_rprintf(r, "<vdocs count=\"%d\">\n", qp_response.vdl->cnt);
		for(i = 0; i < qp_response.vdl->cnt; i++) {
			virtual_document_t* vd = (virtual_document_t*)&qp_response.vdl->data[i];

			ap_rprintf(r, "<vdoc vid=\"%d\" node_id=\"%0X\" relevance=\"%d\">\n", 
						  vd->id, vd->node_id, vd->relevance);
			ap_rprintf(r, "<docs count=\"%d\">\n", vd->comment_cnt);

			for(j = 0; j < vd->comment_cnt; j++) {
				comment_t* cmt = &qp_response.comments[cmt_idx++];
				ap_rprintf(r, "<doc doc_id=\"%d\">\n", cmt->did);

				if(qp_request.output_style == STYLE_XML) {
					ap_rprintf(r, "%s\n", cmt->s);
				} else {
					ap_rprintf(r, "<![CDATA[%s]]>\n", cmt->s);
				}
				ap_rprintf(r, "</doc>\n");
			}

			ap_rprintf(r, "</docs>\n");
			ap_rprintf(r, "</vdoc>\n");
		}
		ap_rprintf(r, "</vdocs>\n");
    }

	ap_rprintf(r, "</xml>\n");

	timelog("send_result_finish");

	s->msg = qp_request.msg;

	sb_run_qp_finalize_search(&qp_request, &qp_response);
	timelog("qp_finalize");

	return SUCCESS;
}
static int check_auth_cookie(request_rec *r)
{

	const char *cookies = NULL, *auth_line = NULL;
	char *cookie = NULL;

    /* Debug. */
	/*ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
	    "check_auth_cookie called");*/

	/* Get config for this directory. */
    cookie_auth_config_rec *conf = ap_get_module_config(r->per_dir_config,
		&auth_cookie_module);

    /* Check we have been configured. */
    if (!conf->cookie_auth_cookie) {
        return DECLINED;
    }

	/* Do not override real auth header, unless config instructs us to. */
	if (!conf->cookie_auth_override &&
		apr_table_get(r->headers_in, "Authorization")) {
		if (conf->cookie_auth_env) {
			unsetenv(conf->cookie_auth_env);
		}
		return DECLINED;
	}

	/* todo: protect against xxxCookieNamexxx, regex? */
	/* todo: make case insensitive? */
	/* Get the cookie (code from mod_log_config). */
	if ((cookies = apr_table_get(r->headers_in, "Cookie"))) {
		char *start_cookie, *end_cookie;
		if ((start_cookie = ap_strstr_c(cookies, conf->cookie_auth_cookie))) {
		    start_cookie += strlen(conf->cookie_auth_cookie) + 1;
		    cookie = apr_pstrdup(r->pool, start_cookie);
			/* kill everything in cookie after ';' */
			end_cookie = strchr(cookie, ';');
			if (end_cookie) {
				*end_cookie = '\0';
      }
      ap_unescape_url(cookie);
		}
	}

	/* No cookie? Nothing for us to do. */
	if (!cookie) {
                if (conf->cookie_auth_unauth_redirect) {
        	        const char* redirect = conf->cookie_auth_unauth_redirect;
        		compose_and_set_redirect(r, redirect);
                        return HTTP_MOVED_TEMPORARILY;
                }
                else {
			return DECLINED;
                }
	}

	/* Debug. */
	/*ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
	    "%s=%s", conf->cookie_auth_cookie, cookie);*/

	char* aux_auth_info = "";

	/* Construct the fake auth_line. */
	if (conf->cookie_auth_base64) {
		char* decoded_cookie = apr_palloc(r->pool, apr_base64_decode_len(cookie));
    int decoded_cookie_length = apr_base64_decode(decoded_cookie, cookie);

		int valid = 1;

		/* if the cookie is encrypted, decrypt it in place */
		if (conf->cookie_auth_encrypt) {
      MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
      int keysize = strlen(conf->cookie_auth_encrypt);
      int blocksize = mcrypt_enc_get_block_size(td);

			// We will copy the iv from the beginning of the cookie.
			// The iv does not need to be null-terminated, but we will
			// null-terminate it for convenience.
			int iv_length = mcrypt_enc_get_iv_size(td);
			char* iv = (char*) apr_palloc(r->pool, iv_length + 1);
			memcpy(iv, decoded_cookie, iv_length);
			iv[iv_length] = '\0';

			// Take the iv off the beginning of the cookie
			decoded_cookie += iv_length;
      decoded_cookie_length -= iv_length;

      mcrypt_generic_init( td, conf->cookie_auth_encrypt, keysize, iv);
      // Encryption in CBC is performed in blocks, so our
      // decryption string will always be an integral number
      // of full blocks.
      char* decrypt_ptr = decoded_cookie;
      while (decoded_cookie_length >= blocksize) {
        mdecrypt_generic(td, decrypt_ptr, blocksize);
        decrypt_ptr += blocksize;
        decoded_cookie_length -= blocksize;
      }
      if (decoded_cookie_length != 0) {
        valid = 0;
      }
      mcrypt_generic_deinit (td);
      mcrypt_module_close(td);
      /*ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
        "mdecrypt(%s)=%s", conf->cookie_auth_cookie, decoded_cookie);*/
		}

		/* if the cookie did not decrypt, then do nothing */
		if (valid) {
			char* end_auth_info = strchr(decoded_cookie, '\t');

			if (end_auth_info) {
				aux_auth_info = decoded_cookie;
				char* unencoded_cookie = end_auth_info + 1;
				*end_auth_info = 0;

				auth_line = apr_pstrcat(r->pool, "Basic ", ap_pbase64encode(r->pool, unencoded_cookie), NULL);
			}
			else {
				auth_line = apr_pstrcat(r->pool, "Basic ", ap_pbase64encode(r->pool, decoded_cookie), NULL);
			}
		}
	} else {
		// Aux auth info and cookie encrypt features only available in base64 mode
		ap_unescape_url(cookie);
		auth_line = apr_pstrcat(r->pool, "Basic ",
			ap_pbase64encode(r->pool, cookie), NULL);
	}

	/* If there is aux auth info, then set the env variable */
	if (conf->cookie_auth_env) {
	  apr_table_set(r->subprocess_env, conf->cookie_auth_env, aux_auth_info);
	}

	/* Debug. */
	/*ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
		"Authorization: %s", auth_line);*/

	/* If there is no aux auth info, then force a redirect if our conf directives say that we should */
        if (conf->cookie_auth_env_redirect && !strlen(aux_auth_info)) {
        	const char* redirect = conf->cookie_auth_env_redirect;
        	compose_and_set_redirect(r, redirect);
                return HTTP_MOVED_TEMPORARILY;
        }
        else {
	        /* Set fake auth_line. */
		if (auth_line) {
                	apr_table_set(r->headers_in, "Authorization", auth_line);
                }
	}

	/* Always return DECLINED because we don't authorize, */
	/* we just set things up for the next auth module to. */
    return DECLINED;
}
Exemple #19
0
static PyObject *parse_qsl(PyObject *self, PyObject *args)
{

    PyObject *pairs;
    int i, len;
    PyObject *qso;
    char unicode = 0;
    char *qs = NULL;
    int keep_blank_values = 0;
    int strict_parsing = 0; /* XXX not implemented */

    if (! PyArg_ParseTuple(args, "O|ii", &qso, &keep_blank_values,
                           &strict_parsing))
        return NULL; /* error */

    if (PyUnicode_Check(qso))
        unicode = 1;

    MP_ANYSTR_AS_STR(qs, qso, 1);
    if (!qs) {
        Py_DECREF(qso); /* MP_ANYSTR_AS_STR */
        return NULL;
    }

    /* split query string by '&' and ';' into a list of pairs */
    pairs = PyList_New(0);
    if (pairs == NULL) {
        Py_DECREF(qso); /* MP_ANYSTR_AS_STR */
        return NULL;
    }

    i = 0;
    len = strlen(qs);

    while (i < len) {

        PyObject *pair, *key, *val;
        char *cpair, *ckey, *cval;
        int plen, j, p, k, v;

        pair = PyBytes_FromStringAndSize(NULL, len);
        if (pair == NULL)
            return NULL;

        /* split by '&' or ';' */
        cpair = PyBytes_AS_STRING(pair);
        j = 0;
        while ((qs[i] != '&') && (qs[i] != ';') && (i < len)) {
            /* replace '+' with ' ' */
            cpair[j] = (qs[i] == '+') ? ' ' : qs[i];
            i++;
            j++;
        }

        if (j == 0) {
            Py_XDECREF(pair);
            i++;
            continue;
        }

        cpair[j] = '\0';
        _PyBytes_Resize(&pair, j);
        cpair = PyBytes_AS_STRING(pair);

        /* split the "abc=def" pair */
        plen = strlen(cpair);

        key = PyBytes_FromStringAndSize(NULL, plen);
        if (key == NULL) {
            Py_DECREF(qso); /* MP_ANYSTR_AS_STR */
            return NULL;
        }

        val = PyBytes_FromStringAndSize(NULL, plen);
        if (val == NULL) {
            Py_DECREF(qso); /* MP_ANYSTR_AS_STR */
            return NULL;
        }

        ckey = PyBytes_AS_STRING(key);
        cval = PyBytes_AS_STRING(val);

        p = 0;
        k = 0;
        v = 0;
        while (p < plen) {
            if (cpair[p] != '=') {
                ckey[k] = cpair[p];
                k++;
                p++;
            }
            else {
                p++;      /* skip '=' */
                while (p < plen) {
                    cval[v] = cpair[p];
                    v++;
                    p++;
                }
            }
        }
        ckey[k] = '\0';
        cval[v] = '\0';

        if (keep_blank_values || (v > 0)) {

            ap_unescape_url(ckey);
            ap_unescape_url(cval);

            _PyBytes_Resize(&key, strlen(ckey));
            _PyBytes_Resize(&val, strlen(cval));

            if (key && val) {
                PyObject *listitem = NULL;
                if (unicode) {
                    PyObject *ukey, *uval;
                    ukey = PyUnicode_DecodeLatin1(ckey, strlen(ckey), NULL);
                    uval = PyUnicode_DecodeLatin1(cval, strlen(cval), NULL);
                    listitem = Py_BuildValue("(O,O)", ukey, uval);
                    Py_DECREF(ukey);
                    Py_DECREF(uval);
                } else
                    listitem = Py_BuildValue("(O,O)", key, val);
                if(listitem) {
                    PyList_Append(pairs, listitem);
                    Py_DECREF(listitem);
                }
            }

        }
        Py_XDECREF(pair);
        Py_XDECREF(key);
        Py_XDECREF(val);
        i++;
    }

    Py_DECREF(qso);
    return pairs;
}
Exemple #20
0
static PyObject *parse_qs(PyObject *self, PyObject *args)
{

    PyObject *pairs, *dict;
    int i, n, len, lsize;
    char *qs;
    PyObject *qso;
    char unicode = 0;
    int keep_blank_values = 0;
    int strict_parsing = 0; /* XXX not implemented */

    if (! PyArg_ParseTuple(args, "O|ii", &qso, &keep_blank_values,
                           &strict_parsing))
        return NULL; /* error */

    if (PyUnicode_Check(qso))
        unicode = 1;

    MP_ANYSTR_AS_STR(qs, qso, 1);
    if (!qs) {
        Py_DECREF(qso); /* MP_ANYSTR_AS_STR */
        return NULL;
    }

    /* split query string by '&' and ';' into a list of pairs */
    pairs = PyList_New(0);
    if (pairs == NULL) {
        Py_DECREF(qso);
        return NULL;
    }

    i = 0;
    len = strlen(qs);

    while (i < len) {

        PyObject *pair;
        char *cpair;
        int j = 0;

        pair = PyBytes_FromStringAndSize(NULL, len);
        if (pair == NULL) {
            Py_DECREF(qso);
            return NULL;
        }

        /* split by '&' or ';' */
        cpair = PyBytes_AS_STRING(pair);
        while ((qs[i] != '&') && (qs[i] != ';') && (i < len)) {
            /* replace '+' with ' ' */
            cpair[j] = (qs[i] == '+') ? ' ' : qs[i];
            i++;
            j++;
        }

        if (j) {
            _PyBytes_Resize(&pair, j);
            if (pair)
                PyList_Append(pairs, pair);
        }

        Py_XDECREF(pair);
        i++;
    }

    Py_DECREF(qso); /* MP_ANYSTR_AS_STR */

    /*
     * now we have a list of "abc=def" string (pairs), let's split
     * them all by '=' and put them in a dictionary.
     */

    dict = PyDict_New();
    if (dict == NULL)
        return NULL;

    lsize = PyList_Size(pairs);
    n = 0;

    while (n < lsize) {

        PyObject *pair, *key, *val;
        char *cpair, *ckey, *cval;
        int k, v;

        pair = PyList_GET_ITEM(pairs, n);
        cpair = PyBytes_AS_STRING(pair);

        len = strlen(cpair);
        key = PyBytes_FromStringAndSize(NULL, len);
        if (key == NULL)
            return NULL;

        val = PyBytes_FromStringAndSize(NULL, len);
        if (val == NULL)
            return NULL;

        ckey = PyBytes_AS_STRING(key);
        cval = PyBytes_AS_STRING(val);

        i = 0;
        k = 0;
        v = 0;
        while (i < len) {
            if (cpair[i] != '=') {
                ckey[k] = cpair[i];
                k++;
                i++;
            }
            else {
                i++;      /* skip '=' */
                while (i < len) {
                    cval[v] = cpair[i];
                    v++;
                    i++;
                }
            }
        }

        ckey[k] = '\0';
        cval[v] = '\0';

        if (keep_blank_values || (v > 0)) {

            ap_unescape_url(ckey);
            ap_unescape_url(cval);

            _PyBytes_Resize(&key, strlen(ckey));
            _PyBytes_Resize(&val, strlen(cval));

            if (key && val) {

                ckey = PyBytes_AS_STRING(key);
                cval = PyBytes_AS_STRING(val);

                if (unicode) {
                    PyObject *list, *ukey, *uval;
                    ukey = PyUnicode_DecodeLatin1(ckey, strlen(ckey), NULL);
                    uval = PyUnicode_DecodeLatin1(ckey, strlen(cval), NULL);
                    list = PyDict_GetItem(dict, ukey);
                    if (list) {
                        PyList_Append(list, uval);
                        Py_DECREF(uval);
                    } else {
                        list = Py_BuildValue("[O]", uval);
                        PyDict_SetItem(dict, ukey, list);
                        Py_DECREF(ukey);
                        Py_DECREF(list);
                    }
                } else {
                    PyObject *list;
                    list = PyDict_GetItem(dict, key);
                    if (list)
                        PyList_Append(list, val);
                    else {
                        list = Py_BuildValue("[O]", val);
                        PyDict_SetItem(dict, key, list);
                        Py_DECREF(list);
                    }
                }
            }
        }

        Py_XDECREF(key);
        Py_XDECREF(val);

        n++;
    }

    Py_DECREF(pairs);
    return dict;
}
Exemple #21
0
static osrfStringArray* apacheParseParms(request_rec* r) {

	if( r == NULL ) return NULL;
	//ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "got a valid request_rec");

	char* arg = NULL;
	apr_pool_t *p = r->pool;	/* memory pool */
	growing_buffer* buffer = buffer_init(1025);

	/* gather the post args and append them to the url query string */
	if( !strcmp(r->method,"POST") ) {

		ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
		
		//osrfLogDebug(OSRF_LOG_MARK, "gateway reading post data..");
	    //ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "idlchunk reading post data..");

		if(ap_should_client_block(r)) {


			/* Start with url query string, if any */
			
			if(r->args && r->args[0])
				buffer_add(buffer, r->args);

			char body[1025];

			//osrfLogDebug(OSRF_LOG_MARK, "gateway client has post data, reading...");

			/* Append POST data */
			
			long bread;
			while( (bread = ap_get_client_block(r, body, sizeof(body) - 1)) ) {

				if(bread < 0) {
					//osrfLogInfo(OSRF_LOG_MARK, 
					//	"ap_get_client_block(): returned error, exiting POST reader");
					break;
				}

				body[bread] = '\0';
				buffer_add( buffer, body );

				//osrfLogDebug(OSRF_LOG_MARK, 
				//	"gateway read %ld bytes: %d bytes of data so far", bread, buffer->n_used);

				if(buffer->n_used > APACHE_TOOLS_MAX_POST_SIZE) {
					//osrfLogError(OSRF_LOG_MARK, "gateway received POST larger "
					//	"than %d bytes. dropping request", APACHE_TOOLS_MAX_POST_SIZE);
					buffer_free(buffer);
					return NULL;
				}
			}

			//osrfLogDebug(OSRF_LOG_MARK, "gateway done reading post data");
		}

	} else { /* GET */

        if(r->args && r->args[0])
            buffer_add(buffer, r->args);
	    //ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "idlchunk read GET data..");
    }


    if(buffer->n_used > 0)
        arg = apr_pstrdup(p, buffer->buf);
    else
        arg = NULL; 
    buffer_free(buffer);

	if( !arg || !arg[0] ) { /* we received no request */
		return NULL;
	}

	//osrfLogDebug(OSRF_LOG_MARK, "parsing URL params from post/get request data: %s", arg);
	//ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "parsing URL params from post/get request data: %s", arg);
	
	osrfStringArray* sarray		= osrfNewStringArray(12); /* method parameters */
	int sanity = 0;
	char* key					= NULL;	/* query item name */
	char* val					= NULL;	/* query item value */

	/* Parse the post/get request data into a series of name/value pairs.   */
	/* Load each name into an even-numbered slot of an osrfStringArray, and */
	/* the corresponding value into the following odd-numbered slot.        */

	while( arg && (val = ap_getword(p, (const char**) &arg, '&'))) {

		key = ap_getword(r->pool, (const char**) &val, '=');
		if(!key || !key[0])
			break;

		ap_unescape_url(key);
		ap_unescape_url(val);

		//osrfLogDebug(OSRF_LOG_MARK, "parsed URL params %s=%s", key, val);

		osrfStringArrayAdd(sarray, key);
		osrfStringArrayAdd(sarray, val);

		if( sanity++ > 1000 ) {
			//osrfLogError(OSRF_LOG_MARK, 
			//	"Parsing URL params failed sanity check: 1000 iterations");
			osrfStringArrayFree(sarray);
			return NULL;
		}

	}

	//osrfLogDebug(OSRF_LOG_MARK,
	//	"Apache tools parsed %d params key/values", sarray->size / 2 );

	return sarray;
}
static int abstract_search_handler(request_rec *r, softbot_handler_rec *s)
{
    int rv = 0;
    int i = 0;
	int recv_pos = 0;
    memfile *buf = NULL;
	virtual_document_t* vd = NULL;
    int max_doc_hits_size = 0;

    sb_run_qp_get_max_doc_hits_size( &max_doc_hits_size );

    init_server(r, s);

	set_con_config(r->server);
	msg_record_init(&s->msg);

	rv = sb_run_qp_init();
    if(rv != SUCCESS && rv != DECLINE) {
	    MSG_RECORD(&s->msg, error, "qp init failed");
        return FAIL;
    }

	if(apr_table_get(s->parameters_in, "q") == NULL ||
			strlen(apr_table_get(s->parameters_in, "q")) == 0) {
	    MSG_RECORD(&s->msg, error, "query is null, must use http get method");
        return FAIL;
	}

	ap_unescape_url((char *)apr_table_get(s->parameters_in, "q"));

    rv = sb_run_qp_init_request(&qp_request, 
                                (char *)apr_table_get(s->parameters_in, "q"));
    if(rv != SUCCESS) {
	    s->msg = qp_request.msg;
        error("can not init request");
        return FAIL;
    }

    rv = sb_run_qp_init_response(&qp_response);
    if(rv != SUCCESS) {
	    s->msg = qp_request.msg;
        error("can not init request");
        return FAIL;
    }

	/* 수신할 doc_hit 를 assign */
	qp_response.vdl->cnt = 1;
	vd = &(qp_response.vdl->data[0]);

	if(g_dochits_buffer == NULL) {
		g_dochits_buffer = (doc_hit_t*)sb_calloc(max_doc_hits_size, sizeof(doc_hit_t));
	}

    vd->dochits = g_dochits_buffer; 

	/* comment를 추출할 virtual document 정보 받기 */
	CHECK_REQUEST_CONTENT_TYPE(r, "x-softbotd/binary");

	if (sb_run_sbhandler_make_memfile(r, &buf) != SUCCESS) {
	    MSG_RECORD(&s->msg, error, "make_memfile_from_postdata failed");
        if(buf != NULL) memfile_free(buf);
		return FAIL;
	}

    vd->dochit_cnt = memfile_getSize(buf) / (sizeof(doc_hit_t) + sizeof(uint32_t));
    for (i = 0; i < vd->dochit_cnt; i++) {
		uint32_t node_id = 0;
		uint32_t recv_data_size = 0;

        recv_data_size = sizeof(doc_hit_t);
        if ( memfile_read(buf, (char*)&(vd->dochits[recv_pos]), recv_data_size)
                != recv_data_size ) {
			MSG_RECORD(&s->msg, error, "incomplete result at [%d]th node: doc_hits ", i);
            if(buf != NULL) memfile_free(buf);
            return FAIL;
        }

		// 2. node_id 수신
		recv_data_size = sizeof(uint32_t);
		if ( memfile_read(buf, (char*)&node_id, recv_data_size)
				!= recv_data_size ) {
			MSG_RECORD(&s->msg, error, "incomplete result at [%d]th node: node_id ", i);
            if(buf != NULL) memfile_free(buf);
			return FAIL;
		}

		// 자신의 node_id가 아니면 error
		if(get_node_id(node_id) != this_node_id) {
			MSG_RECORD(&s->msg, 
			              error, "node_id[%u] not equals this_node_id[%0X]",
						  get_node_id(node_id),
						  this_node_id);
            if(buf != NULL) memfile_free(buf);
			return FAIL;
		}

		debug("did[%u], node_id[%0X]", vd->dochits[recv_pos].id, node_id);

        // 자신의 node_id pop
        node_id = pop_node_id(node_id);
		recv_pos++;
    }
	vd->dochit_cnt = recv_pos;


	/* comment 추출 */
	timelog("sb_run_qp_abstract_search start");
	rv = sb_run_qp_abstract_search(&qp_request, &qp_response);
	timelog("sb_run_qp_abstract_search finish");
	if (rv != SUCCESS) {
	    s->msg = qp_request.msg;
		error("sb_run_qp_abstract_search failed: query[%s]", qp_request.query);
        if(buf != NULL) memfile_free(buf);
		return FAIL;
	}

    /////////// abstarct search 결과 전송 ////////////////////////////////////////
    ap_set_content_type(r, "x-softbotd/binary");

    // 1. 전송건수.
    ap_rwrite(&vd->comment_cnt, sizeof(uint32_t), r);
	
	// 2. doc_hits 전송.
    for (i = 0; i < vd->comment_cnt; i++ ) {
        // 2.1 doc_id 전송.
        ap_rwrite(&vd->dochits[i].id, sizeof(uint32_t), r);
        // 2.2 node_id 전송.
        ap_rwrite(&this_node_id, sizeof(uint32_t), r);
        // 2.3. comment
        ap_rwrite(qp_response.comments[i].s, LONG_LONG_STRING_SIZE, r);
		debug("comments[%s]", qp_response.comments[i].s);
    }

    // log를 위하여 setting 해준다.
    qp_response.search_result = vd->comment_cnt;

	s->msg = qp_request.msg;

    if(buf != NULL) memfile_free(buf);
	return SUCCESS;
}
Exemple #23
0
static PyObject *parse_qsl(PyObject *self, PyObject *args, PyObject *kw)
{

    PyObject *pairs;
    int i, len;
    char *qs;
    int keep_blank_values = 0;
    int strict_parsing = 0; /* XXX not implemented */
    char *keywords[] = { "qs", "keep_blank_values", "strict_parsing", 0 };
    
    if (! PyArg_ParseTupleAndKeywords(args, kw, "s|ii", keywords, &qs, &keep_blank_values, 
                           &strict_parsing)) 
        return NULL; /* error */

    /* split query string by '&' and ';' into a list of pairs */
    /* PYTHON 2.5: 'PyList_New' uses Py_ssize_t for input parameters */ 
    pairs = PyList_New(0);
    if (pairs == NULL)
        return NULL;

    i = 0;
    len = strlen(qs);

    while (i < len) {

        PyObject *pair, *key, *val;
        char *cpair, *ckey, *cval;
        int plen, j, p, k, v;

        /* PYTHON 2.5: 'PyString_FromStringAndSize' uses Py_ssize_t for input parameters */ 
        pair = PyString_FromStringAndSize(NULL, len);
        if (pair == NULL)
            return NULL;

        /* split by '&' or ';' */
        cpair = PyString_AS_STRING(pair);
        j = 0;
        while ((qs[i] != '&') && (qs[i] != ';') && (i < len)) {
            /* replace '+' with ' ' */
            cpair[j] = (qs[i] == '+') ? ' ' : qs[i];
            i++;
            j++;
        }

        if (j == 0) {
            Py_XDECREF(pair);
            i++;
            continue;
        }

        cpair[j] = '\0';
        /* PYTHON 2.5: '_PyString_Resize' uses Py_ssize_t for input parameters */ 
        _PyString_Resize(&pair, j);
        cpair = PyString_AS_STRING(pair);

        /* split the "abc=def" pair */
        plen = strlen(cpair);
        /* PYTHON 2.5: 'PyString_FromStringAndSize' uses Py_ssize_t for input parameters */ 
        key = PyString_FromStringAndSize(NULL, plen);
        if (key == NULL) 
            return NULL;
        /* PYTHON 2.5: 'PyString_FromStringAndSize' uses Py_ssize_t for input parameters */ 
        val = PyString_FromStringAndSize(NULL, plen);
        if (val == NULL) 
            return NULL;

        ckey = PyString_AS_STRING(key);
        cval = PyString_AS_STRING(val);

        p = 0;
        k = 0;
        v = 0;
        while (p < plen) {
            if (cpair[p] != '=') {
                ckey[k] = cpair[p];
                k++;
                p++;
            }
            else {
                p++;      /* skip '=' */
                while (p < plen) {
                    cval[v] = cpair[p];
                    v++;
                    p++;
                }
            }
        }
        ckey[k] = '\0';
        cval[v] = '\0';

        if (keep_blank_values || (v > 0)) {

            ap_unescape_url(ckey);
            ap_unescape_url(cval);

            /* PYTHON 2.5: '_PyString_Resize' uses Py_ssize_t for input parameters */
            _PyString_Resize(&key, strlen(ckey));
            /* PYTHON 2.5: '_PyString_Resize' uses Py_ssize_t for input parameters */
            _PyString_Resize(&val, strlen(cval));

            if (key && val) {
                PyObject* listitem = Py_BuildValue("(O,O)", key, val);
                if(listitem) {
                    PyList_Append(pairs, listitem);
                    Py_DECREF(listitem);
                }
            }

        }
        Py_XDECREF(pair);
        Py_XDECREF(key);
        Py_XDECREF(val);
        i++;
    }

    return pairs;
}
Exemple #24
0
/*
 * resolves the code received from the OP in to an access_token and id_token and returns the parsed contents
 */
apr_byte_t oidc_proto_resolve_code(request_rec *r, oidc_cfg *cfg,
		oidc_provider_t *provider, const char *code, char **s_idtoken,
		char **s_access_token, char **s_token_type) {

	ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
			"oidc_proto_resolve_code: entering");
	const char *response = NULL;

	/* assemble the parameters for a call to the token endpoint */
	apr_table_t *params = apr_table_make(r->pool, 5);
	apr_table_addn(params, "grant_type", "authorization_code");
	apr_table_addn(params, "code", code);
	apr_table_addn(params, "redirect_uri", cfg->redirect_uri);

	/* see if we need to do basic auth or auth-through-post-params (both applied through the HTTP POST method though) */
	const char *basic_auth = NULL;
	if ((apr_strnatcmp(provider->token_endpoint_auth, "client_secret_basic"))
			== 0) {
		basic_auth = apr_psprintf(r->pool, "%s:%s", provider->client_id,
				provider->client_secret);
	} else {
		apr_table_addn(params, "client_id", provider->client_id);
		apr_table_addn(params, "client_secret", provider->client_secret);
	}

	/* see if we've configured any extra static parameters to the token endpoint */
	if (provider->token_endpoint_params != NULL) {
		const char *key, *val;
		const char *p = provider->token_endpoint_params;
		while (*p && (val = ap_getword(r->pool, &p, '&'))) {
			key = ap_getword(r->pool, &val, '=');
			ap_unescape_url((char *) key);
			ap_unescape_url((char *) val);
			apr_table_addn(params, key, val);
		}
	}

	/* resolve the code against the token endpoint */
	if (oidc_util_http_post_form(r, provider->token_endpoint_url, params,
			basic_auth, NULL, provider->ssl_validate_server, &response,
			cfg->http_timeout_long, cfg->outgoing_proxy) == FALSE) {
		ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
				"oidc_proto_resolve_code: could not successfully resolve the \"code\" (%s) against the token endpoint (%s)",
				code, provider->token_endpoint_url);
		return FALSE;
	}

	/* check for errors, the response itself will have been logged already */
	json_t *result = NULL;
	if (oidc_util_decode_json_and_check_error(r, response, &result) == FALSE)
		return FALSE;

	/* get the access_token from the parsed response */
	json_t *access_token = json_object_get(result, "access_token");
	if ((access_token != NULL) && (json_is_string(access_token))) {

		*s_access_token = apr_pstrdup(r->pool, json_string_value(access_token));

		/* log and set the obtained acces_token */
		ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
				"oidc_proto_resolve_code: returned access_token: %s",
				*s_access_token);

		/* the provider must return the token type */
		json_t *token_type = json_object_get(result, "token_type");
		if ((token_type == NULL) || (!json_is_string(token_type))) {
			ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
					"oidc_proto_resolve_code: response JSON object did not contain a token_type string");
			json_decref(result);
			return FALSE;
		}

		*s_token_type = apr_pstrdup(r->pool, json_string_value(token_type));

	} else {
		ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
				"oidc_proto_resolve_code: response JSON object did not contain an access_token string");
	}

	/* get the id_token from the response */
	json_t *id_token = json_object_get(result, "id_token");
	if ((id_token != NULL) && (json_is_string(id_token))) {
		*s_idtoken = apr_pstrdup(r->pool, json_string_value(id_token));

		/* log and set the obtained id_token */
		ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
				"oidc_proto_resolve_code: returned id_token: %s", *s_idtoken);
	}

	json_decref(result);

	return TRUE;
}
Exemple #25
0
static int handle_request(request_rec *r)
{
	tmcdreq_t tmcdreq, *reqp = &tmcdreq;
	tmcdresp_t *response = NULL;
	char *command;
	struct in_addr local_addr;
	struct in_addr remote_addr;
	struct sockaddr_in redir_client;
	int tmcd_status;
	int status = OK;
	char *status_line = NULL;
	char *args = NULL;
	char *function_args = NULL;
	char *p;
	char **argv = NULL;
	int argc, i;

	reqp->istcp = 1;
	reqp->isssl = 1; /* FIXME */

	if (strcmp(r->handler, "tmcd")) {
		status = DECLINED;
		goto err;
	}

#if 0
	r->allowed |= (AP_METHOD_BIT << M_GET);
	if (r->method_number != M_GET) {
		status = DECLINED;
		goto err;
	}
#endif

	memset(reqp, 0, sizeof(*reqp));

	local_addr = r->connection->local_addr.sin_addr;
	remote_addr = r->connection->remote_addr.sin_addr;

	reqp->version = 1; /* FIXME need sane default */
	tmcd_init(reqp, &local_addr, NULL);

	command = r->path_info;
	while (*command && *command == '/') {
		command++;
	}
	if (command[0] == '\0') {
		status = HTTP_BAD_REQUEST;
		goto err;
	}

	if (r->args) {
		args = malloc(strlen(r->args) + 1);
		if (args == NULL) {
			status = HTTP_INTERNAL_SERVER_ERROR;
			goto err;
		}

		strcpy(args, r->args);
		argv = make_argv(args, &argc, '&');
		if (argv == NULL) {
			status = HTTP_INTERNAL_SERVER_ERROR;
			goto err;
		}

		for (i = 0; i < argc; i++) {
			/* Unescape the arguments */
			p = args;
			while (*p) {
				if (*p == '+')
					*p = ' ';
				p++;
			}

			status = ap_unescape_url(args);
			if (status != OK) {
				goto err;
			}

			if (strncasecmp(argv[i], "version=", 8) == 0) {
				long version;
				char *end;
				version = strtol(argv[i] + 8, &end, 10);
				if (*end != '\0' || *(argv[i] + 8) == '\0') {
					status = HTTP_BAD_REQUEST;
					status_line = "Invalid Version";
					goto err;
				}

				reqp->version = version;
			} else if (strncasecmp(argv[i], "redirect=", 9) == 0) {
				if (inet_pton(AF_INET, argv[i] + 9,
				              &redir_client.sin_addr) <= 0) {
					status = HTTP_BAD_REQUEST;
					status_line = "Invalid IP Address";
					goto err;
				}
				/* FIXME info message */

				if (remote_addr.s_addr != local_addr.s_addr) {
					status = HTTP_FORBIDDEN;
					status_line = "Redirection Not Allowed";
					goto err;
				}

				remote_addr =
				    redir_client.sin_addr;

			} else if (strncasecmp(argv[i], "vnodeid=", 8) == 0) {
				if (strlen(argv[i] + 8) >=
				           sizeof(reqp->vnodeid)) {
					status = HTTP_BAD_REQUEST;
					status_line =
					    "Virtual Node ID Too Long";
					goto err;
				}
				reqp->isvnode = 1;
				strcpy(reqp->vnodeid, argv[i] + 8);
			} else if (strncasecmp(argv[i], "args=", 5) == 0) {
				function_args = argv[i] + 5;
			}
		}

	}

	/* FIXME handle wanodekey */
	if ((tmcd_status = iptonodeid(reqp, remote_addr, NULL))) {
		if (reqp->isvnode) {
			status_line = "Invalid Virtual Node";
		}
		else {
			status_line = "Invalid Node";
		}
		status = HTTP_NOT_FOUND;
		goto err;
	}

	if (reqp->tmcd_redirect[0]) {
		/* FIXME what if https should be used? */
		/* FIXME do I need to specify the args should be passed too? */
		char *uri = ap_psprintf(r->pool, "http://%s%s?%s", reqp->tmcd_redirect,
		                        r->uri, r->args);
		ap_table_setn(r->headers_out, "Location", uri);
		status = HTTP_MOVED_TEMPORARILY;
		goto done;
	}

	tmcd_status = tmcd_handle_request(reqp, &response, command,
	                                  function_args);

	if (tmcd_status == TMCD_STATUS_OK) {
		r->content_type = response->type;
		ap_set_content_length(r, response->length);
		/* FIXME doctype */
		ap_soft_timeout("tmcd response call trace", r);
		ap_send_http_header(r);
		ap_rprintf(r, "%s", response->data);
		ap_kill_timeout(r);
		status = OK;
		goto done;
	} else {
		switch(tmcd_status) {
			case TMCD_STATUS_UNKNOWN_COMMAND:
				status = HTTP_NOT_FOUND;
				status_line = "Unknown Command";
				break;
			case TMCD_STATUS_REQUIRES_ENCRYPTION:
				status = HTTP_FORBIDDEN;
				status_line = "SSL Required";
				break;
			case TMCD_STATUS_NODE_NOT_ALLOCATED:
				status = HTTP_FORBIDDEN;
				status_line = "Node Not Allocated";
				break;
			case TMCD_STATUS_COMMAND_FAILED:
				status = HTTP_INTERNAL_SERVER_ERROR;
				if (response && response->data) {
					status_line = response->data;
				}
				break;
			case TMCD_STATUS_MALLOC_FAILED:
				status = HTTP_INTERNAL_SERVER_ERROR;
				break;
		}

		goto err;
	}
err:
done:
	if (argv)
		free(argv);

	if (args)
		free(args);

	if (response)
		tmcd_free_response(response);

	if (status_line) {
		r->status_line = ap_psprintf(r->pool, "%3.3u %s", status,
		                             status_line);
	}
	return status;
}
/*
 *	ic_send_request()
 *	-----------------
 *	Send the client's page/form request to the Interchange server
 */
static int ic_send_request(request_rec *r,ic_conf_rec *conf_rec,BUFF *ic_buff)
{
	char **env,**e,*rp;
	int env_count,rc;
	char request_uri[MAX_STRING_LEN];
	char redirect_url[MAX_STRING_LEN];

	/*
	 *	send the Interchange-link arg parameter
	 *	(this is always empty for a CGI request)
	 */
	ap_hard_timeout("ic_send_request",r);
	if (ap_bputs("arg 0\n",ic_buff) < 0){
		ap_log_reason("error writing to Interchange",r->uri,r);
		return HTTP_INTERNAL_SERVER_ERROR;
	}
	ap_reset_timeout(r);

	/*
	 *	initialize the environment to send to Interchange
	 */
	ap_add_common_vars(r);
	ap_add_cgi_vars(r);
	env = ap_create_environment(r->pool,r->subprocess_env);

	/*
	 *	count the number of environment variables present
	 */
	for (e = env,env_count = 0; *e != NULL; e++,env_count++){
		if (strncmp(*e,"PATH_INFO=",10) == 0)
			env_count--;
	}
	env_count++;

	/*
	 *	send the environment variable count to Interchange
	 */
	if (ap_bprintf(ic_buff,"env %d\n",env_count) < 0){
		ap_log_reason("error writing to Interchange",r->uri,r);
		return HTTP_INTERNAL_SERVER_ERROR;
	}
	ap_reset_timeout(r);

	/*
	 *	ignore the PATH_INFO variable and fix the SCRIPT_NAME,
	 *	REQUEST_URI and REDIRECT_URL variable content
	 */
	request_uri[0] = '\0';
	redirect_url[0] = '\0';
	for (e = env; *e != NULL; e++){
		int len;
		char tmp[MAX_STRING_LEN];
		char *p = *e;

		if (strncmp(p,"PATH_INFO=",10) == 0)
			continue;
		if (strncmp(p,"REDIRECT_URL=",13) == 0){
			strncpy(redirect_url,p + 13,MAX_STRING_LEN - 14);
			continue;
		}
		if (strncmp(p,"REQUEST_URI=",12) == 0)
			strncpy(request_uri,p + 12,MAX_STRING_LEN - 13);
		else if (strncmp(p,"SCRIPT_NAME=",12) == 0){
			p = tmp;
			strcpy(p,"SCRIPT_NAME=");

			if (conf_rec->script_name[0])
				strcat(p,conf_rec->script_name);
			else{
				strcat(p,"/");
				strcat(p,conf_rec->location);
			}
		}
		len = strlen(p);
		if (len && ap_bprintf(ic_buff,"%d %s\n",len,p) < 0){
			ap_log_reason("error writing to Interchange",r->uri,r);
			return HTTP_INTERNAL_SERVER_ERROR;
		}
	}

	rp = request_uri;

	while (*rp == '/')
		rp++;

	/*
	 *	strip the location path from the request_uri string
	 *	unless the location is "/"
	 */
	if (conf_rec->location[0] != '\0'){
		if (strncmp(rp,conf_rec->location,conf_rec->location_len) == 0)
			rp += conf_rec->location_len;
	}else{
		if (rp != request_uri)
			rp--;
	}

	strncpy(request_uri,rp,MAX_STRING_LEN - 1);
	request_uri[MAX_STRING_LEN - 1] = '\0';

	for (rp = request_uri; *rp != '\0'; rp++){
		if (*rp == '?'){
			*rp = '\0';
			break;
		}
	}
	switch (ap_unescape_url(request_uri)){
	case BAD_REQUEST:
	case NOT_FOUND:
		ap_log_reason("Bad URI entities found",r->uri,r);
		return HTTP_INTERNAL_SERVER_ERROR;
	}

	/*
	 *	send the PATH_INFO variable as our "fixed" REQUEST_URI
	 */
	if (ap_bprintf(ic_buff,"%d PATH_INFO=%s\n",strlen(request_uri) + 10,request_uri) < 0){
		ap_log_reason("error writing to Interchange",r->uri,r);
		return HTTP_INTERNAL_SERVER_ERROR;
	}

	/*
	 *	check if we have a REDIRECT_URL
	 *	if so then give it the same "fixes" as PATH_INFO (REQUEST_URI)
	 */
	if (redirect_url[0] != '\0'){
		rp = redirect_url;

		while (*rp == '/')
			rp++;

		/*
		 *	strip the location path from the request_uri string
		 *	unless the location is "/"
		 */
		if (conf_rec->location[0] != '\0'){
			if (strncmp(rp,conf_rec->location,conf_rec->location_len) == 0)
				rp += conf_rec->location_len;
		}else{
			if (rp != redirect_url)
				rp--;
		}

		strncpy(redirect_url,rp,MAX_STRING_LEN - 1);
		redirect_url[MAX_STRING_LEN - 1] = '\0';

		for (rp = redirect_url; *rp != '\0'; rp++){
			if (*rp == '?'){
				*rp = '\0';
				break;
			}
		}
		switch (ap_unescape_url(redirect_url)){
		case BAD_REQUEST:
		case NOT_FOUND:
			ap_log_reason("Bad URI entities found",r->uri,r);
			return HTTP_INTERNAL_SERVER_ERROR;
		}

		if (ap_bprintf(ic_buff,"%d REDIRECT_URL=%s\n",strlen(redirect_url) + 13,redirect_url) < 0){
			ap_log_reason("error writing to Interchange",r->uri,r);
			return HTTP_INTERNAL_SERVER_ERROR;
		}
	}
	ap_reset_timeout(r);

	/*
	 *	send the request body, if any
	 */
	if (ap_should_client_block(r)){
		char buffer[MAX_STRING_LEN];
		int len_read;
		long length = r->remaining;

		if (ap_bprintf(ic_buff,"entity\n%ld ",length) < 0){
			ap_log_reason("error writing to Interchange",r->uri,r);
			return HTTP_INTERNAL_SERVER_ERROR;
		}

		/*
		 *	read a block of data from the client and send
		 *	it to the Interchange server, until there
		 *	is nothing more to read from the client
		 */
		while ((len_read = ap_get_client_block(r,buffer,sizeof(buffer))) > 0){
			ap_reset_timeout(r);

			if (ap_bwrite(ic_buff,buffer,len_read) != len_read){
				ap_log_reason("error writing client block to Interchange",r->uri,r);
				return HTTP_INTERNAL_SERVER_ERROR;
			}
			ap_reset_timeout(r);
		}
		if (len_read < 0){
			ap_log_reason("error reading block from client",r->uri,r);
			return HTTP_INTERNAL_SERVER_ERROR;
		}

		/*
		 *	send an end of line character to Interchange
		 */
		if (ap_bputc('\n',ic_buff) < 0){
			ap_log_reason("error writing to Interchange",r->uri,r);
			return HTTP_INTERNAL_SERVER_ERROR;
		}
	}

	/*
	 *	all data has been sent, so send the "end" marker
	 */
	ap_reset_timeout(r);
	if (ap_bputs("end\n",ic_buff) < 0){
		ap_log_reason("error writing the end marker to Interchange",r->uri,r);
		return HTTP_INTERNAL_SERVER_ERROR;
	}
	if (ap_bflush(ic_buff) < 0){
		ap_log_reason("error flushing data to Interchange",r->uri,r);
		return HTTP_INTERNAL_SERVER_ERROR;
	}

	ap_kill_timeout(r);
	return OK;
}
Exemple #27
0
static int verify_auth_token(cdn_conf *cfg, request_rec *r)
{
  char *last, *uri_base, *query_string, *vox_timestamp_decoded, *forwarded_list;
  const char *token, *vox_sig, *vox_timestamp, *ip;
  apr_table_t *params;
  struct tm ctime;
  long remote_east_of_utc, local_east_of_utc;
  time_t raw;
  apr_time_t vox_ts;

  /* URI must have '?' in it */
  if (!strchr(r->unparsed_uri, '?')) {
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                 "verify_auth_token: URI %s missing '?'",
                 r->unparsed_uri);
    return DECLINED;
  }

  /* The base URL of the request, without the query arguments. */
  uri_base = apr_strtok(r->unparsed_uri, "?", &last);
  uri_base = apr_pstrcat(r->pool, cfg->to_server, uri_base, NULL);

  /* All of the query string parameters */
  query_string = apr_strtok(NULL, "", &last);

  /* Convert the query string to a table */
  params = apr_table_make(r->pool, 1);
  qs_to_table(query_string, params, r->pool);

  /* Get vox_sig from the parameters */
  vox_sig = apr_table_get(params, "vox_sig");
  if (!vox_sig) {
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                 "verify_auth_token: vox_sig missing");
    return DECLINED;
  }

  /* Remove vox_sig from params so it can be regenerated */
  apr_table_unset(params, "vox_sig");

  /* Get vox_timestamp from the parameters */
  vox_timestamp = apr_table_get(params, "vox_timestamp");
  if (!vox_timestamp) {
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                 "verify_auth_token: vox_timestamp missing");
    return DECLINED;
  }

  /* Parse vox_timestamp, which must be in ISO 8601 format */
  memset(&ctime, 0, sizeof(struct tm));
  vox_timestamp_decoded = apr_pstrdup(r->pool, vox_timestamp);
  ap_unescape_url(vox_timestamp_decoded);
  strptime(vox_timestamp_decoded, "%FT%T%z", &ctime);
  remote_east_of_utc = ctime.tm_gmtoff; /* have to save because mktime overwrites */
  ctime.tm_isdst = -1; /* mktime needs to auto-determine DST */
  raw = mktime(&ctime);
  local_east_of_utc = ctime.tm_gmtoff;
  apr_time_ansi_put(&vox_ts, raw - remote_east_of_utc + local_east_of_utc);

  /* verify vox_timestamp is in the future; if not, authentication has failed */
  if (vox_ts < apr_time_now()) {
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                 "Authenticated URL %s is expired (expired %ld, now %ld, raw %ld, "
                 "remote_east_of_utc %ld, local_east_of_utc %ld)",
                 r->uri,
                 apr_time_sec(vox_ts),
                 apr_time_sec(apr_time_now()),
                 raw, remote_east_of_utc, local_east_of_utc);
    return DECLINED;
  }

  /* compute the correct auth token using the connection's remote IP */
  token = make_auth_token(r, r->connection->remote_ip, uri_base, params,
                          cfg->auth_key);

  ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server,
               "verify_auth_token: comparing vox_sig %s with token %s "
               "using remote_ip %s", vox_sig, token, r->connection->remote_ip);

  if (!strncasecmp(token, vox_sig, SHA1_STR_SIZE))
    return OK;

  /* if that IP didn't work, try every IP in the X-Forwarded-For header in order */
  forwarded_list = (char *)apr_table_get(r->headers_in, "X-Forwarded-For");
  if (forwarded_list && (forwarded_list = apr_pstrdup(r->pool, forwarded_list))) {
    last = NULL;
    if (!(ip = apr_strtok(forwarded_list, ", \t", &last)))
      return DECLINED;
    do {
      token = make_auth_token(r, ip, uri_base, params, cfg->auth_key);

      ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server,
                   "verify_auth_token: comparing vox_sig %s with token %s "
                   "using X-Forwarded-For ip %s", vox_sig, token, ip);

      if (!strncasecmp(token, vox_sig, SHA1_STR_SIZE))
        return OK;
    } while ((ip = apr_strtok(NULL, ", \t", &last)));
  }

  return DECLINED;
}
/* init_ext_filter_process: get the external filter process going
 * This is per-filter-instance (i.e., per-request) initialization.
 */
static apr_status_t init_ext_filter_process(ap_filter_t *f)
{
    ef_ctx_t *ctx = f->ctx;
    apr_status_t rc;
    ef_dir_t *dc = ctx->dc;
    const char * const *env;

    ctx->proc = apr_pcalloc(ctx->p, sizeof(*ctx->proc));

    rc = apr_procattr_create(&ctx->procattr, ctx->p);
    ap_assert(rc == APR_SUCCESS);

    rc = apr_procattr_io_set(ctx->procattr,
                            APR_CHILD_BLOCK,
                            APR_CHILD_BLOCK,
                            APR_CHILD_BLOCK);
    ap_assert(rc == APR_SUCCESS);

    rc = set_resource_limits(f->r, ctx->procattr);
    ap_assert(rc == APR_SUCCESS);

    if (dc->log_stderr > 0) {
        rc = apr_procattr_child_err_set(ctx->procattr,
                                      f->r->server->error_log, /* stderr in child */
                                      NULL);
        ap_assert(rc == APR_SUCCESS);
    }

    rc = apr_procattr_child_errfn_set(ctx->procattr, child_errfn);
    ap_assert(rc == APR_SUCCESS);
    apr_pool_userdata_set(f->r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ctx->p);

    rc = apr_procattr_error_check_set(ctx->procattr, 1);
    if (rc != APR_SUCCESS) {
        return rc;
    }

    /* add standard CGI variables as well as DOCUMENT_URI, DOCUMENT_PATH_INFO,
     * and QUERY_STRING_UNESCAPED
     */
    ap_add_cgi_vars(f->r);
    ap_add_common_vars(f->r);
    apr_table_setn(f->r->subprocess_env, "DOCUMENT_URI", f->r->uri);
    apr_table_setn(f->r->subprocess_env, "DOCUMENT_PATH_INFO", f->r->path_info);
    if (f->r->args) {
            /* QUERY_STRING is added by ap_add_cgi_vars */
        char *arg_copy = apr_pstrdup(f->r->pool, f->r->args);
        ap_unescape_url(arg_copy);
        apr_table_setn(f->r->subprocess_env, "QUERY_STRING_UNESCAPED",
                       ap_escape_shell_cmd(f->r->pool, arg_copy));
    }

    env = (const char * const *) ap_create_environment(ctx->p,
                                                       f->r->subprocess_env);

    rc = apr_proc_create(ctx->proc,
                            ctx->filter->command,
                            (const char * const *)ctx->filter->args,
                            env, /* environment */
                            ctx->procattr,
                            ctx->p);
    if (rc != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, f->r,
                      "couldn't create child process to run `%s'",
                      ctx->filter->command);
        return rc;
    }

    apr_pool_note_subprocess(ctx->p, ctx->proc, APR_KILL_AFTER_TIMEOUT);

    /* We don't want the handle to the child's stdin inherited by any
     * other processes created by httpd.  Otherwise, when we close our
     * handle, the child won't see EOF because another handle will still
     * be open.
     */

    apr_pool_cleanup_register(ctx->p, ctx->proc->in,
                         apr_pool_cleanup_null, /* other mechanism */
                         ef_close_file);

#if APR_FILES_AS_SOCKETS
    {
        apr_pollfd_t pfd = { 0 };

        rc = apr_pollset_create(&ctx->pollset, 2, ctx->p, 0);
        ap_assert(rc == APR_SUCCESS);

        pfd.p         = ctx->p;
        pfd.desc_type = APR_POLL_FILE;
        pfd.reqevents = APR_POLLOUT;
        pfd.desc.f    = ctx->proc->in;
        rc = apr_pollset_add(ctx->pollset, &pfd);
        ap_assert(rc == APR_SUCCESS);

        pfd.reqevents = APR_POLLIN;
        pfd.desc.f    = ctx->proc->out;
        rc = apr_pollset_add(ctx->pollset, &pfd);
        ap_assert(rc == APR_SUCCESS);
    }
#endif

    return APR_SUCCESS;
}
int spep::apache::RequestHandler::handleRequestInner( request_rec *req )
{
	if( !this->_spep->isStarted() )
	{
		return HTTP_SERVICE_UNAVAILABLE;
	}
	
	spep::SPEPConfigData *spepConfigData = this->_spep->getSPEPConfigData();
	
	char *properURI = apr_pstrdup( req->pool, req->parsed_uri.path );
	if( req->parsed_uri.query != NULL )
	{
		properURI = apr_psprintf( req->pool, "%s?%s", properURI, req->parsed_uri.query );
	}
	
	ap_unescape_url( properURI );
	
	Cookies cookies( req );
	std::vector<std::string> cookieValues;
	cookies.getCookieValuesByName( cookieValues, spepConfigData->getTokenName() );
	if( !cookieValues.empty() )
	{
		std::string sessionID;
		spep::PrincipalSession principalSession;
		bool validSession = false;

		// SPEP cookie was found, validate using one of the values and use that to proceed.
		for (std::vector<std::string>::iterator cookieValueIterator = cookieValues.begin();
			cookieValueIterator != cookieValues.end(); ++cookieValueIterator) {

			sessionID = *cookieValueIterator;
			try {
				principalSession = this->_spep->getAuthnProcessor()->verifySession( sessionID );
				validSession = true;
				break;
			} catch( std::exception& e ) {
			}
		}
		
		if( validSession )
		{
			// If attribute querying is not disabled...
			if( !this->_spep->getSPEPConfigData()->disableAttributeQuery() )
			{
				// Put attributes into the environment.
				
				std::string usernameAttribute = spepConfigData->getUsernameAttribute();
				
				std::string attributeValueSeparator = spepConfigData->getAttributeValueSeparator();
				std::string attributeNamePrefix = spepConfigData->getAttributeNamePrefix();
				for( spep::PrincipalSession::AttributeMapType::iterator attributeIterator = principalSession.getAttributeMap().begin();
					attributeIterator != principalSession.getAttributeMap().end();
					++attributeIterator )
				{
					
					std::string name = spep::UnicodeStringConversion::toString( attributeIterator->first );
					std::string envName = attributeNamePrefix + name;
					
					std::stringstream valueStream;
					bool first = true;
					for( std::vector<UnicodeString>::iterator attributeValueIterator = attributeIterator->second.begin(); 
						attributeValueIterator != attributeIterator->second.end(); 
						++attributeValueIterator )
					{
						std::string value = spep::UnicodeStringConversion::toString( *attributeValueIterator );
						
						if( first )
						{
							valueStream << value;
							first = false;
						}
						else
						{
							valueStream << attributeValueSeparator << value;
						}
					}
					
					std::string envValue = valueStream.str();
					
					// Insert the attribute name/value pair into the subprocess environment.
					apr_table_set( req->subprocess_env, envName.c_str(), envValue.c_str() );
					
					if( name.compare( usernameAttribute ) == 0 )
					{
#ifndef APACHE1
						req->user = apr_pstrdup( req->pool, envValue.c_str() );
#else
						req->connection->user = apr_pstrdup( req->pool, envValue.c_str() );
#endif
					}
				}
			}
			
			if( this->_spep->getSPEPConfigData()->disablePolicyEnforcement() )
			{
				// No need to perform authorization, just let them in.
				return DECLINED;
			}
			
			// Perform authorization on the URI requested.
			spep::PolicyEnforcementProcessorData pepData;
			pepData.setESOESessionID( principalSession.getESOESessionID() );
			pepData.setResource( properURI );
			
			this->_spep->getPolicyEnforcementProcessor()->makeAuthzDecision( pepData );
			spep::Decision authzDecision( pepData.getDecision() );
			
			validSession = false;
			try
			{
				principalSession = this->_spep->getAuthnProcessor()->verifySession( sessionID );
				validSession = true;
			}
			catch( std::exception& e )
			{
			}
			
			if( validSession )
			{
				if( authzDecision == spep::Decision::PERMIT )
				{
					return DECLINED;
				}
				else if( authzDecision == spep::Decision::DENY )
				{
					return HTTP_FORBIDDEN;
				}
				else if( authzDecision == spep::Decision::ERROR )
				{
					return HTTP_INTERNAL_SERVER_ERROR;
				}
				else
				{
					return HTTP_INTERNAL_SERVER_ERROR;
				}
			}
		}
	}
	
	// If we get to this stage, the session has not been authenticated. We proceed to clear the
	// cookies configured by the SPEP to be cleared upon logout, since this is potentially the
	// first time they have come back to the SPEP since logging out.
	
	bool requireSend = false;
	const std::vector<std::string>& logoutClearCookies = this->_spep->getSPEPConfigData()->getLogoutClearCookies();
	for( std::vector<std::string>::const_iterator logoutClearCookieIterator = logoutClearCookies.begin();
		logoutClearCookieIterator != logoutClearCookies.end();
		++logoutClearCookieIterator )
	{
		// Throw the configured string into a stringstream
		std::stringstream ss( *logoutClearCookieIterator );
		
		// Split into name, domain, path. Doc says that stringstream operator>> won't throw
		std::string cookieNameString, cookieDomainString, cookiePathString;
		ss >> cookieNameString >> cookieDomainString >> cookiePathString;

		// Default to NULL, and then check if they were specified
		const char *cookieName = NULL, *cookieDomain = NULL, *cookiePath = NULL;
		// No cookie name, no clear.
		if( cookieNameString.length() == 0 )
		{
			continue;
		}
		
		// If the user sent this cookie.
		Cookies cookies( req );
		std::vector<std::string> cookieValues;
		cookies.getCookieValuesByName( cookieValues, spepConfigData->getTokenName() );
		if( !cookieValues.empty() ) {
			cookieName = cookieNameString.c_str();
			
			if( cookieDomainString.length() > 0 )
			{
				cookieDomain = cookieDomainString.c_str();
			}
			
			if( cookiePathString.length() > 0 )
			{
				cookiePath = cookiePathString.c_str();
			}
			
			// Set the cookie to an empty value.
			cookies.addCookie( req, cookieName, "", cookiePath, cookieDomain, false );
			
			// Flag that we need to send the cookies, because we have set at least one.
			requireSend = true;
		}
	}
	
	if( requireSend )
	{
		cookies.sendCookies( req );
	}
	
	// Lazy init code.
	if( spepConfigData->isLazyInit() )
	{
		
		std::string globalESOECookieName( spepConfigData->getGlobalESOECookieName() );
		Cookies cookies( req );
		std::vector<std::string> cookieValues;
		cookies.getCookieValuesByName( cookieValues, globalESOECookieName );
		if( cookieValues.empty() ) {
			bool matchedLazyInitResource = false;
			UnicodeString properURIUnicode( spep::UnicodeStringConversion::toUnicodeString( properURI ) );
			
			std::vector<UnicodeString>::const_iterator lazyInitResourceIterator;
			for( lazyInitResourceIterator = spepConfigData->getLazyInitResources().begin();
				lazyInitResourceIterator != spepConfigData->getLazyInitResources().end();
				++lazyInitResourceIterator )
			{
				// TODO Opportunity for caching of compiled regex patterns is here.
				UParseError parseError;
				UErrorCode errorCode = U_ZERO_ERROR;
				// Perform the regular expression matching here.
				UBool result = RegexPattern::matches( *lazyInitResourceIterator, properURIUnicode, parseError, errorCode );
				
				if ( U_FAILURE( errorCode ) )
				{
					// TODO throw u_errorName( errorCode )
					return HTTP_INTERNAL_SERVER_ERROR;
				}
				
				// FALSE is defined by ICU. This line for portability.
				if (result != FALSE)
				{
					matchedLazyInitResource = true;
					break;
				}
			}
			
			if( matchedLazyInitResource )
			{
				if( !spepConfigData->isLazyInitDefaultPermit() )
				{
					return DECLINED;
				}
			}
			else
			{
				if( spepConfigData->isLazyInitDefaultPermit() )
				{
					return DECLINED;
				}
			}
		}
	}
	
	boost::posix_time::ptime epoch( boost::gregorian::date( 1970, 1, 1 ) );
	boost::posix_time::time_duration timestamp = boost::posix_time::microsec_clock::local_time() - epoch;
	boost::posix_time::time_duration::tick_type currentTimeMillis = timestamp.total_milliseconds();
	
	apr_uri_t *uri = static_cast<apr_uri_t*>( apr_pcalloc( req->pool, sizeof(apr_uri_t) ) );
	apr_uri_parse( req->pool, this->_spep->getSPEPConfigData()->getServiceHost().c_str(), uri );
	
	const char *hostname = apr_table_get( req->headers_in, "Host" );
	if( hostname == NULL )
	{
		hostname = req->server->server_hostname;
	}
	
	const char *format = NULL;
	const char *base64RequestURI = NULL;
	// If we can't determine our own hostname, just fall through to the service host.
	// If the service host was requested obviously we want that.
	if( hostname == NULL || std::strcmp( uri->hostinfo, hostname ) == 0 )
	{
		// Join the service hostname and requested URI to form the return URL
		char *returnURL = apr_psprintf( req->pool, "%s%s", 
				this->_spep->getSPEPConfigData()->getServiceHost().c_str(), req->unparsed_uri );
		
		// Base64 encode this so that the HTTP redirect doesn't corrupt it.
		base64RequestURI = ap_pbase64encode( req->pool, returnURL );
		
		// Create the format string for building the redirect URL.
		format = apr_psprintf( req->pool, "%s%s", this->_spep->getSPEPConfigData()->getServiceHost().c_str(), 
					this->_spep->getSPEPConfigData()->getSSORedirect().c_str() );
	}
	else
	{
		base64RequestURI = ap_pbase64encode( req->pool, req->unparsed_uri );
		// getSSORedirect() will only give us a temporary.. dup it into the pool so we don't lose it when we leave this scope.
		format = apr_pstrdup( req->pool, this->_spep->getSPEPConfigData()->getSSORedirect().c_str() );
	}
	
	char *redirectURL = apr_psprintf( req->pool, format, base64RequestURI );
	
	std::stringstream timestampParameter;
	if( strchr( redirectURL, '?' ) != NULL )
	{
		// Query string already exists.. append the timestamp as another parameter
		timestampParameter << "&ts=" << currentTimeMillis;
		redirectURL = apr_psprintf( req->pool, "%s%s", redirectURL, timestampParameter.str().c_str() );
	}
	else
	{
		// No query string. Add one with the timestamp as a parameter.
		timestampParameter << "?ts=" << currentTimeMillis;
		redirectURL = apr_psprintf( req->pool, "%s%s", redirectURL, timestampParameter.str().c_str() );
	}
	
	apr_table_setn( req->headers_out, "Location", redirectURL );
	return HTTP_MOVED_TEMPORARILY;
	
}
Exemple #30
0
/* Manages the loadfactors and member status
 */
static int balancer_handler(request_rec *r)
{
    void *sconf = r->server->module_config;
    proxy_server_conf *conf = (proxy_server_conf *)
        ap_get_module_config(sconf, &proxy_module);
    proxy_balancer *balancer, *bsel = NULL;
    proxy_worker *worker, *wsel = NULL;
    apr_table_t *params = apr_table_make(r->pool, 10);
    int access_status;
    int i, n;
    const char *name;

    /* is this for us? */
    if (strcmp(r->handler, "balancer-manager"))
        return DECLINED;
    r->allowed = (AP_METHOD_BIT << M_GET);
    if (r->method_number != M_GET)
        return DECLINED;

    if (r->args) {
        char *args = apr_pstrdup(r->pool, r->args);
        char *tok, *val;
        while (args && *args) {
            if ((val = ap_strchr(args, '='))) {
                *val++ = '\0';
                if ((tok = ap_strchr(val, '&')))
                    *tok++ = '\0';
                /*
                 * Special case: workers are allowed path information
                 */
                if ((access_status = ap_unescape_url(val)) != OK)
                    if (strcmp(args, "w") || (access_status !=  HTTP_NOT_FOUND))
                        return access_status;
                apr_table_setn(params, args, val);
                args = tok;
            }
            else
                return HTTP_BAD_REQUEST;
        }
    }
    
    /* Check that the supplied nonce matches this server's nonce;
     * otherwise ignore all parameters, to prevent a CSRF attack. */
    if ((name = apr_table_get(params, "nonce")) == NULL 
        || strcmp(balancer_nonce, name) != 0) {
        apr_table_clear(params);
    }

    if ((name = apr_table_get(params, "b")))
        bsel = ap_proxy_get_balancer(r->pool, conf,
            apr_pstrcat(r->pool, "balancer://", name, NULL));
    if ((name = apr_table_get(params, "w"))) {
        proxy_worker *ws;

        ws = ap_proxy_get_worker(r->pool, conf, name);
        if (bsel && ws) {
            worker = (proxy_worker *)bsel->workers->elts;
            for (n = 0; n < bsel->workers->nelts; n++) {
                if (strcasecmp(worker->name, ws->name) == 0) {
                    wsel = worker;
                    break;
                }
                ++worker;
            }
        }
    }
    /* First set the params */
    /*
     * Note that it is not possible set the proxy_balancer because it is not
     * in shared memory.
     */
    if (wsel) {
        const char *val;
        if ((val = apr_table_get(params, "lf"))) {
            int ival = atoi(val);
            if (ival >= 1 && ival <= 100) {
                wsel->s->lbfactor = ival;
                if (bsel)
                    recalc_factors(bsel);
            }
        }
        if ((val = apr_table_get(params, "wr"))) {
            if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ)
                strcpy(wsel->s->route, val);
            else
                *wsel->s->route = '\0';
        }
        if ((val = apr_table_get(params, "rr"))) {
            if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ)
                strcpy(wsel->s->redirect, val);
            else
                *wsel->s->redirect = '\0';
        }
        if ((val = apr_table_get(params, "dw"))) {
            if (!strcasecmp(val, "Disable"))
                wsel->s->status |= PROXY_WORKER_DISABLED;
            else if (!strcasecmp(val, "Enable"))
                wsel->s->status &= ~PROXY_WORKER_DISABLED;
        }
        if ((val = apr_table_get(params, "ls"))) {
            int ival = atoi(val);
            if (ival >= 0 && ival <= 99) {
                wsel->s->lbset = ival;
             }
        }

    }
    if (apr_table_get(params, "xml")) {
        ap_set_content_type(r, "text/xml");
        ap_rputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n", r);
        ap_rputs("<httpd:manager xmlns:httpd=\"http://httpd.apache.org\">\n", r);
        ap_rputs("  <httpd:balancers>\n", r);
        balancer = (proxy_balancer *)conf->balancers->elts;
        for (i = 0; i < conf->balancers->nelts; i++) {
            ap_rputs("    <httpd:balancer>\n", r);
            ap_rvputs(r, "      <httpd:name>", balancer->name, "</httpd:name>\n", NULL);
            ap_rputs("      <httpd:workers>\n", r);
            worker = (proxy_worker *)balancer->workers->elts;
            for (n = 0; n < balancer->workers->nelts; n++) {
                ap_rputs("        <httpd:worker>\n", r);
                ap_rvputs(r, "          <httpd:scheme>", worker->scheme,
                          "</httpd:scheme>\n", NULL);
                ap_rvputs(r, "          <httpd:hostname>", worker->hostname,
                          "</httpd:hostname>\n", NULL);
               ap_rprintf(r, "          <httpd:loadfactor>%d</httpd:loadfactor>\n",
                          worker->s->lbfactor);
                ap_rputs("        </httpd:worker>\n", r);
                ++worker;
            }
            ap_rputs("      </httpd:workers>\n", r);
            ap_rputs("    </httpd:balancer>\n", r);
            ++balancer;
        }
        ap_rputs("  </httpd:balancers>\n", r);
        ap_rputs("</httpd:manager>", r);
    }
    else {
        ap_set_content_type(r, "text/html; charset=ISO-8859-1");
        ap_rputs(DOCTYPE_HTML_3_2
                 "<html><head><title>Balancer Manager</title></head>\n", r);
        ap_rputs("<body><h1>Load Balancer Manager for ", r);
        ap_rvputs(r, ap_get_server_name(r), "</h1>\n\n", NULL);
        ap_rvputs(r, "<dl><dt>Server Version: ",
                  ap_get_server_description(), "</dt>\n", NULL);
        ap_rvputs(r, "<dt>Server Built: ",
                  ap_get_server_built(), "\n</dt></dl>\n", NULL);
        balancer = (proxy_balancer *)conf->balancers->elts;
        for (i = 0; i < conf->balancers->nelts; i++) {

            ap_rputs("<hr />\n<h3>LoadBalancer Status for ", r);
            ap_rvputs(r, balancer->name, "</h3>\n\n", NULL);
            ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"
                "<th>StickySession</th><th>Timeout</th><th>FailoverAttempts</th><th>Method</th>"
                "</tr>\n<tr>", r);
            if (balancer->sticky) {
                ap_rvputs(r, "<td>", balancer->sticky, NULL);
            }
            else {
                ap_rputs("<td> - ", r);
            }
            ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",
                apr_time_sec(balancer->timeout));
            ap_rprintf(r, "<td>%d</td>\n", balancer->max_attempts);
            ap_rprintf(r, "<td>%s</td>\n",
                       balancer->lbmethod->name);
            ap_rputs("</table>\n<br />", r);
            ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>"
                "<th>Worker URL</th>"
                "<th>Route</th><th>RouteRedir</th>"
                "<th>Factor</th><th>Set</th><th>Status</th>"
                "<th>Elected</th><th>To</th><th>From</th>"
                "</tr>\n", r);

            worker = (proxy_worker *)balancer->workers->elts;
            for (n = 0; n < balancer->workers->nelts; n++) {
                char fbuf[50];
                ap_rvputs(r, "<tr>\n<td><a href=\"", r->uri, "?b=",
                          balancer->name + sizeof("balancer://") - 1, "&w=",
                          ap_escape_uri(r->pool, worker->name),
                          "&nonce=", balancer_nonce, 
                          "\">", NULL);
                ap_rvputs(r, worker->name, "</a></td>", NULL);
                ap_rvputs(r, "<td>", ap_escape_html(r->pool, worker->s->route),
                          NULL);
                ap_rvputs(r, "</td><td>",
                          ap_escape_html(r->pool, worker->s->redirect), NULL);
                ap_rprintf(r, "</td><td>%d</td>", worker->s->lbfactor);
                ap_rprintf(r, "<td>%d</td><td>", worker->s->lbset);
                if (worker->s->status & PROXY_WORKER_DISABLED)
                   ap_rputs("Dis ", r);
                if (worker->s->status & PROXY_WORKER_IN_ERROR)
                   ap_rputs("Err ", r);
                if (worker->s->status & PROXY_WORKER_STOPPED)
                   ap_rputs("Stop ", r);
                if (worker->s->status & PROXY_WORKER_HOT_STANDBY)
                   ap_rputs("Stby ", r);
                if (PROXY_WORKER_IS_USABLE(worker))
                    ap_rputs("Ok", r);
                if (!PROXY_WORKER_IS_INITIALIZED(worker))
                    ap_rputs("-", r);
                ap_rputs("</td>", r);
                ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td><td>", worker->s->elected);
                ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r);
                ap_rputs("</td><td>", r);
                ap_rputs(apr_strfsize(worker->s->read, fbuf), r);
                ap_rputs("</td></tr>\n", r);

                ++worker;
            }
            ap_rputs("</table>\n", r);
            ++balancer;
        }
        ap_rputs("<hr />\n", r);
        if (wsel && bsel) {
            ap_rputs("<h3>Edit worker settings for ", r);
            ap_rvputs(r, wsel->name, "</h3>\n", NULL);
            ap_rvputs(r, "<form method=\"GET\" action=\"", NULL);
            ap_rvputs(r, r->uri, "\">\n<dl>", NULL);
            ap_rputs("<table><tr><td>Load factor:</td><td><input name=\"lf\" type=text ", r);
            ap_rprintf(r, "value=\"%d\"></td></tr>\n", wsel->s->lbfactor);
            ap_rputs("<tr><td>LB Set:</td><td><input name=\"ls\" type=text ", r);
            ap_rprintf(r, "value=\"%d\"></td></tr>\n", wsel->s->lbset);
            ap_rputs("<tr><td>Route:</td><td><input name=\"wr\" type=text ", r);
            ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->route),
                      NULL);
            ap_rputs("\"></td></tr>\n", r);
            ap_rputs("<tr><td>Route Redirect:</td><td><input name=\"rr\" type=text ", r);
            ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->redirect),
                      NULL);
            ap_rputs("\"></td></tr>\n", r);
            ap_rputs("<tr><td>Status:</td><td>Disabled: <input name=\"dw\" value=\"Disable\" type=radio", r);
            if (wsel->s->status & PROXY_WORKER_DISABLED)
                ap_rputs(" checked", r);
            ap_rputs("> | Enabled: <input name=\"dw\" value=\"Enable\" type=radio", r);
            if (!(wsel->s->status & PROXY_WORKER_DISABLED))
                ap_rputs(" checked", r);
            ap_rputs("></td></tr>\n", r);
            ap_rputs("<tr><td colspan=2><input type=submit value=\"Submit\"></td></tr>\n", r);
            ap_rvputs(r, "</table>\n<input type=hidden name=\"w\" ",  NULL);
            ap_rvputs(r, "value=\"", ap_escape_uri(r->pool, wsel->name), "\">\n", NULL);
            ap_rvputs(r, "<input type=hidden name=\"b\" ", NULL);
            ap_rvputs(r, "value=\"", bsel->name + sizeof("balancer://") - 1,
                      "\">\n", NULL);
            ap_rvputs(r, "<input type=hidden name=\"nonce\" value=\"", 
                      balancer_nonce, "\">\n", NULL);
            ap_rvputs(r, "</form>\n", NULL);
            ap_rputs("<hr />\n", r);
        }
        ap_rputs(ap_psignature("",r), r);
        ap_rputs("</body></html>\n", r);
    }
    return OK;
}