Exemple #1
0
std::map<std::string,std::string> uri_parse_query(const std::string& query)
{
	UriParserStateA state;
	UriUriA uri;
	state.uri=&uri;
	UriQueryListA* list;

	if(uriParseUriA(&state,query.c_str())!=0||
		uriDissectQueryMallocA(&list,nullptr,uri.query.first,uri.query.afterLast)!=0)
	{
		uriFreeUriMembersA(&uri);
		return {{"error","Bad string."}};
	}

	std::map<std::string,std::string> queries;
	auto head=list;

	while(head!=nullptr)
	{
		if(head->key!=nullptr)
		{
			if(head->value!=nullptr)
				queries[std::string(head->key)]=std::string(head->value);
			else
				queries[std::string(head->key)]="true";
		}
		head=head->next;
	}

	uriFreeQueryListA(list);
	uriFreeUriMembersA(&uri);
	return queries;
}
int httpd_query_iterate(const char *uri_str, query_iterate_func f, void *userdata)
{
    UriParserStateA state;
    UriUriA uri;
    UriQueryListA *queryList, *p;
    int itemCount;

    state.uri = &uri;
    if (uriParseUriA(&state, uri_str) != URI_SUCCESS)
    {
        uriFreeUriMembersA(&uri);
        return 1;
    }

    if (uriDissectQueryMallocA(&queryList, &itemCount, uri.query.first, uri.query.afterLast) != URI_SUCCESS)
    {
        uriFreeUriMembersA(&uri);
        return 1;
    }

    p = queryList;
    while(NULL != p)
    {
        if (0 == f(p->key, p->value, userdata))
            break;
        p = p->next;
    }

    uriFreeQueryListA(queryList);
    uriFreeUriMembersA(&uri);
    return 0;
}
Exemple #3
0
void HttpHandler::parseURL(const char* request_uri)
{
    this->parameter = new std::unordered_map<std::string, std::string>();
    UriParserStateA state;
    UriUriA uri;
    state.uri = &uri;

    if (request_uri == nullptr)
    {
        return;
    }

    if (uriParseUriA(&state, request_uri) != URI_SUCCESS)
    {
        uriFreeUriMembersA(&uri);
        return;
    }

    UriQueryListA* queryList;
    int itemCount;

    if (uriDissectQueryMallocA(&queryList, &itemCount, uri.query.first, uri.query.afterLast) == URI_SUCCESS)
    {
        auto& current = queryList;

        do
        {
            if (queryList->value != nullptr) {
                auto buffer = new char[std::strlen(queryList->value) + 1];
                std::strcpy(buffer, (char*) queryList->value);

                uriUnescapeInPlaceExA(buffer, false, URI_BR_DONT_TOUCH);
                (*this->parameter)[queryList->key] = buffer;
                delete[] buffer;
            }
            else {
                (*this->parameter)[queryList->key] = std::string("");
            }

            current = queryList->next;
        } while (current != nullptr);

        uriFreeQueryListA(queryList);
        uriFreeUriMembersA(&uri);
        return;
    }
}
Exemple #4
0
Datum parse_uri(PG_FUNCTION_ARGS)
{
  TupleDesc tupledesc;
  AttInMetadata *attinmeta;
  text* input=PG_GETARG_TEXT_P(0);
    /* Function is defined STRICT in SQL, so no NULL check is needed. */
  bool normalize=PG_GETARG_BOOL(1);
  bool parse_query=PG_GETARG_BOOL(2);

  char* inp=palloc((1+VARSIZE(input)-VARHDRSZ)*sizeof(char));
  if (!inp) {
    ereport(ERROR,
            (errcode(ERRCODE_OUT_OF_MEMORY),
             errmsg("Memory allocation failed.")));
    PG_RETURN_NULL();
  }
  memcpy(inp,VARDATA(input),VARSIZE(input)-VARHDRSZ);
  inp[VARSIZE(input)-VARHDRSZ]='\0';

  /* Function internals start here */

  int i;
  int memctr;
  UriPathSegmentA* pathseg;
  int quit;
  char* writehere;
  UriParserStateA state;
  UriUriA uri;

  state.uri = &uri;

  if (uriParseUriA(&state, inp) != URI_SUCCESS) {
    uriFreeUriMembersA(&uri);
/*
    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("Unable to parse URI.")));
*/
    PG_RETURN_NULL();
  }

  if (normalize) {
    if (uriNormalizeSyntaxA(&uri) != URI_SUCCESS) {
      uriFreeUriMembersA(&uri);
      PG_RETURN_NULL();
    }
  }

  UriQueryListA* queryList=NULL;
  int itemCount;
  if (parse_query&&(uri.query.afterLast!=uri.query.first)) {
    if (uriDissectQueryMallocA(&queryList, &itemCount, uri.query.first,
                               uri.query.afterLast) != URI_SUCCESS) {
      uriFreeUriMembersA(&uri);
      uriFreeQueryListA(queryList);
      PG_RETURN_NULL();
    }
  }
    

  /* Function internals finish here */
   
  if (get_call_result_type(fcinfo, NULL, &tupledesc) != TYPEFUNC_COMPOSITE) {
    ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("function returning record called in context "
                    "that cannot accept type record")));
    PG_RETURN_NULL();
  }
  /* This error should never happen, because the SQL function is defined
     as returning a uri_type. */

  attinmeta = TupleDescGetAttInMetadata(tupledesc);

  char** retval=(char**) palloc(13*sizeof(char*));
  if (!retval) {
    ereport(ERROR,
            (errcode(ERRCODE_OUT_OF_MEMORY),
             errmsg("Memory allocation failed.")));
    PG_RETURN_NULL();
  }
  if (uri.scheme.afterLast==uri.scheme.first) {
    retval[0]=NULL;
  } else {
    retval[0]=(char*) palloc((1+(uri.scheme.afterLast-uri.scheme.first))*sizeof(char)); /* scheme, e.g. "http" */
    if (!retval[0]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpz(retval[0],uri.scheme.first,uri.scheme.afterLast-uri.scheme.first);
  }
  if (uri.userInfo.afterLast==uri.userInfo.first) {
    retval[1]=NULL;
  } else {
    retval[1]=(char*) palloc((1+(uri.userInfo.afterLast-uri.userInfo.first))*sizeof(char)); /* userInfo, e.g. "gpadmin" */
    if (!retval[1]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpz(retval[1],uri.userInfo.first,uri.userInfo.afterLast-uri.userInfo.first);
  }
  if (uri.hostText.afterLast==uri.hostText.first) {
    retval[2]=NULL;
  } else {
    retval[2]=(char*) palloc((1+(uri.hostText.afterLast-uri.hostText.first))*sizeof(char)); /* hostText, e.g. "192.165.0.0" */
    if (!retval[2]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpz(retval[2],uri.hostText.first,uri.hostText.afterLast-uri.hostText.first);
  }
  if (uri.hostData.ip4==NULL) {
    retval[3]=NULL;
  } else {
    retval[3]=(char*) palloc(17*sizeof(char)); /* IPv4 */
    if (!retval[3]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpy(retval[3],"\\000\\000\\000\\000",17);
    for(i=0;i<4;++i) {
      retval[3][1+4*i]+=uri.hostData.ip4->data[i]>> 6;
      retval[3][2+4*i]+=(uri.hostData.ip4->data[i]>> 3)&7;
      retval[3][3+4*i]+=uri.hostData.ip4->data[i]&7;
    }
  }
  if (uri.hostData.ip6==NULL) {
    retval[4]=NULL;
  } else {
    retval[4]=(char*) palloc(65*sizeof(char)); /* IPv6 */
    if (!retval[4]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpy(retval[4],"\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000\\000",65);
    for(i=0;i<16;++i) {
      retval[4][1+4*i]+=uri.hostData.ip6->data[i]>> 6;
      retval[4][2+4*i]+=(uri.hostData.ip6->data[i]>> 3)&7;
      retval[4][3+4*i]+=uri.hostData.ip6->data[i]&7;
    }
  }
  if (uri.hostData.ipFuture.afterLast==uri.hostData.ipFuture.first) {
    retval[5]=NULL;
  } else {
    retval[5]=(char*) palloc((1+(uri.hostData.ipFuture.afterLast-uri.hostData.ipFuture.first))*sizeof(char)); /* ipFuture, text field */
    if (!retval[5]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpz(retval[5],uri.hostData.ipFuture.first,uri.hostData.ipFuture.afterLast-uri.hostData.ipFuture.first);
  }
  if (uri.portText.afterLast==uri.portText.first) {
    retval[6]=NULL;
  } else {
    retval[6]=(char*) palloc((1+(uri.portText.afterLast-uri.portText.first))*sizeof(char)); /* portText, e.g. "80" */
    if (!retval[6]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpz(retval[6],uri.portText.first,uri.portText.afterLast-uri.portText.first);
  }
  if (uri.pathHead==NULL) {
    retval[7]=NULL;
  } else {
    memctr=2;
    pathseg=uri.pathHead;
    do {
      quit=((pathseg==uri.pathTail)||(pathseg->next==NULL));
      memctr+=3+2*(pathseg->text.afterLast-pathseg->text.first);
      pathseg=pathseg->next;
    } while (!quit);
    if (memctr==2) {
      ++memctr;
    }
    retval[7]=(char*) palloc(memctr*sizeof(char)); /* path */
    /* e.g. "{usr,local,lib}" */
    if (!retval[7]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    writehere=retval[7];
    *writehere='{';
    ++writehere;
    pathseg=uri.pathHead;
    do {
      quit=((pathseg==uri.pathTail)||(pathseg->next==NULL));
      writehere=memenc(writehere,pathseg->text.first,pathseg->text.afterLast-pathseg->text.first);
      *writehere=',';
      ++writehere;
      pathseg=pathseg->next;
    } while (!quit);
    if (memctr!=3) {
      --writehere;
    }
    memcpy(writehere,"}",2);
  }
  if (uri.query.afterLast==uri.query.first) {
    retval[8]=NULL;
  } else {
    retval[8]=(char*) palloc((1+(uri.query.afterLast-uri.query.first))*sizeof(char)); /* query without leading "?" */
    if (!retval[8]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpz(retval[8],uri.query.first,uri.query.afterLast-uri.query.first);
  }
  if (uri.fragment.afterLast==uri.fragment.first) {
    retval[9]=NULL;
  } else {
    retval[9]=(char*) palloc((1+(uri.fragment.afterLast-uri.fragment.first))*sizeof(char)); /* fragment without leading "#" */
    if (!retval[9]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpz(retval[9],uri.fragment.first,uri.fragment.afterLast-uri.fragment.first);
  }
  if (uri.absolutePath) {
    retval[10]=(char*) palloc(5*sizeof(char)); /* absolutePath */
    if (!retval[10]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpy(retval[10],"true",5);
  } else {
    retval[10]=(char*) palloc(6*sizeof(char)); /* absolutePath */
    if (!retval[10]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    memcpy(retval[10],"false",6);
  }

  if (parse_query) {
    int key_counter=2;
    int val_counter=2;
    int counter=0;
    for(UriQueryListA* it=queryList;(counter!=itemCount)&&(it!=NULL);
        it=it->next,++counter) {
      if (it->key==NULL) {
        key_counter+=3; /* should never reach here. */
      } else {
        key_counter+=3+2*strlen(it->key);
      }
      if (it->value==NULL) {
        val_counter+=3; /* currently no way to distinguish empty string
                           value (?a=) from null value (?a). This is a GPDB
                           limitation. */
      } else {
        val_counter+=3+2*strlen(it->value);
      }
    }
    if (key_counter==2) {
      ++key_counter;
    }
    if (val_counter==2) {
      ++val_counter;
    }
    retval[11]=palloc(key_counter*sizeof(char));
    if (!retval[11]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    retval[12]=palloc(val_counter*sizeof(char));
    if (!retval[12]) {
      ereport(ERROR,
              (errcode(ERRCODE_OUT_OF_MEMORY),
               errmsg("Memory allocation failed.")));
      PG_RETURN_NULL();
    }
    retval[11][0]='{';
    retval[12][0]='{';
    char* key_ptr=retval[11]+1;
    char* val_ptr=retval[12]+1;
    counter=0;
    for(UriQueryListA* it=queryList;(counter!=itemCount)&&(it!=NULL);
        it=it->next,++counter) {
      if (it->key==NULL) {
        *key_ptr='"';
        ++key_ptr;
        *key_ptr='"';
        ++key_ptr;
        *key_ptr=',';
        ++key_ptr;
        /* should never reach here. */
      } else {
        key_ptr=strenc(key_ptr,it->key);
        *key_ptr=',';
        ++key_ptr;
      }
      if (it->value==NULL) {
        *val_ptr='"';
        ++val_ptr;
        *val_ptr='"';
        ++val_ptr;
        *val_ptr=',';
        ++val_ptr;
                        /* currently no way to distinguish empty string
                           value (?a=) from null value (?a). This is a GPDB
                           limitation. */
      } else {
        val_ptr=strenc(val_ptr,it->value);
        *val_ptr=',';
        ++val_ptr;
      }
    }
    if (key_counter!=3) {
      --key_ptr;
    }
    memcpy(key_ptr,"}",2);
    if (val_counter!=3) {
      --val_ptr;
    }
    memcpy(val_ptr,"}",2);
    uriFreeQueryListA(queryList);
  } else {
    retval[11]=NULL;
    retval[12]=NULL;
  }

  /* There is no need to call pfree. It's called automatically. */

  HeapTuple tuple;
  Datum result;

  tuple=BuildTupleFromCStrings(attinmeta,retval);
  result=HeapTupleGetDatum(tuple);

  /* Free memory start */
  uriFreeUriMembersA(&uri);
  /* Free memory finish */

  PG_RETURN_DATUM(result);
}