HTTP client GET request

I'm trying to make a HTTP client, to send commands to a radio software over HTTP via localhost

if I type this into my browser, I get the desired result [lowers a slider in the program]
http://127.0.0.1:8282/parameter/hd1/spk/volume?set=0

I managed to get my app to connect to the HTTP server but I can't figure out the right way to send a HTTP request [GET]

I'm using winsock to do this, I've been recommended libcurl but that's even more confusing as I can't find many examples for dummies like myself. [I had to look up how to install a lib, so yeah, I'm pretty bad at this.]

thanks for reading and any replies


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "stdafx.h"
#include "vdjDsp8.h"
#include <stdio.h>
#include <sstream>
#include <fstream>
#include <iostream>
#include <string.h>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#pragma comment (lib, "Ws2_32.lib")
#include <WinSock2.h>
#include <WS2tcpip.h>

//.........other code in between not important

	SOCKADDR_IN addr;
	int addrLen = sizeof(addr);
	IN_ADDR ipvalue;
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	addr.sin_port = htons(8282);
	addr.sin_family = AF_INET;

	SOCKET connection = socket(AF_INET, SOCK_STREAM, NULL);
	if (connect(connection, (SOCKADDR*)&addr, addrLen) == 0) {
		SendCommand("deck 1 play");  // Dj software confirms connecting because this command is acted on

	string getInput = "GET /parameter/hd1/spk/volume?=0 HTTP/1.1\r\nHOST: http://127.0.0.1:8282\r\n\r\n";  // MY BEST GUESS
	send(connection, getInput.c_str(), strlen(getInput.c_str()), 0);
	}
Last edited on
its probably the command to the server is wrong, not the code.
my only guess is maybe it wants json or something (json is very simple formatted text, its really easy). Might review the server side documentation to see exactly what it wants.
So you're saying getInput looks like it's formatted correctly? [like you would expect for a HTTP request.]

I just sent this with curl with cmd and it worked so I'm not sure
curl -silent -output nul http://127.0.0.1:8282/parameter/hd1/spk/volume?set=0

do you know of any examples for libcurl
Since sarcasm is not conveyed well in text, I'll say it straight, now I'm chasing linker errors, and getting pissed off, I've avoided 3rd party libraries exactly because of this, I don't know what I'm doing, nor if what I'm reading is actually helping.

It's like I've just been taught the alphabet without being told what words mean

I tried to make a console app with the simplest example I thought was right,
I had to follow a tutorial to even use libcurl [dependencies, etc]
tried changing linker system sub system between console & windows
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <curl/curl.h>

int main(void)
{
    CURL* curl;
    CURLcode res;

    /* In windows, this will init the winsock stuff */
    curl_global_init(CURL_GLOBAL_ALL);

    /* get a curl handle */
    curl = curl_easy_init();
    if (curl) {
        /* First set the URL that is about to receive our POST. This URL can
           just as well be a https:// URL if that is what should receive the
           data. */
        curl_easy_setopt(curl, CURLOPT_URL, "127.0.0.1:8282");
        /* Now specify the POST data */
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "/parameter/hd1/spk/volume?=0");

        /* Perform the request, res will get the return code */
        res = curl_easy_perform(curl);
        /* Check for errors */
        if (res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                curl_easy_strerror(res));

        /* always cleanup */
        curl_easy_cleanup(curl);
    }
    curl_global_cleanup();
    return 0;
}


one of about 8 errors
Error LNK2019 unresolved external symbol __imp__curl_global_cleanup referenced in function _main
that is not so bad. that error means it can't find the function... at the linker level. So you probably need to add curl_something.lib to your {project? makefile? command line?} compile so it can see it. Then it should just work.
I had to follow a tutorial to even do the makefile, [was the tutorial right, IDK]

, can we not suggest cURL, winsock should be more than capable to send such a simple HTTP request
So what's in your current makefile / project?

Sooner or later, you'll need to figure out how to add 3rd party libraries to your projects if you hope to do anything interesting. So it's worth the time/pain getting to grips with it.

> if I type this into my browser, I get the desired result [lowers a slider in the program]
> http://127.0.0.1:8282/parameter/hd1/spk/volume?set=0
Sure you can do this with 'just winsock'.

This is an absolute must if you're doing any network programming.
https://www.wireshark.org/

Use it to find out what a 'get' request looks like when issued by a browser.

Then you should be able to properly mimic it just using winsock.

Send with:
1
2
std::string request = "GET /parameter/hd1/spk/volume?=0 HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n";
ssize_t nbytes = send(connection, request.c_str(), request.size(), 0);

Additionally, you must zero out addr before use.

And the socket() call really should be:
 
SOCKET connection = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
but it'll work as is.
Last edited on
@kbw - thank you but ssize_t is undefined
@@kbw changed ssize_t to size_t

compiles, connects, but the volume does not change, I'm beginning to think it's the other software.
You can run up your own http server on a different port to check your code.

Alternatively, you can connect with netcat and send that string directly, if you want to test the server. What happens when you try to connect from your browser? You can open the debug windows and examine what the browser actually sends, and what comes back.

ssize_t is a signed value, so you can get -1 back on failure. size_t is an unsigned value. If you don't have ssize_t defined, you could use an int instead,
Last edited on
@kbw thanks for the help, I had a manic moment with libcURL trying things no sane person would... and it worked, turns out the program I'm send to is pretty janky.

no tailoring required, just send the full address, I don't think it's supposed to work like that but results are results.


1
2
3
4
curl_easy_setopt(curl, CURLOPT_URL, "127.0.0.1:8282/parameter/hd1/spk/volume=0");
    // NOT NEEDED APPARENTLY curl_easy_setopt(curl, CURLOPT_HTTPGET, "/parameter/hd1/spk/volume?=0");
        /* Perform the request, res will get the return code */
        res = curl_easy_perform(curl);



THIS THREAD CANE BE LOCKED
Registered users can post here. Sign in or register to post.