grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) { grpc_uri *uri; size_t scheme_begin = 0; size_t scheme_end = NOT_SET; size_t authority_begin = NOT_SET; size_t authority_end = NOT_SET; size_t path_begin = NOT_SET; size_t path_end = NOT_SET; size_t query_begin = NOT_SET; size_t query_end = NOT_SET; size_t fragment_begin = NOT_SET; size_t fragment_end = NOT_SET; size_t i; for (i = scheme_begin; uri_text[i] != 0; i++) { if (uri_text[i] == ':') { scheme_end = i; break; } if (uri_text[i] >= 'a' && uri_text[i] <= 'z') continue; if (uri_text[i] >= 'A' && uri_text[i] <= 'Z') continue; if (i != scheme_begin) { if (uri_text[i] >= '0' && uri_text[i] <= '9') continue; if (uri_text[i] == '+') continue; if (uri_text[i] == '-') continue; if (uri_text[i] == '.') continue; } break; } if (scheme_end == NOT_SET) { return bad_uri(uri_text, i, "scheme", suppress_errors); } if (uri_text[scheme_end + 1] == '/' && uri_text[scheme_end + 2] == '/') { authority_begin = scheme_end + 3; for (i = authority_begin; uri_text[i] != 0 && authority_end == NOT_SET; i++) { if (uri_text[i] == '/' || uri_text[i] == '?' || uri_text[i] == '#') { authority_end = i; } } if (authority_end == NOT_SET && uri_text[i] == 0) { authority_end = i; } if (authority_end == NOT_SET) { return bad_uri(uri_text, i, "authority", suppress_errors); } /* TODO(ctiller): parse the authority correctly */ path_begin = authority_end; } else { path_begin = scheme_end + 1; } for (i = path_begin; uri_text[i] != 0; i++) { if (uri_text[i] == '?' || uri_text[i] == '#') { path_end = i; break; } } if (path_end == NOT_SET && uri_text[i] == 0) { path_end = i; } if (path_end == NOT_SET) { return bad_uri(uri_text, i, "path", suppress_errors); } if (uri_text[i] == '?') { query_begin = ++i; if (!parse_fragment_or_query(uri_text, &i)) { return bad_uri(uri_text, i, "query", suppress_errors); } else if (uri_text[i] != 0 && uri_text[i] != '#') { /* We must be at the end or at the beginning of a fragment */ return bad_uri(uri_text, i, "query", suppress_errors); } query_end = i; } if (uri_text[i] == '#') { fragment_begin = ++i; if (!parse_fragment_or_query(uri_text, &i)) { return bad_uri(uri_text, i - fragment_end, "fragment", suppress_errors); } else if (uri_text[i] != 0) { /* We must be at the end */ return bad_uri(uri_text, i, "fragment", suppress_errors); } fragment_end = i; } uri = gpr_malloc(sizeof(*uri)); memset(uri, 0, sizeof(*uri)); uri->scheme = copy_component(uri_text, scheme_begin, scheme_end); uri->authority = copy_component(uri_text, authority_begin, authority_end); uri->path = copy_component(uri_text, path_begin, path_end); uri->query = copy_component(uri_text, query_begin, query_end); uri->fragment = copy_component(uri_text, fragment_begin, fragment_end); parse_query_parts(uri); return uri; }
grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) { grpc_uri *uri; int scheme_begin = 0; int scheme_end = -1; int authority_begin = -1; int authority_end = -1; int path_begin = -1; int path_end = -1; int i; for (i = scheme_begin; uri_text[i] != 0; i++) { if (uri_text[i] == ':') { scheme_end = i; break; } if (uri_text[i] >= 'a' && uri_text[i] <= 'z') continue; if (uri_text[i] >= 'A' && uri_text[i] <= 'Z') continue; if (i != scheme_begin) { if (uri_text[i] >= '0' && uri_text[i] <= '9') continue; if (uri_text[i] == '+') continue; if (uri_text[i] == '-') continue; if (uri_text[i] == '.') continue; } break; } if (scheme_end == -1) { return bad_uri(uri_text, i, "scheme", suppress_errors); } if (uri_text[scheme_end + 1] == '/' && uri_text[scheme_end + 2] == '/') { authority_begin = scheme_end + 3; for (i = authority_begin; uri_text[i] != 0; i++) { if (uri_text[i] == '/') { authority_end = i; } if (uri_text[i] == '?') { return bad_uri(uri_text, i, "query_not_supported", suppress_errors); } if (uri_text[i] == '#') { return bad_uri(uri_text, i, "fragment_not_supported", suppress_errors); } } if (authority_end == -1 && uri_text[i] == 0) { authority_end = i; } if (authority_end == -1) { return bad_uri(uri_text, i, "authority", suppress_errors); } /* TODO(ctiller): parse the authority correctly */ path_begin = authority_end; } else { path_begin = scheme_end + 1; } for (i = path_begin; uri_text[i] != 0; i++) { if (uri_text[i] == '?') { return bad_uri(uri_text, i, "query_not_supported", suppress_errors); } if (uri_text[i] == '#') { return bad_uri(uri_text, i, "fragment_not_supported", suppress_errors); } } path_end = i; uri = gpr_malloc(sizeof(*uri)); memset(uri, 0, sizeof(*uri)); uri->scheme = copy_fragment(uri_text, scheme_begin, scheme_end); uri->authority = copy_fragment(uri_text, authority_begin, authority_end); uri->path = copy_fragment(uri_text, path_begin, path_end); return uri; }