/* return each comma separated token, one at a time */ CACHE_DECLARE(const char *)ap_cache_tokstr(apr_pool_t *p, const char *list, const char **str) { apr_size_t i; const char *s; s = ap_strchr_c(list, ','); if (s != NULL) { i = s - list; do s++; while (apr_isspace(*s)) ; /* noop */ } else i = strlen(list); while (i > 0 && apr_isspace(list[i - 1])) i--; *str = s; if (i) return apr_pstrndup(p, list, i); else return NULL; }
static int nextarg(apr_pool_t *p, const char *val, char **arg) { char quote; int pos=0; char *tmp= (char*)apr_pstrdup(p, val); while (apr_isspace(*tmp)) { ++tmp; ++pos; } quote = (*tmp == '"' || *tmp == '\'') ? *tmp++ : '\0'; *arg = tmp; for (; *tmp; ++tmp && ++pos ) { if ((apr_isspace(*tmp) && !quote) || (*tmp == quote)) { break; } if (*tmp == '\\' && apr_isspace(tmp[1])) { ++tmp; ++pos; continue; } } if (!*tmp) { return 0; } *tmp++ = '\0'; pos++; return pos; }
static void pm_norepeat_config(nx_module_t *module) { const nx_directive_t *curr; nx_pm_norepeat_conf_t *modconf; const char *start, *ptr, *end; char *field = NULL; apr_size_t len; modconf = apr_pcalloc(module->pool, sizeof(nx_pm_norepeat_conf_t)); module->config = modconf; curr = module->directives; while ( curr != NULL ) { if ( nx_module_common_keyword(curr->directive) == TRUE ) { } else if ( strcasecmp(curr->directive, "CheckFields") == 0 ) { if ( modconf->fields != NULL ) { nx_conf_error(curr, "CheckFields already defined"); } ptr = curr->args; for ( ; (ptr != NULL) && apr_isspace(*ptr); (ptr)++ ); if ( (curr->args == NULL) || (strlen(ptr) == 0) ) { nx_conf_error(curr, "value missing for CheckFields"); } end = ptr + strlen(ptr); modconf->fields = apr_array_make(module->pool, 5, sizeof(const char *)); while ( *ptr != '\0' ) { start = ptr; for ( ; !((*ptr == '\0') || apr_isspace(*ptr) || (*ptr == ',')); ptr++ ); if ( ptr > start ) { len = (apr_size_t) (ptr - start + 1); field = apr_palloc(module->pool, len); apr_cpystrn(field, start, len); } *((const char **) apr_array_push(modconf->fields)) = field; for ( ; apr_isspace(*ptr) || (*ptr == ','); ptr++ ); } } else { nx_conf_error(curr, "invalid pm_norepeat keyword: %s", curr->directive); } curr = curr->next; } modconf->pid = (int) getpid(); }
/* little helper function to get the original request path code borrowed from request.c and util_script.c */ static const char *ap_xsendfile_get_orginal_path(request_rec *rec) { const char *rv = rec->the_request, *last; int dir = 0; size_t uri_len; /* skip method && spaces */ while (*rv && !apr_isspace(*rv)) { ++rv; } while (apr_isspace(*rv)) { ++rv; } /* first space is the request end */ last = rv; while (*last && !apr_isspace(*last)) { ++last; } uri_len = last - rv; if (!uri_len) { return NULL; } /* alright, lets see if the request_uri changed! */ if (strncmp(rv, rec->uri, uri_len) == 0) { rv = apr_pstrdup(rec->pool, rec->filename); dir = rec->finfo.filetype == APR_DIR; } else { /* need to lookup the url again as it changed */ request_rec *sr = ap_sub_req_lookup_uri( apr_pstrmemdup(rec->pool, rv, uri_len), rec, NULL ); if (!sr) { return NULL; } rv = apr_pstrdup(rec->pool, sr->filename); dir = rec->finfo.filetype == APR_DIR; ap_destroy_sub_req(sr); } /* now we need to truncate so we only have the directory */ if (!dir && (last = ap_strrchr(rv, '/')) != NULL) { *((char*)last + 1) = '\0'; } return rv; }
/* Remove leading and trailing white space from a C string, in place. */ static void trim_string(char **pstr) { char *str = *pstr; int i; while (apr_isspace(*str)) str++; *pstr = str; i = strlen(str); while ((i > 0) && apr_isspace(str[i-1])) i--; str[i] = '\0'; }
static int strnatcmp0(char const *a, char const *b, int fold_case) { int ai, bi; char ca, cb; int fractional, result; ai = bi = 0; while (1) { ca = a[ai]; cb = b[bi]; /* skip over leading spaces or zeros */ while (apr_isspace(ca)) ca = a[++ai]; while (apr_isspace(cb)) cb = b[++bi]; /* process run of digits */ if (apr_isdigit(ca) && apr_isdigit(cb)) { fractional = (ca == '0' || cb == '0'); if (fractional) { if ((result = compare_left(a+ai, b+bi)) != 0) return result; } else { if ((result = compare_right(a+ai, b+bi)) != 0) return result; } } if (!ca && !cb) { /* The strings compare the same. Perhaps the caller will want to call strcmp to break the tie. */ return 0; } if (fold_case) { ca = apr_toupper(ca); cb = apr_toupper(cb); } if (ca < cb) return -1; else if (ca > cb) return +1; ++ai; ++bi; } }
/* * get the authorization header that should contain a bearer token */ static apr_byte_t oidc_oauth_get_bearer_token(request_rec *r, const char **access_token) { /* get the authorization header */ const char *auth_line; auth_line = apr_table_get(r->headers_in, "Authorization"); if (!auth_line) { oidc_debug(r, "no authorization header found"); return FALSE; } /* look for the Bearer keyword */ if (apr_strnatcasecmp(ap_getword(r->pool, &auth_line, ' '), "Bearer")) { oidc_error(r, "client used unsupported authentication scheme: %s", r->uri); return FALSE; } /* skip any spaces after the Bearer keyword */ while (apr_isspace(*auth_line)) { auth_line++; } /* copy the result in to the access_token */ *access_token = apr_pstrdup(r->pool, auth_line); /* log some stuff */ oidc_debug(r, "bearer token: %s", *access_token); return TRUE; }
/** * find certain header line, return copy of first part (up to first ";") * @param p pool to allocate from * @param name name of the header * @param string input: pointer to pointer string where to find the header; * output: pointer to the ";" or "\n" after the copied value * @param end pointer where to stop searching * @note string must be NUL-terminated (but the NUL may be after *end) * @return copy of the header value or NULL if not found */ static char *mbox_mime_get_header(apr_pool_t *p, const char *name, char **string, const char *end) { char *ptr; int namelen = strlen(name); for (ptr = *string; ptr && *ptr && ptr < end ; ptr = ap_strchr(ptr + 1, '\n') + 1) { int l; if (strncasecmp(ptr, name, namelen) != 0) continue; ptr += namelen; if (*ptr != ':') continue; ptr++; while (*ptr == ' ') ptr++; if (ptr >= end) break; l = strcspn(ptr, ";\n"); *string = ptr + l; while (apr_isspace(ptr[l]) && l > 0) l--; return apr_pstrndup(p, ptr, l); } return NULL; }
static const char * set_redirect_min_size(cmd_parms *cmd, void *config, const char *size_str) { aclr_dir_config *cfg = (aclr_dir_config *)config; char *endptr; long size; size = strtol(size_str, &endptr, 10); while (apr_isspace(*endptr)) endptr++; if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') { ; } else if (*endptr == 'k' || *endptr == 'K') { size *= 1024; } else if (*endptr == 'm' || *endptr == 'M') { size *= 1048576; } else { return apr_pstrcat(cmd->pool, "Invalid size in AccelRedirectSize: ", size_str, NULL); } cfg->fsize = (size >= 0) ? size : UNSET; return NULL; }
static apr_status_t parse_status_line(response_context_t *ctx, serf_bucket_alloc_t *allocator) { int res; char *reason; /* ### stupid APR interface makes this non-const */ /* ctx->linebuf.line should be of form: HTTP/1.1 200 OK */ res = apr_date_checkmask(ctx->linebuf.line, "HTTP/#.# ###*"); if (!res) { /* Not an HTTP response? Well, at least we won't understand it. */ return SERF_ERROR_BAD_HTTP_RESPONSE; } ctx->sl.version = SERF_HTTP_VERSION(ctx->linebuf.line[5] - '0', ctx->linebuf.line[7] - '0'); ctx->sl.code = apr_strtoi64(ctx->linebuf.line + 8, &reason, 10); /* Skip leading spaces for the reason string. */ if (apr_isspace(*reason)) { reason++; } /* Copy the reason value out of the line buffer. */ ctx->sl.reason = serf_bstrmemdup(allocator, reason, ctx->linebuf.used - (reason - ctx->linebuf.line)); return APR_SUCCESS; }
/* * Strips all of the RE: junk from the subject line. */ static char *strip_subject(apr_pool_t *p, Message *m) { char *newVal, *match = m->subject, *tmp = NULL; /* Match the following cases: Re:, RE:, RE[1]:, Re: Re[2]: Re: */ while (match && *match) { /* When we don't have a match, tmp contains the "real" subject. */ tmp = newVal = match; match = NULL; if (*newVal == 'R' && (*++newVal == 'e' || *newVal == 'E')) { /* Note to self. In pure compressed syntax, the famous dangling * else occurs. Oh, well. */ if (*++newVal == '[') { while (apr_isdigit(*++newVal)) { } if (*++newVal == ']' && *++newVal == ':') match = ++newVal; } else if (*newVal == ':') match = ++newVal; } if (match) while (apr_isspace(*match)) match++; } return apr_pstrdup(p, tmp); }
static void fill_gmi(Ganglia_25metric* gmi, py_metric_init_t* minfo) { char *s, *lasts; int i; const apr_array_header_t *arr = apr_table_elts(minfo->extra_data); const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; /* gmi->key will be automatically assigned by gmond */ gmi->name = apr_pstrdup (pool, minfo->mname); gmi->tmax = minfo->tmax; if (!strcasecmp(minfo->vtype, "string")) { gmi->type = GANGLIA_VALUE_STRING; gmi->msg_size = UDP_HEADER_SIZE+MAX_G_STRING_SIZE; } else if (!strcasecmp(minfo->vtype, "uint")) { gmi->type = GANGLIA_VALUE_UNSIGNED_INT; gmi->msg_size = UDP_HEADER_SIZE+8; } else if (!strcasecmp(minfo->vtype, "int")) { gmi->type = GANGLIA_VALUE_INT; gmi->msg_size = UDP_HEADER_SIZE+8; } else if (!strcasecmp(minfo->vtype, "float")) { gmi->type = GANGLIA_VALUE_FLOAT; gmi->msg_size = UDP_HEADER_SIZE+8; } else if (!strcasecmp(minfo->vtype, "double")) { gmi->type = GANGLIA_VALUE_DOUBLE; gmi->msg_size = UDP_HEADER_SIZE+16; } else { gmi->type = GANGLIA_VALUE_UNKNOWN; gmi->msg_size = UDP_HEADER_SIZE+8; } gmi->units = apr_pstrdup(pool, minfo->units); gmi->slope = apr_pstrdup(pool, minfo->slope); gmi->fmt = apr_pstrdup(pool, minfo->format); gmi->desc = apr_pstrdup(pool, minfo->desc); MMETRIC_INIT_METADATA(gmi, pool); for (s=(char *)apr_strtok(minfo->groups, ",", &lasts); s!=NULL; s=(char *)apr_strtok(NULL, ",", &lasts)) { char *d = s; /* Strip the leading white space */ while (d && *d && apr_isspace(*d)) { d++; } MMETRIC_ADD_METADATA(gmi,MGROUP,d); } /* transfer any extra data as metric metadata */ for (i = 0; i < arr->nelts; ++i) { if (elts[i].key == NULL) continue; MMETRIC_ADD_METADATA(gmi, elts[i].key, elts[i].val); } }
static int clear_conn_headers(void *data, const char *key, const char *val) { apr_table_t *headers = ((header_dptr*)data)->table; apr_pool_t *pool = ((header_dptr*)data)->pool; const char *name; char *next = apr_pstrdup(pool, val); while (*next) { name = next; while (*next && !apr_isspace(*next) && (*next != ',')) { ++next; } while (*next && (apr_isspace(*next) || (*next == ','))) { *next++ = '\0'; } apr_table_unset(headers, name); } return 1; }
/* Iterate through the cookies, isolate our cookie and then remove it. * * If our cookie appears two or more times, but with different values, * remove it twice and set the duplicated flag to true. Remove any * $path or other attributes following our cookie if present. If we end * up with an empty cookie, remove the whole header. */ static int extract_cookie_line(ap_cookie_do * v, const char *key, const char *val) { char *last1, *last2; char *cookie = apr_pstrdup(v->r->pool, val); const char *name = apr_pstrcat(v->r->pool, v->name ? v->name : "", "=", NULL); apr_size_t len = strlen(name); const char *new_cookie = ""; const char *comma = ","; char *next1; const char *semi = ";"; char *next2; const char *sep = ""; int cookies = 0; /* find the cookie called name */ int eat = 0; next1 = apr_strtok(cookie, comma, &last1); while (next1) { next2 = apr_strtok(next1, semi, &last2); while (next2) { char *trim = next2; while (apr_isspace(*trim)) { trim++; } if (!strncmp(trim, name, len)) { if (v->encoded) { if (strcmp(v->encoded, trim + len)) { v->duplicated = 1; } } v->encoded = apr_pstrdup(v->r->pool, trim + len); eat = 1; } else { if (*trim != '$') { cookies++; eat = 0; } if (!eat) { new_cookie = apr_pstrcat(v->r->pool, new_cookie, sep, next2, NULL); } } next2 = apr_strtok(NULL, semi, &last2); sep = semi; } next1 = apr_strtok(NULL, comma, &last1); sep = comma; } /* any cookies left over? */ if (cookies) { apr_table_addn(v->new_cookies, key, new_cookie); } return 1; }
/* length of dest assumed >= length of src * collapse in place (src == dest) is legal. * returns terminating null ptr to dest string. */ APR_DECLARE(char *) apr_collapse_spaces(char *dest, const char *src) { while (*src) { if (!apr_isspace(*src)) *dest++ = *src; ++src; } *dest = 0; return (dest); }
AP_DECLARE(char *) ap_getword_conf(apr_pool_t *p, const char **line) { const char *str = *line, *strend; char *res; char quote; while (*str && apr_isspace(*str)) ++str; if (!*str) { *line = str; return ""; } if ((quote = *str) == '"' || quote == '\'') { strend = str + 1; while (*strend && *strend != quote) { if (*strend == '\\' && strend[1] && (strend[1] == quote || strend[1] == '\\')) { strend += 2; } else { ++strend; } } res = substring_conf(p, str + 1, strend - str - 1, quote); if (*strend == quote) ++strend; } else { strend = str; while (*strend && !apr_isspace(*strend)) ++strend; res = substring_conf(p, str, strend - str, 0); } while (*strend && apr_isspace(*strend)) ++strend; *line = strend; return res; }
apr_int32_t util_timestring_to_seconds(char *string) { char *character; apr_int32_t number = 0; if (string == NULL) return 0; character = string; /* calculate number */ while (apr_isdigit(*character) || apr_isspace(*character)) { if (apr_isdigit(*character)) { /* translate to number */ unsigned digit = (unsigned) *character - (unsigned) '0'; ap_assert(digit < 10); number = (number * (apr_int32_t) 10) + (apr_int32_t) digit; } character += 1; } if (*character != '\0') { switch(*character) { case 'w': case 'W': number = number * SECONDS_IN_WEEK; break; case 'd': case 'D': number = number * SECONDS_IN_DAY; break; case 'h': case 'H': number = number * SECONDS_IN_HOUR; break; case 'm': case 'M': number = number * SECONDS_IN_MINUTE; break; case 's': case 'S': default: /* this is only here for clarity */ number = number; break; } } if (number > MAX_CACHE_TIMEOUT) number = MAX_CACHE_TIMEOUT; return number; }
AP_DECLARE(char *) ap_getword_white(apr_pool_t *p, const char **line) { const char *pos = *line; int len; char *res; while (!apr_isspace(*pos) && *pos) { ++pos; } len = pos - *line; res = calloc(1, len + 1); memcpy(res, *line, len); res[len] = 0; while (apr_isspace(*pos)) { ++pos; } *line = pos; return res; }
static APR_INLINE apr_size_t string_first_non_whitespace(const char *str, apr_size_t len) { apr_size_t i; for (i = 0; i < len; i++) { if (! apr_isspace(str[i])) return i; } /* if we get here, then the string must be entirely whitespace */ return len; }
void svn_cstring_split_append(apr_array_header_t *array, const char *input, const char *sep_chars, svn_boolean_t chop_whitespace, apr_pool_t *pool) { char *last; char *pats; char *p; pats = apr_pstrdup(pool, input); /* strtok wants non-const data */ p = apr_strtok(pats, sep_chars, &last); while (p) { if (chop_whitespace) { while (apr_isspace(*p)) p++; { char *e = p + (strlen(p) - 1); while ((e >= p) && (apr_isspace(*e))) e--; *(++e) = '\0'; } } if (p[0] != '\0') APR_ARRAY_PUSH(array, const char *) = p; p = apr_strtok(NULL, sep_chars, &last); } return; }
/** * find value for parameter with certain name * @param p pool to allocate from * @param name name of the attribute * @param string string with name=value pairs separated by ";", * value may be a quoted string delimited by double quotes * @param end pointer where to stop searching * @note string must be NUL-terminated (but the NUL may be after *end) * @return copy of the value, NULL if not found */ static char *mbox_mime_get_parameter(apr_pool_t *p, const char *name, const char *string, const char *end) { const char *ptr = string; int namelen = strlen(name); while (ptr && *ptr && ptr < end) { int have_match = 0; const char *val_end; while (*ptr && (apr_isspace(*ptr) || *ptr == ';')) ptr++; if (strncasecmp(ptr, name, namelen) == 0) { ptr += strlen(name); while (*ptr && apr_isspace(*ptr) && ptr < end) ptr++; if (*ptr == '=') { have_match = 1; ptr++; if (ptr >= end) break; while (*ptr && apr_isspace(*ptr) && ptr < end) ptr++; } } if (!have_match) ptr += strcspn(ptr, ";= \t"); if (*ptr == '"') val_end = ap_strchr_c(++ptr, '"'); else val_end = ptr + strcspn(ptr, ";\n "); if (!val_end || val_end > end) val_end = end; if (have_match) return apr_pstrmemdup(p, ptr, val_end - ptr); ptr = val_end + 1; } return NULL; }
/* Obtain the Request-URI from the original request-line, returning * a new string from the request pool containing the URI or "". */ static char *original_uri(request_rec *r) { char *first, *last; if (r->the_request == NULL) { return (char *) apr_pcalloc(r->pool, 1); } first = r->the_request; /* use the request-line */ while (*first && !apr_isspace(*first)) { ++first; /* skip over the method */ } while (apr_isspace(*first)) { ++first; /* and the space(s) */ } last = first; while (*last && !apr_isspace(*last)) { ++last; /* end at next whitespace */ } return apr_pstrmemdup(r->pool, first, last - first); }
static apr_status_t groups_for_user(apr_pool_t *p, char *user, char *grpfile, apr_table_t ** out) { ap_configfile_t *f; apr_table_t *grps = apr_table_make(p, 15); apr_pool_t *sp; struct ap_varbuf vb; const char *group_name, *ll, *w; apr_status_t status; apr_size_t group_len; if ((status = ap_pcfg_openfile(&f, p, grpfile)) != APR_SUCCESS) { return status ; } apr_pool_create(&sp, p); ap_varbuf_init(p, &vb, VARBUF_INIT_LEN); while (!(ap_varbuf_cfg_getline(&vb, f, VARBUF_MAX_LEN))) { if ((vb.buf[0] == '#') || (!vb.buf[0])) { continue; } ll = vb.buf; apr_pool_clear(sp); group_name = ap_getword(sp, &ll, ':'); group_len = strlen(group_name); while (group_len && apr_isspace(*(group_name + group_len - 1))) { --group_len; } while (ll[0]) { w = ap_getword_conf(sp, &ll); if (!strcmp(w, user)) { apr_table_setn(grps, apr_pstrmemdup(p, group_name, group_len), "in"); break; } } } ap_cfg_closefile(f); apr_pool_destroy(sp); ap_varbuf_free(&vb); *out = grps; return APR_SUCCESS; }
void svn_stringbuf_strip_whitespace(svn_stringbuf_t *str) { /* Find first non-whitespace character */ apr_size_t offset = svn_stringbuf_first_non_whitespace(str); /* Go ahead! Waste some RAM, we've got pools! :) */ str->data += offset; str->len -= offset; str->blocksize -= offset; /* Now that we've trimmed the front, trim the end, wasting more RAM. */ while ((str->len > 0) && apr_isspace(str->data[str->len - 1])) str->len--; str->data[str->len] = '\0'; }
/* This code should be replaced with header buckets. */ static apr_status_t fetch_headers(serf_bucket_t *bkt, response_context_t *ctx) { apr_status_t status; /* RFC 2616 says that CRLF is the only line ending, but we can easily * accept any kind of line ending. */ status = fetch_line(ctx, SERF_NEWLINE_ANY); if (SERF_BUCKET_READ_ERROR(status)) { return status; } /* Something was read. Process it. */ if (ctx->linebuf.state == SERF_LINEBUF_READY && ctx->linebuf.used) { const char *end_key; const char *c; end_key = c = memchr(ctx->linebuf.line, ':', ctx->linebuf.used); if (!c) { /* Bad headers? */ return SERF_ERROR_BAD_HTTP_RESPONSE; } /* Skip over initial ':' */ c++; /* And skip all whitespaces. */ for(; c < ctx->linebuf.line + ctx->linebuf.used; c++) { if (!apr_isspace(*c)) { break; } } /* Always copy the headers (from the linebuf into new mem). */ /* ### we should be able to optimize some mem copies */ serf_bucket_headers_setx( ctx->headers, ctx->linebuf.line, end_key - ctx->linebuf.line, 1, c, ctx->linebuf.line + ctx->linebuf.used - c, 1); } return status; }
static int get_basic_auth(request_rec *r, const char **user, const char **pw) { const char *auth_line; char *decoded_line; int length; /* Get the appropriate header */ auth_line = apr_table_get(r->headers_in, (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authorization" : "Authorization"); if (!auth_line) { note_basic_auth_failure(r); return HTTP_UNAUTHORIZED; } if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) { /* Client tried to authenticate using wrong auth scheme */ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01614) "client used wrong authentication scheme: %s", r->uri); note_basic_auth_failure(r); return HTTP_UNAUTHORIZED; } /* Skip leading spaces. */ while (apr_isspace(*auth_line)) { auth_line++; } decoded_line = apr_palloc(r->pool, apr_base64_decode_len(auth_line) + 1); length = apr_base64_decode(decoded_line, auth_line); /* Null-terminate the string. */ decoded_line[length] = '\0'; *user = ap_getword_nulls(r->pool, (const char**)&decoded_line, ':'); *pw = decoded_line; /* set the user, even though the user is unauthenticated at this point */ r->user = (char *) *user; return OK; }
static const char *log_cookie(request_rec *r, char *a) { const char *cookies_entry; /* * This supports Netscape version 0 cookies while being tolerant to * some properties of RFC2109/2965 version 1 cookies: * - case-insensitive match of cookie names * - white space between the tokens * It does not support the following version 1 features: * - quoted strings as cookie values * - commas to separate cookies */ if ((cookies_entry = apr_table_get(r->headers_in, "Cookie"))) { char *cookie, *last1, *last2; char *cookies = apr_pstrdup(r->pool, cookies_entry); while ((cookie = apr_strtok(cookies, ";", &last1))) { char *name = apr_strtok(cookie, "=", &last2); if (name) { char *value = name + strlen(name) + 1; apr_collapse_spaces(name, name); if (!strcasecmp(name, a)) { char *last; value += strspn(value, " \t"); /* Move past leading WS */ last = value + strlen(value) - 1; while (last >= value && apr_isspace(*last)) { *last = '\0'; --last; } return ap_escape_logitem(r->pool, value); } } cookies = NULL; } } return NULL; }
/* Check if the cookie header value passed in (The Cookie: part has * already been stripped) contains a DumbHippo authorization cookie * for the server name found in the configuration. * * The reason we need to actually parse the DumbHippo authorization * cookies and check the server name is we have issues where * a cookie from http://mugshot.org can be sent to * http://dogfood.mugshot.org, for example. **/ static int hippo_has_cookie(cache_server_conf *conf, const char *cookie_name, const char *header) { /* The Cookie: header was defined successively in: * * http://wp.netscape.com/newsref/std/cookie_spec.html * http://www.ietf.org/rfc/rfc2109.txt * http://www.ietf.org/rfc/rfc2965.txt * * With more elaborations in each, but all valid Cookie: headers * fit into the pattern: * * Cookie: token "=" (token|quoted_string) (";"|",') 0*(token "=" (token|quoted_string)) * * Though not all such strings are valid cookies (For example, the * first token is always supposed to be $Version, and ',' can only * be used to separate cookies, and cannot be used to separate a * a cookie from the following parameters.) We don't try to * validate, but simply parse the header according to the above syntax, * and look for: * * "auth" "=" (token | quoted_string) * * Similarly, we ignore the detailed HTTPD spec for token, and just look * for whitespace or the specific separator that follows. */ const char *p = header; int cookie_name_len = strlen(cookie_name); while (*p) { const char *name_start; const char *name_end; const char *value_start; const char *value_end; /* Find the leading token, which is the cookie name (or * a reserved value like $Version or $Path) */ while (apr_isspace(*p)) ++p; name_start = p; while (*p && *p != '=' && !apr_isspace(*p)) ++p; name_end = p; while (apr_isspace(*p)) ++p; /* Look for and skip the separating "=" */ if (*p != '=') return 0; /* parse error */ ++p; while (apr_isspace(*p)) ++p; if (!*p) return 0; /* parse error */ /* Now we have the value, which is either a quoted string or a * a token */ if (*p == '"') { /* Quoted string follows */ ++p; value_start = p; while (1) { if (!*p) { return 0; /* parse error */ } else if (*p == '\\') { // We don't have to actually unescape here ... // since it never matters to us whether a cookie // has a " or a \" in it. ++p; if (!*p) return 0; /* parse error */ ++p; } else if (*p == '"') { break; } else { ++p; } } value_end = p; ++p; } else { /* Unquoted token */ value_start = p; while (*p && *p != ',' && *p != ';' && !apr_isspace(*p)) ++p; value_end = p; } /* Did we find the cookie we were looking for? */ if (name_end - name_start == cookie_name_len && strncmp(name_start, cookie_name, cookie_name_len) == 0 && hippo_auth_is_for_server(conf, value_start, value_end)) return 1; while (apr_isspace(*p)) ++p; if (*p) { /* Look for and skip the separator between name=value pairs */ if (*p != ',' && *p != ';') return 0; /* parse error */ ++p; while (apr_isspace(*p)) ++p; } } return 0; }
static apr_status_t read_table(cache_handle_t *handle, request_rec *r, apr_table_t *table, apr_file_t *file) { char w[MAX_STRING_LEN]; char *l; int p; apr_status_t rv; while (1) { /* ### What about APR_EOF? */ rv = apr_file_gets(w, MAX_STRING_LEN - 1, file); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Premature end of cache headers."); return rv; } /* Delete terminal (CR?)LF */ p = strlen(w); /* Indeed, the host's '\n': '\012' for UNIX; '\015' for MacOS; '\025' for OS/390 -- whatever the script generates. */ if (p > 0 && w[p - 1] == '\n') { if (p > 1 && w[p - 2] == CR) { w[p - 2] = '\0'; } else { w[p - 1] = '\0'; } } /* If we've finished reading the headers, break out of the loop. */ if (w[0] == '\0') { break; } #if APR_CHARSET_EBCDIC /* Chances are that we received an ASCII header text instead of * the expected EBCDIC header lines. Try to auto-detect: */ if (!(l = strchr(w, ':'))) { int maybeASCII = 0, maybeEBCDIC = 0; unsigned char *cp, native; apr_size_t inbytes_left, outbytes_left; for (cp = w; *cp != '\0'; ++cp) { native = apr_xlate_conv_byte(ap_hdrs_from_ascii, *cp); if (apr_isprint(*cp) && !apr_isprint(native)) ++maybeEBCDIC; if (!apr_isprint(*cp) && apr_isprint(native)) ++maybeASCII; } if (maybeASCII > maybeEBCDIC) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "CGI Interface Error: Script headers apparently ASCII: (CGI = %s)", r->filename); inbytes_left = outbytes_left = cp - w; apr_xlate_conv_buffer(ap_hdrs_from_ascii, w, &inbytes_left, w, &outbytes_left); } } #endif /*APR_CHARSET_EBCDIC*/ /* if we see a bogus header don't ignore it. Shout and scream */ if (!(l = strchr(w, ':'))) { return APR_EGENERAL; } *l++ = '\0'; while (*l && apr_isspace(*l)) { ++l; } apr_table_add(table, w, l); } return APR_SUCCESS; }
static apr_dbd_t *dbd_mysql_open(apr_pool_t *pool, const char *params, const char **error) { static const char *const delims = " \r\n\t;|,"; const char *ptr; int i; const char *key; size_t klen; const char *value; size_t vlen; #if MYSQL_VERSION_ID >= 50013 my_bool do_reconnect = 1; #endif MYSQL *real_conn; unsigned long flags = 0; struct { const char *field; const char *value; } fields[] = { {"host", NULL}, {"user", NULL}, {"pass", NULL}, {"dbname", NULL}, {"port", NULL}, {"sock", NULL}, {"flags", NULL}, {"fldsz", NULL}, {"group", NULL}, #if MYSQL_VERSION_ID >= 50013 {"reconnect", NULL}, {"connecttimeout", NULL}, {"readtimeout", NULL}, {"writetimeout", NULL}, #endif {NULL, NULL} }; unsigned int port = 0; #if MYSQL_VERSION_ID >= 50013 unsigned int timeout = 0; #endif apr_dbd_t *sql = apr_pcalloc(pool, sizeof(apr_dbd_t)); sql->fldsz = FIELDSIZE; sql->conn = mysql_init(sql->conn); if ( sql->conn == NULL ) { return NULL; } for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) { /* don't dereference memory that may not belong to us */ if (ptr == params) { ++ptr; continue; } for (key = ptr-1; apr_isspace(*key); --key); klen = 0; while (apr_isalpha(*key)) { /* don't parse backwards off the start of the string */ if (key == params) { --key; ++klen; break; } --key; ++klen; } ++key; for (value = ptr+1; apr_isspace(*value); ++value); vlen = strcspn(value, delims); for (i = 0; fields[i].field != NULL; i++) { if (!strncasecmp(fields[i].field, key, klen)) { fields[i].value = apr_pstrndup(pool, value, vlen); break; } } ptr = value+vlen; } if (fields[4].value != NULL) { port = atoi(fields[4].value); } if (fields[6].value != NULL && !strcmp(fields[6].value, "CLIENT_FOUND_ROWS")) { flags |= CLIENT_FOUND_ROWS; /* only option we know */ } if (fields[7].value != NULL) { sql->fldsz = atol(fields[7].value); } if (fields[8].value != NULL) { mysql_options(sql->conn, MYSQL_READ_DEFAULT_GROUP, fields[8].value); } #if MYSQL_VERSION_ID >= 50013 if (fields[9].value != NULL) { do_reconnect = atoi(fields[9].value) ? 1 : 0; } if (fields[10].value != NULL) { timeout = atoi(fields[10].value); mysql_options(sql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const void *)&timeout); } if (fields[11].value != NULL) { timeout = atoi(fields[11].value); mysql_options(sql->conn, MYSQL_OPT_READ_TIMEOUT, (const void *)&timeout); } if (fields[12].value != NULL) { timeout = atoi(fields[12].value); mysql_options(sql->conn, MYSQL_OPT_WRITE_TIMEOUT, (const void *)&timeout); } #endif #if MYSQL_VERSION_ID >= 50013 /* the MySQL manual says this should be BEFORE mysql_real_connect */ mysql_options(sql->conn, MYSQL_OPT_RECONNECT, &do_reconnect); #endif real_conn = mysql_real_connect(sql->conn, fields[0].value, fields[1].value, fields[2].value, fields[3].value, port, fields[5].value, flags); if(real_conn == NULL) { if (error) { *error = apr_pstrdup(pool, mysql_error(sql->conn)); } mysql_close(sql->conn); return NULL; } #if MYSQL_VERSION_ID >= 50013 /* Some say this should be AFTER mysql_real_connect */ mysql_options(sql->conn, MYSQL_OPT_RECONNECT, &do_reconnect); #endif return sql; }