/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include AXIS2_EXPORT axis2_char_t *axis2_request_url_prefix = "services"; AXIS2_EXTERN axis2_status_t AXIS2_CALL axutil_parse_rest_url_for_params( const axutil_env_t *env, const axis2_char_t *tmpl, const axis2_char_t *url, int *match_count, axis2_char_t ****matches) { axis2_char_t ***ret = NULL; axis2_char_t *tmp1 = NULL; axis2_char_t **tmp2 = NULL; axis2_char_t ***tmp3 = NULL; axis2_char_t *tmp4 = NULL; axis2_char_t *resource = NULL; axis2_char_t *query = NULL; axis2_char_t *url_tmp = NULL; axis2_char_t *url_resource = NULL; axis2_char_t *url_query = NULL; axis2_bool_t finished = AXIS2_FALSE; axis2_status_t status = AXIS2_FAILURE; int ret_count = 0; int i = 0; int j = 0; axis2_bool_t in_tok = AXIS2_FALSE; tmp2 = AXIS2_MALLOC(env->allocator, 2 * (sizeof(axis2_char_t *))); memset(tmp2, 0, 2 * sizeof(axis2_char_t *)); if(tmpl[0] == '/') { tmp1 = (axis2_char_t *)tmpl; tmp1++; resource = axutil_strdup(env, tmp1); } else { resource = axutil_strdup(env, tmpl); } i = (int)strlen(resource); /* We are sure that the difference lies within the int range */ if(resource[i] == '/') { resource[i] = '\0'; } tmp1 = strchr(resource, '?'); if(tmp1) { axis2_char_t *tmp4 = NULL; tmp4 = tmp1; tmp1++; resource[tmp4 - resource] = '\0'; if(*tmp1 && ((tmp1 - resource) < (int)strlen(resource) - 1)) /* We are sure that the difference lies within the int range */ { query = tmp1; /* * Query String based matching is not implemented. This is * reserved for future implementations. */ } } /* Validation of Template */ i = (int)strlen(resource); /* We are sure that the difference lies within the int range */ if(!strchr(resource, '{') && !strchr(resource, '}')) { i = 0; } for(j = 0; j < i; j++) { if(!in_tok) { if(resource[j] == '}') { AXIS2_FREE(env->allocator, resource); return AXIS2_FAILURE; } else if(resource[j] == '{') { if(j + 1 == i || resource[j + 1] == '}') { AXIS2_FREE(env->allocator, resource); return AXIS2_FAILURE; } else if(resource[j + 1] == '{') { j++; } else { in_tok = AXIS2_TRUE; } } } else { if(resource[j] == '{') { AXIS2_FREE(env->allocator, resource); return AXIS2_FAILURE; } else if(resource[j] == '}') { if(j + 1 < i && resource[j + 1] == '}') { j++; } else { in_tok = AXIS2_FALSE; } } } } if(in_tok) { AXIS2_FREE(env->allocator, resource); return AXIS2_FAILURE; } /* Validity of template guaranteed if not returned */ if(url[0] == '/') { tmp1 = (axis2_char_t *)url; tmp1++; url_resource = axutil_strdup(env, tmp1); } else { url_resource = axutil_strdup(env, url); } i = (int)strlen(url_resource); /* We are sure that the difference lies within the int range */ if(url_resource[i] == '/') { url_resource[i] = '\0'; } i = 0; url_tmp = url_resource; tmp1 = strchr(url_resource, '?'); if(tmp1) { axis2_char_t *tmp4 = NULL; tmp4 = tmp1; tmp1++; url_resource[tmp4 - url_resource] = '\0'; if(*tmp1 && ((tmp1 - url_resource) < (int)strlen(url_resource) - 1)) /* We are sure that the difference lies within the int range */ { url_query = tmp1; } } tmp1 = resource; /* Simplest case match */ if(!strchr(resource, '{')) { if(strcmp(resource, url_resource) == 0) { finished = AXIS2_TRUE; } } while(!finished) { tmp4 = strchr(tmp1, '{'); if(tmp4 && tmp4[1]) { if(tmp4[1] != '{') { axis2_char_t *tmp5 = NULL; axis2_char_t *tmp6 = NULL; axis2_char_t *tmp7 = NULL; axis2_char_t *tmp8 = NULL; axis2_char_t *tmp9 = NULL; /* Logic for finding out constant portion to match */ i = (int)(tmp4 - tmp1); tmp2[0] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); strncpy(tmp2[0], tmp1, i); tmp2[0][i] = '\0'; if(url_tmp && *url_tmp) { tmp6 = url_tmp; tmp5 = strstr(tmp6, tmp2[0]); if(tmp5) { tmp5 += strlen(tmp2[0]); tmp7 = tmp4; tmp8 = tmp4; tmp7++; if(*tmp7) { axis2_bool_t finished_tmp = AXIS2_FALSE; while(!finished_tmp) { tmp6 = strchr(tmp8, '}'); if(tmp6 && *tmp6) { if(tmp6[1] != '}') { tmp8 = tmp6 + 1; break; } } else { finished_tmp = AXIS2_TRUE; } } if(!finished_tmp && !strchr(tmp8, '{')) { tmp7 = tmp8 + strlen(tmp8); } else { while(!finished_tmp) { tmp6 = strchr(tmp8, '{'); if(tmp6 && tmp6[1]) { if(tmp6[1] != '{') { tmp7 = tmp6; break; } } else { finished_tmp = AXIS2_TRUE; } } } if(!finished_tmp) { i = (int)(tmp7 - tmp8); tmp9 = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); strncpy(tmp9, tmp8, i); tmp9[i] = '\0'; } } if(tmp9 && *tmp9) { tmp6 = strstr(tmp5, tmp9); AXIS2_FREE(env->allocator, tmp9); tmp9 = NULL; } else { tmp6 = strchr(tmp5, '/'); } /* Logic for saving the match */ if(tmp6 && tmp6 != tmp5) { i = (int)(tmp6 - tmp5); url_tmp = tmp6; tmp2[1] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); strncpy(tmp2[1], tmp5, i); tmp2[1][i] = '\0'; } else { i = (int)strlen(tmp5); /* We are sure that the difference lies within the int range */ tmp2[1] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); strncpy(tmp2[1], tmp5, i); tmp2[1][i] = '\0'; url_tmp = NULL; } } } else { break; } while(!finished) { tmp1 = tmp4 + 1; tmp4 = strchr(tmp1, '}'); if(tmp4 && *tmp4) { if(tmp4[1] != '}') { /* Logic for saving the key for the match */ i = (int)(tmp4 - tmp1); if(tmp2[0]) { AXIS2_FREE(env->allocator, tmp2[0]); } tmp2[0] = AXIS2_MALLOC(env->allocator, (i + 1) * sizeof(char)); strncpy(tmp2[0], tmp1, i); tmp2[0][i] = '\0'; tmp3 = ret; ret_count++; ret = AXIS2_MALLOC(env->allocator, ret_count * 2 * (sizeof(axis2_char_t *))); memset(ret, 0, ret_count * 2 * sizeof(axis2_char_t *)); for(i = 0; i < ret_count - 1; i++) { ret[i] = tmp3[i]; } ret[i] = tmp2; tmp2 = AXIS2_MALLOC(env->allocator, 2 * (sizeof(axis2_char_t *))); memset(tmp2, 0, 2 * sizeof(axis2_char_t *)); tmp3 = NULL; break; } else { tmp4++; } } else { finished = AXIS2_TRUE; } } } else { tmp4++; } } else { /* Result of mismatch at the simplest case */ if(!strchr(resource, '{')) { finished = AXIS2_FALSE; break; } finished = AXIS2_TRUE; } tmp1 = tmp4 + 1; } if(resource) { AXIS2_FREE(env->allocator, resource); } if(url_resource) { AXIS2_FREE(env->allocator, url_resource); } if(tmp2) { if(tmp2[0]) { AXIS2_FREE(env->allocator, tmp2[0]); } if(tmp2[1]) { AXIS2_FREE(env->allocator, tmp2[1]); } AXIS2_FREE(env->allocator, tmp2); } if(finished) { status = AXIS2_SUCCESS; } *match_count = ret_count; *matches = ret; return status; } AXIS2_EXTERN axis2_char_t **AXIS2_CALL axutil_parse_request_url_for_svc_and_op( const axutil_env_t *env, const axis2_char_t *request) { axis2_char_t **ret = NULL; axis2_char_t *service_str = NULL; axis2_char_t *tmp = NULL; int i = 0; ret = AXIS2_MALLOC(env->allocator, 2 * (sizeof(axis2_char_t *))); memset(ret, 0, 2 * sizeof(axis2_char_t *)); tmp = (axis2_char_t *)request; tmp = strstr(tmp, axis2_request_url_prefix); if(tmp) { service_str = tmp; tmp += axutil_strlen(axis2_request_url_prefix); /*break stop on first prefix as user may have prefix in service name */ } if(service_str) { service_str += axutil_strlen(axis2_request_url_prefix); if('\0' != *service_str) { if(*service_str == '/') service_str++; /*to remove the leading '/' */ tmp = strchr(service_str, '/'); if(tmp) { i = (int)(tmp - service_str); ret[0] = AXIS2_MALLOC(env->allocator, i * sizeof(char) + 1); strncpy(ret[0], service_str, i); ret[0][i] = '\0'; /* Now search for the op */ service_str = tmp; if('\0' != *service_str) { service_str++; tmp = strchr(service_str, '?'); if(tmp) { i = (int)(tmp - service_str); ret[1] = AXIS2_MALLOC(env->allocator, i * sizeof(char) + 1); strncpy(ret[1], service_str, i); ret[1][i] = '\0'; } else { ret[1] = axutil_strdup(env, service_str); } } } else { ret[0] = axutil_strdup(env, service_str); } } } return ret; } AXIS2_EXTERN axis2_char_t *AXIS2_CALL axutil_xml_quote_string( const axutil_env_t *env, const axis2_char_t *s, axis2_bool_t quotes) { const char *scan; size_t len = 0; size_t extra = 0; char *qstr; char *qscan; char c; for(scan = s; (c = *scan) != '\0'; ++scan, ++len) { if(c == '<' || c == '>') extra += 3; /* < or > */ else if(c == '&') extra += 4; /* & */ else if(quotes && c == '"') extra += 5; /* " */ } /* nothing to do */ if(extra == 0) return NULL; qstr = AXIS2_MALLOC(env->allocator, len + extra + 1); for(scan = s, qscan = qstr; (c = *scan) != '\0'; ++scan) { if(c == '<') { *qscan++ = '&'; *qscan++ = 'l'; *qscan++ = 't'; *qscan++ = ';'; } else if(c == '>') { *qscan++ = '&'; *qscan++ = 'g'; *qscan++ = 't'; *qscan++ = ';'; } else if(c == '&') { *qscan++ = '&'; *qscan++ = 'a'; *qscan++ = 'm'; *qscan++ = 'p'; *qscan++ = ';'; } else if(quotes && c == '"') { *qscan++ = '&'; *qscan++ = 'q'; *qscan++ = 'u'; *qscan++ = 'o'; *qscan++ = 't'; *qscan++ = ';'; } else { *qscan++ = c; } } *qscan = '\0'; return qstr; } AXIS2_EXTERN axis2_status_t AXIS2_CALL axutil_url_decode( const axutil_env_t *env, axis2_char_t *dest, axis2_char_t *src) { AXIS2_PARAM_CHECK(env->error, dest, AXIS2_FAILURE); AXIS2_PARAM_CHECK(env->error, src, AXIS2_FAILURE); for(; *src != '\0'; ++dest, ++src) { if(src[0] == '%' && isxdigit(src[1]) && isxdigit(src[2])) { *dest = (axis2_char_t)(axutil_hexit(src[1]) * 16 + axutil_hexit(src[2])); /* We are sure that the conversion is safe */ src += 2; } else { *dest = *src; } } *dest = '\0'; return AXIS2_SUCCESS; } AXIS2_EXTERN int AXIS2_CALL axutil_hexit( axis2_char_t c) { if(c >= '0' && c <= '9') { return c - '0'; } if(c >= 'a' && c <= 'f') { return c - 'a' + 10; } if(c >= 'A' && c <= 'F') { return c - 'A' + 10; } return 0; } AXIS2_EXTERN axis2_status_t AXIS2_CALL axis2_char_2_byte( const axutil_env_t *env, axis2_char_t *char_buffer, axis2_byte_t **byte_buffer, int *byte_buffer_size) { int length = 0; int i = 0; axis2_byte_t *bytes = NULL; length = (int)axutil_strlen(char_buffer); bytes = (axis2_byte_t *)AXIS2_MALLOC(env->allocator, length * sizeof(axis2_byte_t)); if(!bytes) { AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No memory. Cannot create byte buffer"); return AXIS2_FAILURE; } for(i = 0; i < length; i++) { bytes[i] = (axis2_byte_t)char_buffer[i]; } *byte_buffer = bytes; *byte_buffer_size = length; return AXIS2_SUCCESS; }