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:
preserve
std::string
in local variable untilcurl_easy_perform()
finished:std::string json = writer.write(submitted_data); curl_easy_setopt(curl, curlopt_postfields, json.c_str());
use
curlopt_copypostfields
instead ofcurlopt_postfields
:curl_easy_setopt(curl, curlopt_copypostfields, writer.write(submitted_data).c_str());
Comments
Post a Comment