SFML community forums

Help => Network => Topic started by: Spellbreaker on November 19, 2010, 03:31:47 pm

Title: response.GetField("Content-Length") returns 0
Post by: Spellbreaker on November 19, 2010, 03:31:47 pm
Hello!

I have a question, I have the following code :

Code: [Select]

    sf::Http http;
    http.SetHost(host);
    sf::Http::Request request(page);
    sf::Http::Response response = http.SendRequest(request);
    sf::Http::Response::Status status = response.GetStatus();
    std::string str;
    if (status == sf::Http::Response::Ok) {
        str = response.GetField("Content-Length");
    } else {
        str = "Request Error.";
    }
    return str.length();


Why does str always contains 0 ?

Sincerly,

Spellbreaker
Title: response.GetField("Content-Length") returns 0
Post by: Laurent on November 19, 2010, 04:21:52 pm
Which version of SFML do you use?
Title: response.GetField("Content-Length") returns 0
Post by: Spellbreaker on November 20, 2010, 12:21:57 pm
Latest SFML2 SVN Version (1684)
Title: response.GetField("Content-Length") returns 0
Post by: Laurent on November 20, 2010, 02:07:27 pm
Can you show me a complete example (including the host name and page requested)?
Title: response.GetField("Content-Length") returns 0
Post by: Spellbreaker on November 20, 2010, 02:28:23 pm
Code: [Select]

long DLL_EXPORT getURLContentLength(const char * host, const char * page) {
    sf::Http http;
    http.SetHost(host);
    sf::Http::Request request(page);
    sf::Http::Response response = http.SendRequest(request);
    sf::Http::Response::Status status = response.GetStatus();
    std::string str;
    if (status == sf::Http::Response::Ok) {
        str = response.GetField("Content-Length");
    } else {
        str = "Request Error.";
    }
   std::cout << str;
}


This is the Function, the call is :

getURLContentLenght("http://www.sfml-dev.org", "features.php");

If I request the Pages Content, it works correctly, but I simply don't get the content-length.

I want do modify that function to only request the header, then getting the Content-Lenght: Field.

Right now I have to request the whole page once, then get the contentlength by str.length() in C++, and then I have to request the Content again ( with a getURLContent function ).
Title: response.GetField("Content-Length") returns 0
Post by: Laurent on November 20, 2010, 02:38:34 pm
It seems like the response from the server doesn't include a content-length field. So there's nothing you can do.
Title: response.GetField("Content-Length") returns 0
Post by: Spellbreaker on November 20, 2010, 02:41:55 pm
Ah okay. So the solution would be :

If Status is okay, but lenght = 0, then request the whole page and return the string length, right?
Title: response.GetField("Content-Length") returns 0
Post by: Laurent on November 20, 2010, 02:46:00 pm
Probably. But requesting the page every time you call one of your functions is probably not the most efficient strategy. You should probably request it once (either header or full body) and then call functions that extract information from the received page.
Title: response.GetField("Content-Length") returns 0
Post by: Spellbreaker on November 20, 2010, 02:49:46 pm
Yeah I know, but can I load the page once and store it in a struct inside of the DLL? I thought the information gets lost after the external function call returns to WME...
Title: response.GetField("Content-Length") returns 0
Post by: Laurent on November 20, 2010, 03:03:03 pm
Quote
I thought the information gets lost after the external function call returns to WME...

WME?
If you allocate a structure with new, it won't get destroyed until you call delete. You just have to make sure that both happen in the same module (either the caller or the DLL).

This is usually what C APIs do, together with an opaque pointer:
Code: [Select]
header
------

struct HttpResource; // client doesn't have to know what is inside this structure

DLL_EXPORT HttpResource* get(const char* url);

DLL_EXPORT size_t contentLength(HttpResource* resource);

DLL_EXPORT const char* body(HttpResource* resource);

...

DLL_EXPORT void destroy(HttpResource* resource);



implementation
--------------

struct HttpResource
{
    sf::Http::Response response;
};

HttpResource* get(const char* url)
{
    sf::Http host(...);
    HttpResource* resource = new HttpResource;
    resource->response = host.SendRequest(url);
    return resource;
}

size_t contentLength(HttpResource* resource)
{
    return resource->response.GetField("content-length");
}

const char* body(HttpResource* resource)
{
    return resource->response.GetBody().c_str();
}

...

void destroy(HttpResource* resource)
{
    delete resource;
}
Title: response.GetField("Content-Length") returns 0
Post by: Spellbreaker on November 20, 2010, 03:25:46 pm
:D Damn sorry, I got WME and SFML mixed up. But thanks anyway ;) ;)

The problem with the external DLL call resides in WME, I asked the wrong guy here ;)