I Am trying to send Wav file using mongoose http server. Basically,I am forming POST request and sending with
struct mg_connection *mg_connect_http(struct mg_mgr *mgr,
mg_event_handler_t ev_handler,
const char *url,
const char *extra_headers,
const char *post_data)
API,This API expect const char *post_data in visible ascii string format but my wav file is raw data, as there are 0x00(null) characters in raw wav file , whole content of file is not sent. Is there any conversation I need to perform on wav file before I send it to server?
I think you should try chunked encoding.
I.e. you should not send raw data in mg_connect_http, but use mg_send_http_chunk and Co.
Another solution you might try is:
c = mg_connect();
mg_set_protocol_http_websocket(c);
mg_printf(c, "POST /my_uri HTTP/1.0\r\n");
mg_printf(c, "Content-Length: %lu\r\n\r\n", (unsigned long) post_len);
mg_send(c, post, post_len);
Note this will buffer the whole WAV file in memory before sending.
Related
I have a server (python) that sends bytes from a file to a client in c++. I am using libcurl to make requests to the python server and flask to do all of the "hard" work for me in python. After i get the file bytes from the server, i want to write it to a zip file on the client side. Initially, i was going to use libcurl to do it for me, but i decided i didn't want to do that as it would require an extra function in my wrapper which is not necessary.
FILE* zip_file = fopen(zip_name, "wb");
//make request and store the bytes from the server in a string
fwrite(response_information.first.c_str(), sizeof(char), sizeof(response_information.first.c_str()), zip_file);
//response_information is a pair . First = std::string, Second = curl response code
I do plan on switching to fopen_s (safe version of fopen), but i want to get a working program first. This is part of a bigger project so i can't provide code that can be run. Some things to note that i think can be causing this: storing response as string then attempting to get the c string version and write it to the file. When storing the return value/code of fwrite, i get "8" which means "*" bytes written apparently. Also, when im on windows, it says that the file was modified after i run my program, but nothing is in the zip file itself. How can i write the response bytes to a file?
The third parameter in fwrite is a count of items to write. So sizeof doesn't seem to be the thing you need. response_information.first.c_str() is a pointer, so sizeof(response_information.first.c_str()) returns a pointer size. Here it should be:
fwrite(response_information.first.c_str(), sizeof(char), strlen(response_information.first.c_str()), zip_file);
or
fwrite(response_information.first.c_str(), sizeof(char), response_information.first.length(), zip_file);
I have a C++ program which is receiving encoded binary data as a HTTP response. The response needs to be decoded and stored as a binary file. The HTTP server that is sending the binary data is written in Python and following is an example code that performs the encoding.
#!/usr/bin/env python3
import base64
# content of the file is string "abc" for testing, the file could be an image file
with open('/tmp/abc', 'rb') as _doc:
data = _doc.read()
# Get Base-64 encoded bytes
data_bytes = base64.b64encode(data)
# Convert the bytes to a string
data_str = data_bytes.decode('utf-8')
print(data_str)
Now, I want to decode the received data_str using a C++ program. I could make the python equivalent as below to work properly.
_data = data_str.encode('utf-8')
bin_data = base64.b64decode(_data)
But, with C++, I tried to use the Boost library's from_utf8 method, but no avail. Could anyone please guide the best way of decoding and getting the binary data in C++ (preferably using boost, since it is portable)?
I'm trying to convert the full string of bytes from a file opened in binary mode to a string encoded in the ISO-8859-1 character set. My understanding is that by converting to ISO-8859-1 all binary information from the file is retained which is why it is being converted to that format. Is this a valid statement?
I'm working in C++ (Visual Studio 2017) building an executable to be used on the Windows platform. I'm not experienced in HTTP programming.
I have prototype code written in PowerShell code which successfully performs the functionality that I'm trying to duplicate in C++. In the power shell code an HTTP message is sent to upload a firmware file to a device.
The message includes headers and a body:
The message is using the multipart/form-data protocol.
An example of the headers of the message are:
Authorization: Bearer Yosda0IDRQuVaU_L0SnV5g==
Content-Type: multipart/form-data; boundary=42b745c8-4da8-454e-8c13-cbb5c1f7694f
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
An example of the body of the message is:
--1a2fc07a-d882-4470-a1da-79716d34cd9b
Content-Disposition: form-data; name="upgrade_file"; filename=""
Content-Type: application/octet-stream
// File data (encoded in ISO-8859-1 format) goes here //
--1a2fc07a-d882-4470-a1da-79716d34cd9b
Content-Disposition: form-data; name="submit"
Install OS
--1a2fc07a-d882-4470-a1da-79716d34cd9b--
The PowerShell script is converting the file with the following lines of code:
$bytes = [System.IO.File]::ReadAllBytes($file.FullName);
if ( $bytes )
{
$enc = [System.Text.Encoding]::GetEncoding(iso-8859-1);
$data = $enc.GetString($bytes);
}
Once the headers and body are setup the message is sent and the firmware is uploaded when running the PowerShell code.
In my C++ code I've got the headers and the pre-body and post-body codes worked out. I think (not sure) that I just need to convert the file to iso-8859-1 to get the message to work now.
I'm using libcurl to send the message.
res = curl_easy_perform(pCurl);
Currently (without converting file to iso-8859-1) I get the following error message from the function call:
Failure when receiving data from the peer
When the message is sent I can see that only some bytes are uploaded. I assume that could be because the file data is not properly encoded and when it is reading that data it reaches some point where the data is in a format that it cannot handle.
In my project I want to send possibly large and frequent XML data to a custom server written in c++. I don't want to use Apache and CGI because the data is too frequent to be starting a CGI process for every request. I would prefer if the data was recieved directly in the c++ code that will process the data and send a reply.
I started out by using libmicrohttpd for the c++ server but now I believe it won't be possible because it doesn't give access to the raw POST data. I started looking for another library but I can't seem to find a c++ library that does this. Can anyone suggest a c++ http server library that has access to the raw post data?
Here is the code I intended to start with. It is one of the example files provided in the source code of libmicrohttpd. Post Example from libmicrohttpd library
Edit:
A little more context.
From what I understand to access the post data in libmicrohttpd you create MHD_PostProcessor function that gets called incrementally as the post data is received in chunks. But in the example below it only shows how to get post data in the form of key value pairs. But I can't see how to get the data from a post.
The example implements the MHD_PostProcessor as post_iterator. See the definition of
static int post_iterator(void *cls,
enum MHD_ValueKind kind,
const char *key,
const char *filename,
const char *content_type,
const char *transfer_encoding,
const char *data, uint64_t off, size_t size) {
...
in the example posted above. You will see it only shows how to iterate the key value pairs.
MHD does give you access to the raw POST data, just grab it from "upload_data" directly instead of passing it to the MHD_PostProcessor. MHD will give you the uploaded POST stream incrementally by calling your main request processing callback repeatedly with more and more POST data being given to you raw, unprocessed in "upload_data".
How to extract the option fields in TCP header using C/C++ in case of an offline pcap file. I tried including the option field within header structure, but it doesn't give a consistent result when I compare the result with Wireshark. It seems arbitrary bytes are going missing when accessed through TCP header structure. Please help.
Rather than attempting to read the file directly, use pcap_open_offline or pcap_fopen_offline from libpcap. This will read the save file in and allow you to supply filters. The pseudocode goes like this (you will need to add error handling):
char *fname = "/path/to/my/file";
const u_char *packet;
pcap_t *handle;
handle = pcap_open_offline (fname, errbuf);
while (packet = pcap_next(handle,&header))
{
char *data = (char *) packet;
...
}
pcap_close (handle);
If by any chance you are already using libpcap, you'll have to post the code. Remember that to find the IP headers reliably you will need to check the ethernet type (ETHER_TYPE_IP vs ETHER_TYPE_8021Q), then find the TCP header (the length of the IP header can vary), and only then will you get a pointer to the TCP header.