smcp_status_t plugtest_test_handler(smcp_node_t node) { smcp_status_t ret = SMCP_STATUS_NOT_ALLOWED; char* content = NULL; coap_size_t max_len = 0; smcp_method_t method = smcp_inbound_get_code(); if(method==COAP_METHOD_GET) { ret = smcp_outbound_begin_response(COAP_RESULT_205_CONTENT); } else if(method==COAP_METHOD_POST) { ret = smcp_outbound_begin_response(COAP_RESULT_201_CREATED); } else if(method==COAP_METHOD_PUT) { ret = smcp_outbound_begin_response(COAP_RESULT_204_CHANGED); } else if(method==COAP_METHOD_DELETE) { ret = smcp_outbound_begin_response(COAP_RESULT_202_DELETED); } if(ret) goto bail; smcp_outbound_add_option_uint(COAP_OPTION_CONTENT_TYPE, COAP_CONTENT_TYPE_TEXT_PLAIN); content = smcp_outbound_get_content_ptr(&max_len); if(!content) { ret = SMCP_STATUS_FAILURE; goto bail; } smcp_inbound_get_path(content, SMCP_GET_PATH_LEADING_SLASH|SMCP_GET_PATH_INCLUDE_QUERY); strlcat(content,"\nPlugtest!\nMethod = ",max_len); strlcat(content,coap_code_to_cstr(method),max_len); strlcat(content,"\n",max_len); { const uint8_t* value; coap_size_t value_len; coap_option_key_t key; while((key=smcp_inbound_next_option(&value, &value_len))!=COAP_OPTION_INVALID) { strlcat(content,coap_option_key_to_cstr(key,1),max_len); strlcat(content,": ",max_len); if(coap_option_value_is_string(key)) { int argh = strlen(content)+value_len; strlcat(content,(char*)value,MIN(max_len,argh+1)); content[argh] = 0; } else { strlcat(content,"<binary>",max_len); } strlcat(content,"\n",max_len); } } smcp_outbound_set_content_len((coap_size_t)strlen(content)); ret = smcp_outbound_send(); bail: return ret; }
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; }