0

I am trying to use HTTP post request to get the location info from google geolocation API but something is going wrong with the connection after I send the query i get 0 as return value for recev()

Is the way am sending post request the issue?

why does the connection close after I send the request? what should i do to keep the connection alive?

#include <windows.h>
#include <winsock.h>
#include <string.h>
#pragma comment(lib, "Ws2_32.lib")

char content[1500];

#define constGLReq  \
    "POST /geolocation/v1/geolocate?key=AIzaSyBibyFS6jV3OgPxIZkFp_t97G_THjrq0Z4; sensor=false HTTP/1.1\r\n" \
        "Host: www.googleapis.com\r\n" \
        "Connection: close\r\n" \
        "Cache-Control: no-cache\r\n" \
        "Connection: keep-alive\r\n" \
        "Content-Type: application/json\r\n" \
        "Content-Length: 0\r\n" \
        "\r\n"

int main()
{
    char data[512];
    SOCKET Socket;
    int Res ;
    WSADATA wsaData;
    char * host = "www.googleapis.com";
    struct hostent *server;
    SOCKADDR_IN Socaddr;


    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {           
        return -1;
    }

    memset(data, 0, sizeof(data));
    memset(content, 0, sizeof(content));
    Socket = socket(AF_INET, SOCK_STREAM, 0);
    if (Socket == INVALID_SOCKET)
    {
        /* Problem in socket creation*/
    }
    server = gethostbyname(host);

    memset(&Socaddr, 0, sizeof(SockAddr));
    Socaddr.sin_port = htons(443);
    Socaddr.sin_family = AF_INET;
    memcpy(&Socaddr.sin_addr.s_addr, server->h_addr, server->h_length);

        Res = connect(Socket, (SOCKADDR*)(&Socaddr), sizeof(Socaddr));
    if (Res != 0)
    {
        closesocket(Socket1);
    }
    else
    {
        Res = send(Socket, constGLReq, (int)strlen(constGLReq), 0);

        if (Res == SOCKET_ERROR)/* Checking for sending failed */
        {
            closesocket(Socket1);
        }
        else if (Res <= 0)
        {
        }
        else /* Sending successfull */`enter code here`
        {


            do
            {
            Res  = recv(Socket, data, sizeof(data), 0);
            error = WSAGetLastError();

            if (strlen(data) != 0)
            {
                    if (strlen(content) == 0)
                    {
                        strcpy(content, data);
                    }
                    else
                    {
                        strcat(content, data);
                    }
            }
            memset(data, 0, sizeof(data));
        } while (Res > 0);
                }
            }
    closesocket(Socket1);
    WSACleanup();
    return 0;
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
siva
  • 1
  • When `recv` returns `0` it means that the other side of the connection have closed it, and that you should too. – Some programmer dude Jul 31 '19 at 12:12
  • 1
    There are also other problems with your code, like for example you won't be receiving a null-terminated string, so `strlen(data)` will not work correctly (and will in fact lead to *undefined behavior*). If you want to treat the received data as a string you need to add the null-terminator yourself. – Some programmer dude Jul 31 '19 at 12:23
  • 3
    Can't you just use curl or WinHTTP to get job done? – Kamila Szewczyk Jul 31 '19 at 12:51
  • The first line of your `POST` request is malformed. You can't have unencoded whitespace in a URL. The whitespace in front of `sensor=false` is breaking the request. There is no `sensor` attribute in the GeoLocation API, you need to remove it. The server is likely closing the connection with an error because of that mistake in your code. – Remy Lebeau Jul 31 '19 at 18:03
  • Also, requesting `Connection: keep-alive` is redundant in HTTP 1.1. However, requesting a keep-alive doesnt guarantee the server will honor it. Ultimately, the server decides whether to keep the connection alive or not. You have to parse the server's response to know what decision was actually made, as well as to know when the response ends. You can't just blindly read data in an endless loop, *especially* when a keep-alive is used. You must stop reading when the end of the response is reached. Read [RFC 2616 Section 4.4](https://tools.ietf.org/html/rfc2616#section-4.4) for the rules on that. – Remy Lebeau Jul 31 '19 at 18:05
  • @RemyLebeau I have remove sensor along with white space but still I receive zero – siva Aug 01 '19 at 06:50
  • @siva well, like I said, you are not PARSING THE RESPONSE at all, you are just reading in a loop until `recv()` fails, so it makes sense that you would get 0 from it eventually. See [When is an HTTP response finished?](https://stackoverflow.com/questions/19199066/), and [this answer](https://stackoverflow.com/a/16247097/65863) to [Differ between header and content of http server response (sockets)](https://stackoverflow.com/questions/16243118/). You have a ways to go still before you have a viable HTTP client. – Remy Lebeau Aug 01 '19 at 16:34

0 Answers0