Exemple #1
0
smcp_status_t
smcp_auth_verify_request() {
	smcp_status_t ret = SMCP_STATUS_OK;
	coap_option_key_t key;
	const uint8_t* authvalue;
	size_t authvalue_len;

	// For testing purposes only!
	if(smcp_inbound_get_code() >1 && smcp_inbound_get_code()<COAP_RESULT_100) {
		ret = SMCP_STATUS_UNAUTHORIZED;
	}

	smcp_inbound_reset_next_option();

	while((key = smcp_inbound_next_option(&authvalue,&authvalue_len))!=COAP_OPTION_INVALID) {
		if(key==COAP_OPTION_PROXY_URI) {
			// For testing purposes only!
			ret = SMCP_STATUS_OK;
		}
		if(key==COAP_OPTION_AUTHENTICATE) {
			// For testing purposes only!
			ret = SMCP_STATUS_OK;
			// writeme!
		}
	}

	if(smcp_inbound_origin_is_local()) {
		ret = SMCP_STATUS_OK;
	}

	ret = SMCP_STATUS_OK;

	// For testing purposes only!
	if(ret==SMCP_STATUS_UNAUTHORIZED) {
		smcp_outbound_begin_response(COAP_RESULT_401_UNAUTHORIZED);
		smcp_outbound_add_option(COAP_OPTION_AUTHENTICATE,NULL,0);
		smcp_outbound_send();
	}

	return ret;
}
smcp_status_t
smcp_node_route(smcp_node_t node, smcp_request_handler_func* func, void** context) {
	smcp_status_t ret = 0;
	smcp_t const self = smcp_get_current_instance();

	smcp_inbound_reset_next_option();

	{
		// TODO: Rewrite this to be more efficient.
		const uint8_t* prev_option_ptr = self->inbound.this_option;
		coap_option_key_t prev_key = 0;
		coap_option_key_t key;
		const uint8_t* value;
		coap_size_t value_len;
		while ((key = smcp_inbound_next_option(&value, &value_len)) != COAP_OPTION_INVALID) {
			if (key > COAP_OPTION_URI_PATH) {
				self->inbound.this_option = prev_option_ptr;
				self->inbound.last_option_key = prev_key;
				break;
			} else if (key == COAP_OPTION_URI_PATH) {
				smcp_node_t next = smcp_node_find(
					node,
					(const char*)value,
					(int)value_len
				);
				if (next) {
					node = next;
				} else {
					self->inbound.this_option = prev_option_ptr;
					self->inbound.last_option_key = prev_key;
					break;
				}
			} else if(key==COAP_OPTION_URI_HOST) {
				// Skip host at the moment,
				// because we don't do virtual hosting yet.
			} else if(key==COAP_OPTION_URI_PORT) {
				// Skip port at the moment,
				// because we don't do virtual hosting yet.
			} else if(key==COAP_OPTION_PROXY_URI) {
				// Skip the proxy URI for now.
			} else if(key==COAP_OPTION_CONTENT_TYPE) {
				// Skip.
			} else {
				if(COAP_OPTION_IS_CRITICAL(key)) {
					ret=SMCP_STATUS_BAD_OPTION;
					assert_printf("Unrecognized option %d, \"%s\"",
						key,
						coap_option_key_to_cstr(key, false)
					);
					goto bail;
				}
			}
			prev_option_ptr = self->inbound.this_option;
			prev_key = self->inbound.last_option_key;
		}
	}

	*func = (void*)node->request_handler;
	if(node->context) {
		*context = node->context;
	} else {
		*context = (void*)node;
	}

bail:
	return ret;
}
Exemple #3
0
smcp_status_t
smcp_curl_proxy_request_handler(
    smcp_curl_proxy_node_t		node
) {
    smcp_status_t ret = SMCP_STATUS_NOT_ALLOWED;
    smcp_curl_request_t request = NULL;
    struct curl_slist *headerlist=NULL;
    smcp_method_t method = smcp_inbound_get_code();

    //require_action(method<=COAP_METHOD_DELETE,bail,ret = SMCP_STATUS_NOT_ALLOWED);

    //require_action(COAP_OPTION_URI_PATH!=smcp_inbound_peek_option(NULL,NULL),bail,ret=SMCP_STATUS_NOT_FOUND);

    node->interface = smcp_get_current_instance();

    smcp_inbound_reset_next_option();

    request = smcp_curl_request_create();
    request->proxy_node = node;

    require_action(request!=NULL,bail,ret = SMCP_STATUS_MALLOC_FAILURE);

    switch(method) {
    case COAP_METHOD_GET:
        curl_easy_setopt(request->curl, CURLOPT_CUSTOMREQUEST, "GET");
        break;
    case COAP_METHOD_PUT:
        curl_easy_setopt(request->curl, CURLOPT_PUT, 1L);
        break;
    case COAP_METHOD_POST:
        curl_easy_setopt(request->curl, CURLOPT_POST, 1L);
        break;
    case COAP_METHOD_DELETE:
        curl_easy_setopt(request->curl, CURLOPT_CUSTOMREQUEST, "DELETE");
        break;
    default:
        ret = SMCP_STATUS_NOT_ALLOWED;
        break;
    }

    {
        coap_option_key_t key;
        const uint8_t* value;
        coap_size_t value_len;
        while((key=smcp_inbound_next_option(&value, &value_len))!=COAP_OPTION_INVALID) {
            if(key==COAP_OPTION_PROXY_URI) {
                char uri[value_len+1];
                memcpy(uri,value,value_len);
                uri[value_len] = 0;
                curl_easy_setopt(request->curl, CURLOPT_URL, uri);
                assert_printf("CuRL URL: \"%s\"",uri);
                ret = 0;
            } else if(key==COAP_OPTION_URI_HOST) {
            } else if(key==COAP_OPTION_URI_PORT) {
            } else if(key==COAP_OPTION_URI_PATH) {
            } else if(key==COAP_OPTION_URI_QUERY) {
            } else if(key==COAP_OPTION_CONTENT_TYPE || key==COAP_OPTION_ACCEPT) {
                const char* option_name = coap_option_key_to_cstr(key, false);
                const char* value_string = coap_content_type_to_cstr(value[1]);
                char header[strlen(option_name)+strlen(value_string)+3];
                strcpy(header,option_name);
                strcat(header,": ");
                strcat(header,value_string);
                headerlist = curl_slist_append(headerlist, header);
                assert_printf("CuRL HEADER: \"%s\"",header);
            } else {
                if(coap_option_value_is_string(key)) {
                    const char* option_name = coap_option_key_to_cstr(key, false);
                    char header[strlen(option_name)+value_len+3];
                    strcpy(header,option_name);
                    strcat(header,": ");
                    strncat(header,(const char*)value,value_len);
                    assert_printf("CuRL HEADER: \"%s\"",header);
                    headerlist = curl_slist_append(headerlist, header);
                }
            }
        }
    }

    require_noerr(ret,bail);

    if(smcp_inbound_get_content_len()) {
        coap_size_t len = smcp_inbound_get_content_len();
        request->output_content = calloc(1,len+1);
        request->output_content_len = len;
        memcpy(request->output_content,smcp_inbound_get_content_ptr(),len);
        curl_easy_setopt(request->curl, CURLOPT_READFUNCTION, ReadMemoryCallback);
        curl_easy_setopt(request->curl, CURLOPT_READDATA, (void *)request);
    }

    curl_easy_setopt(request->curl, CURLOPT_USERAGENT, "smcp-curl-proxy/1.0");
    curl_easy_setopt(request->curl, CURLOPT_HTTPHEADER, headerlist),headerlist=NULL;
    curl_easy_setopt(request->curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
    curl_easy_setopt(request->curl, CURLOPT_WRITEDATA, (void *)request);

    ret = smcp_start_async_response(&request->async_response,0);
    require_noerr(ret,bail);

    if(node->curl_multi_handle)
        curl_multi_add_handle(node->curl_multi_handle, request->curl);
    else
        curl_easy_perform(request->curl);

bail:
    if(headerlist)
        curl_slist_free_all(headerlist);

    if(ret && request)
        smcp_curl_request_release(request);

    return ret;
}