terom@10: #include terom@10: #include terom@10: #include terom@27: #include terom@27: #include terom@10: terom@10: #include terom@10: terom@10: #include "http.h" terom@10: #include "common.h" terom@10: terom@10: int http_qarg_parse (struct evhttp_request *request, struct http_qarg *qarg_spec) { terom@10: // our return code terom@12: int error = -1; terom@10: terom@10: // get the uri from the request terom@10: const char *uri = evhttp_request_get_uri(request); terom@10: terom@10: // the keyval list that we get from evhttp_parse_query terom@10: struct evkeyval *qarg; terom@10: struct evkeyvalq qargs; terom@10: terom@10: // parse the uri into a list terom@10: evhttp_parse_query(uri, &qargs); terom@10: terom@27: // the http_qarg that we iterate with terom@27: struct http_qarg *qarg_info; terom@27: terom@10: // iterate over the list of given query arugments terom@10: TAILQ_FOREACH(qarg, &qargs, next) { terom@10: terom@10: // match them against our http_qarg structs terom@10: for (qarg_info = qarg_spec; qarg_info->hqa_type != QARG_END; qarg_info++) { terom@10: if (strcmp(qarg->key, qarg_info->hqa_key) == 0) { terom@10: // found a match terom@10: terom@10: // extract a value from the qarg terom@10: char *cptr = NULL; terom@27: unsigned long long int uint_val; terom@10: terom@10: switch (qarg_info->hqa_type) { terom@27: case QARG_UINT16 : terom@27: case QARG_UINT32 : terom@27: case QARG_UINT64 : terom@27: uint_val = strtoull(qarg->value, &cptr, 10); terom@10: terom@27: if ( terom@27: (*qarg->value == '\0' || *cptr != '\0') terom@27: || (qarg_info->hqa_type == QARG_UINT16 && uint_val > SHRT_MAX) terom@27: || (qarg_info->hqa_type == QARG_UINT32 && uint_val > UINT_MAX) terom@27: || (qarg_info->hqa_type == QARG_UINT64 && uint_val > ULLONG_MAX) terom@27: ) terom@27: ERROR("invalid QARG_UINT: %s: %s -> %lld", qarg->key, qarg->value, uint_val); terom@27: terom@27: if (qarg_info->hqa_type == QARG_UINT16) terom@27: *((unsigned short int *) qarg_info->hqa_addr) = (unsigned short int) uint_val; terom@27: else if (qarg_info->hqa_type == QARG_UINT32) terom@27: *((unsigned int *) qarg_info->hqa_addr) = (unsigned int) uint_val; terom@27: else if (qarg_info->hqa_type == QARG_UINT64) terom@27: *((unsigned long long int *) qarg_info->hqa_addr) = (unsigned long long int) uint_val; terom@27: else terom@27: assert(0); terom@10: terom@10: break; terom@10: terom@10: case QARG_INVALID : terom@10: ERROR("QARG_INVALID: %s: %s", qarg->key, qarg->value); terom@10: terom@10: default : terom@12: FATAL("invalid qarg_info->hqa_type: %d", qarg_info->hqa_type); terom@10: } terom@27: terom@27: // clear the QARG_REQUIRED flag terom@27: qarg_info->hqa_flags &= ~QARG_REQUIRED; terom@10: } terom@10: } terom@10: } terom@27: terom@27: // missing qargs? terom@27: for (qarg_info = qarg_spec; qarg_info->hqa_type != QARG_END; qarg_info++) { terom@27: if (qarg_info->hqa_flags & QARG_REQUIRED) terom@27: ERROR("missing value for required qarg: %s", qarg_info->hqa_key); terom@27: } terom@27: terom@12: // success terom@12: error = 0; terom@10: error: terom@10: terom@10: // clean up the qargs (badly named functions :< ) terom@10: evhttp_clear_headers(&qargs); terom@10: terom@12: return error; terom@10: }