Submit data p/ database via SOCK_STREAM

Asked

Viewed 24 times

1

Hello, I need to create a function that should connect to port 80 of the server "servername" send a request in which the list of parameters/ values of the POST request is defined based on its parameters. Only after the execution of the function, the value inserted in the parameters is not being inserted in the form (PHP) of the server, even if they are contained in the buffer.

#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int my_connect(char *servername, char *port);
void recv_server_reply(int s);
void submeter_dados(char *servername, char *uri, char *plate, char *owner, double value);

char http_msg[] = 
    "POST %sHTTP/1.1\r\n"
    "Host: %s\r\n"
    "Content-Type: application/x-www-form-urlencoded\r\n"
    "Content-Length: %ld\r\n"
    "Connection: close\r\n"
    "\r\n"
    "%s";

int main (int argc, char* const argv[]) {

  //enviar dados
  submeter_dados("servidor.pt", "/ficheiro/redirecionado/peloformulario", "PL1819", "John", 5000.0);

  return 0;
}


void recv_server_reply(int s) 
{
  char buf[4096];

  printf("Reply from server: ");
  while(1) 
  {
    int n = read(s, buf, 1);
    if(n <= 0)
      break;
    putchar(buf[0]);
    fflush(stdout);
    if(buf[0]=='\n')
      printf(": ");
  }


  printf("\n\n");
}


int my_connect(char *servername, char *port) {

  //get server address using getaddrinfo
  struct addrinfo hints;
  struct addrinfo *addrs;
  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_family = AF_INET;
  int r = getaddrinfo(servername, port, &hints, &addrs);
  if (r != 0) {
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(r));
    exit(1);
  }

  //create socket
  int s = socket(AF_INET, SOCK_STREAM, 0);
  if (s == -1) {
    perror("socket");  
    exit(2);
  }

  //connect to server
  r = connect(s, addrs->ai_addr, addrs->ai_addrlen);
  if (r == -1) {
    perror("connect");  
    close(s);
    exit(3);
  }

  return s;
}

void submeter_dados(char *servername, char *uri, char *plate, char *owner, double value){
    int sd = my_connect(severname, "80");

    char params[4096];
    char buffer[1000];
    sprintf(params, "plate=%.6s&owner=%s&value=%.2lf", plate, owner, value);
    snprintf(buffer, sizeof(buffer), http_msg, uri, servername, strlen(params), params);

    write(sd, buffer, strlen(buffer));

    recv_server_reply(sd);
}

Thanks for the help!

1 answer

1


In http_msg, there seems to be a gap between %s and HTTP/1.1 missing. This is enough for the server not to recognize the page you are trying to access.

Fixing this example seems to work and the server receives the parameters (tested against a test server done in Express/Node.js).

Also note that you are using the write() function incorrectly for sockets. You would have to do something similar to read(), go calling write() and analyze the return value, until you write all the contents of the buffer. It is not what causes your problem at the moment because your request has few bytes and ends up being transmitted in a single call to write(), but it would be enough to be a little bigger to break again.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.