buffer in recv function empty when receiving HTTP request from browser.

My program is supposed to work as a proxy to listen to HTTP request comming from my browser and pass it on to the internet as well as receiving answers from the web to the browser.
All I want at the moment is to read the header from a HTTP request comming from my browser. At the moment this is what I have:

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <string>
#include <cstring>
#include <iostream>
#include <unistd.h>
#include "AppSocket.hpp"

#define buff_size 1024*1024

void AppSocket::Start(int port) {
  // Create a socket
  listening_fd = socket(AF_INET, SOCK_STREAM, 0); // AF_INET is for IPv4
  if (listening_fd == -1) {  //something wrong happened
    std::cerr << "Could not create a socket." << std::endl;
    exit(-1);
  }
  // Bind the socket to an IP/port
        // Binding informatioin
  app_hint.sin_family = AF_INET;   //IPv4
  app_hint.sin_port = htons(port); // htons (host to network short)
                                      // flips the bits to lendian or bendian
                                      // depending on the processor it's running on
  inet_pton(AF_INET, "127.0.0.1", &app_hint.sin_addr);  //"0.0.0.0 -> any address in this machine"
                                                  //pton will convert IPv4 addr to binary
        // Actual binding process
          //socket    format
  if ( bind(listening_fd, (sockaddr*)&app_hint, sizeof(app_hint)) < 0 ) {
      std::cerr << "Cannot bind to IP/port." << std::endl;
      exit(-2);
  }
  std::cout << "Socket has been bound." << std::endl;

   // Mark the socket for listening
  if (listen(listening_fd, SOMAXCONN) == -1) {    //SOMAXCONN -> maximum number of connections
      std::cerr << "Cannot listen." << std::endl;
      exit(-3);
  }

  std::cout << "Listening to port " << port << std::endl;
  std::cout << "Your socket is: " << listening_fd << std::endl;
}

// Mark the socket for listening
void AppSocket::AcceptCall() {

  std::cout << "At AcceptCall " << std::endl;
  std::cout << "Your socket is: " << listening_fd << std::endl;

  client_size = sizeof(client_addr);
  client_fd = accept(listening_fd, (sockaddr *)&client_addr, &client_size);

  // Accept a call
  if (client_fd < 0) {
    std::cerr << "Error connecting to client." << std::endl;
    exit(-4);
  }

  std::cout << inet_ntoa(client_addr.sin_addr) << " connected to port "
            << ntohs(client_addr.sin_port) << std::endl;

  close(listening_fd);
}

int AppSocket::ReceiveRequest(char *buffer, int max) {

  std::cout << "We are here! c:" << std::endl;
  std::cout << "Client file descriptor is: " << client_fd << std::endl;
  memset(buffer, 0, buff_size);    //clear buffer

  int n = recv(client_fd, buffer, buff_size, 0);
  if (n < 0)
    std::cerr << "A connection issue has occured." << std::endl;

  if (n == 0)
    std::cout << "Client disconected." << std::endl;

  std::cout << "recv return " << n << std::endl;
  std::cout << buffer << std::endl;
  // this just echos the message bach to browser, end of story
  //send(client_fd, buffer, n + 1, 0);

  return 0;
}

AppSocket::~AppSocket() {
  if (listening_fd)
    close(listening_fd);
  if (client_fd)
    close(client_fd);
}


The recv function returns 3 but the buffer is empty... I ran gdb and is shows the memory as just "".
This only happens when I request a actual webpage, when I run a localhost it works just fine I receive the GET requests. What could it be?

Last edited on
Weird, your code looks OK other than not zero'ing app_hint (probably done outside the code).

It is also possible that the first byte is a null character and you can print more data by doing something like std::string_view(buffer, n), but I don't think that is valid html.

It may also be possible your buffer size is too big and the reason why it worked in localhost was because the max packet size is 63000, but then again, your packet size is 1 million bytes long.

I assume this code is for a server, since you are binding and listening, but your explanation confuses me since you have a browser, but to me it looks like just an echo server.

The only weird thing is that you are specifying and converting localhost as the IP, but you can also use htonl(INADDR_ANY), not sure if that is the source of the problem, but your comment also says //0.0.0.0 -> any address in this machine , but your actual code is different (0.0.0.0 is INADDR_ANY).

If that doesn't help, from my knowledge when you deal with http you should use libcurl, so perhaps that could maybe help you, and could solve some problems in the long run.

I think this prints out the whole html document
https://curl.haxx.se/libcurl/c/getinmemory.html

And for getting just the GET feedback you can combine the above with this.
https://curl.haxx.se/libcurl/c/CURLOPT_HTTPGET.html

I don't use curl but that should be the general gist of it.
1
2
3
4
5
6
7
int AppSocket::ReceiveRequest(char *buffer, int max) {

  std::cout << "We are here! c:" << std::endl;
  std::cout << "Client file descriptor is: " << client_fd << std::endl;
  memset(buffer, 0, buff_size);    //clear buffer

  int n = recv(client_fd, buffer, buff_size, 0);

Why are you using buff_size and not the max parameter?

Sorry for taking so long.

So... I figured it out. It was my browser's proxy settings... turns out I configured it wrongly... it took me a long time to realise that because the port I configured the proxy was right, so apperently when I sent a http request it actually tried to use my proxy server as the actual server for the web site but must be sending the data in a weird way. If anyone cares to know.

I assume this code is for a server, since you are binding and listening, but your explanation confuses me since you have a browser, but to me it looks like just an echo server.

It used to echo back to the browser just so I could test the connectivity while still in 'localhost' development phases.

Why are you using buff_size and not the max parameter?

I guess, since I was getting segfault, I changed it at some point, I'm using max now.

The code works, thank you all for your replies!
Last edited on
Topic archived. No new replies allowed.