0

I have made this code below to download large file and save it to file. (I removed not important parts)

int nDataLength;
int i = 0;
static char buffer[4096];
while ((nDataLength = recv(Socket, buffer, sizeof(buffer), NULL)) > 0)
{
    //MessageBoxA(0, std::to_string(nDataLength).c_str(), "TEST", 0);
    fwrite(buffer, nDataLength, 1, pFile);
}

Now It saves file, but it also saves HTTP header. Now I don't really know how to strip the header from received data.
If it was small enough I could read Content-Length from buffer and then open the file again and remove header, but thats not the option cause buffer will be overwritten with new data.

Also I cannot use other libraries like libcurl etc.

EDIT:

char* content = strstr(buffer, "\r\n\r\n");
    if (content != NULL) {
        content += 4;
        fwrite(content, nDataLength, 1, pFile);
    }
    else
    {
        fwrite(buffer, nDataLength, 1, pFile);
    }
  • The specification for HTTP will tell you, in exact detail, how an HTTP message is formatted and where exactly the header ends, and the content begins. Are you familiar with the HTTP technical specification? It's a freely-available document. – Sam Varshavchik Aug 30 '20 at 18:34
  • Just write the data, do not write the header. For that, you have to parse the header... Start simple, write the entire data to a temp file, header and all. Then write a separate function (or even a program) which takes the temp file, parses the header, and then writes the correct data to the final file. Once you can do that, then try to combine this so that you don't need the temp file. – hyde Aug 30 '20 at 18:35
  • @SamVarshavchik I know that data starts after \r\n\r\n but I don't know how to strip it. – Boże Bożenka Aug 30 '20 at 18:42
  • @hyde I'm doing that right know, I know data is after /r/n but I cannot replicate it without tempfile. – Boże Bożenka Aug 30 '20 at 18:43
  • I don't know how to discard until /r/n/r/n. I added the sample code(Look at my question) I came up with but It instead add header data to the end of buffer. Also I'm fairly new to c++ so I might be missing something. – Boże Bożenka Aug 30 '20 at 19:04

1 Answers1

-1

OK, I came up with function that strips header before saving.

 int nDataLength;
int i = 0;
static char buffer[4096];
while ((nDataLength = recv(Socket, buffer, sizeof(buffer), NULL)) > 0)
{
    char* content = strstr(buffer, "\r\n\r\n");
    if (content != NULL) {
        std::string s2(buffer); 
        size_t p = s2.find("\r\n\r\n");
        fwrite(buffer+p+4, nDataLength-p-4, 1, pFile);
    }
    else
    {
        fwrite(buffer, nDataLength, 1, pFile);
    }
    
}
  • `recv()` reads an arbitrary number of bytes. There is no guarantee that `buffer` will contain a complete `"\r\n\r\n"` at one time. Also, `recv()` does not null-terminate the data it returns, but `strstr()` requires a null-terminated string (so does the `std::string` constructor you are using). So, this function, as written, will NOT work 100% correctly. Also, using `strstr()` and `string::find()` together the way you are is redundant. – Remy Lebeau Aug 30 '20 at 23:20
  • Could you provide your source for this function then? I'll mark it as answer. – Boże Bożenka Aug 31 '20 at 10:56
  • that is your choice, but your solution is just plain wrong for several reasons and it WILL fail eventually, which is why I downvoted it. I've posted numerous answers in the past explaining/showing the *proper* way to read HTTP responses. For instance: https://stackoverflow.com/a/30472253/65863, https://stackoverflow.com/a/7234357/65863, https://stackoverflow.com/a/16247097/65863, https://stackoverflow.com/a/14421507/65863 – Remy Lebeau Sep 01 '20 at 16:38