c++ - Invalid unicode while sending a POST request to django with libcurl and jsoncpp -


i've created rest endpoint in django using rest-framework module; simple code goes below:

models.py

class data(models.model):     name = models.charfield(max_length=256)     description = models.textfield()      def __str__(self):         return self.name 

serializers.py

class dataserializer(serializers.modelserializer):     class meta:         model = data         fields = ('name', 'description') 

views.py

def data_list(request):     """     list data.     """     if request.method == 'get':         categories = data.objects.all()         serializer = dataserializer(categories, many=true)         return jsonresponse(serializer.data)      elif request.method == 'post':         data = jsonparser().parse(request)         serializer = dataserializer(data=data)         if serializer.is_valid():             serializer.save()             return jsonresponse(serializer.data, status=201)         return jsonresponse(serializer.errors, status=400) 

i've tried sending post requests using restclient plugin firefox, , can validate works as-is.

however, use-case i'd write database using libcurl in c++ application.

if use jsoncpp create json object, , use libcurl make post request, below:

void main() {     json::value submitted_data;     submitted_data["name"] = "data id";     submitted_data["description"] = "data description";     json::styledwriter writer;      curl *curl;     curlcode res;      curl_global_init(curl_global_all);      curl = curl_easy_init();     if (curl) {         curl_easy_setopt(curl, curlopt_url, "http://127.0.0.1:8000/data/");         struct curl_slist *headers = null;         headers = curl_slist_append(headers, "content-type: application/json; charset=utf-8");         curl_easy_setopt(curl, curlopt_httpheader, headers);         curl_easy_setopt(curl, curlopt_post, 1);         curl_easy_setopt(curl, curlopt_postfields, writer.write(submitted_data).c_str());          res = curl_easy_perform(curl);         if (res != curle_ok)             fprintf(stderr, "curl_easy_perform() failed: %s\n",             curl_easy_strerror(res));          curl_easy_cleanup(curl);     } } 

i error django server:

  file "c:\python27\lib\site-packages\rest_framework\parsers.py", line 67, in parse     raise parseerror('json parse error - %s' % six.text_type(exc)) parseerror: json parse error - 'utf8' codec can't decode byte 0xdd in position 0: invalid continuation byte 

and post request isn't successful. understanding that:

  • django-rest-framework expects utf-8 encoded json string,
  • jsoncpp encodes strings in utf-8, and
  • libcurl agnostic encoding , deals data @ byte level.

so i'm bit surprised , not sure how begin troubleshooting. can me figure out how have c++ application , django application work together?

thanks!

per curlopt_postfields documentation:

the data pointed not copied library: consequence, must preserved calling application until associated transfer finishes. behaviour can changed (so libcurl copy data) setting curlopt_copypostfields option.

you passing temporary char* pointer curlopt_postfields. because json::styledwriter::write() returns temporary std::string calling c_str() on. when call curl_easy_setopt() complete, std::string gets destroyed, , char* pointer curl holding on no longer valid. curl ends transmitting garbage data freed memory. undefined behavior, lucky code did not crash altogether.

so, need either:

  1. preserve std::string in local variable until curl_easy_perform() finished:

    std::string json = writer.write(submitted_data); curl_easy_setopt(curl, curlopt_postfields, json.c_str()); 
  2. use curlopt_copypostfields instead of curlopt_postfields:

    curl_easy_setopt(curl, curlopt_copypostfields, writer.write(submitted_data).c_str()); 

Comments

Popular posts from this blog

account - Script error login visual studio DefaultLogin_PCore.js -

xcode - CocoaPod Storyboard error: -