• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 327
  • Last Modified:

Trouble with sockets CGI program

I have written a rather simple C program to submit certain information to a CGI script. However, I have tried and the program fails to work properly... Are there any problems with the program which will affect its ability to send the information to the CGI script?
(The cgi script is located at: http://www-cgi.monash.edu.au/cgi-bin/cgiwrap/~tatjana/TestCGI, and all it does is print out the contents of the form passed to it, either GET or POST is supported. This program is meant to do exactly what the browser does, and send the information to the CGI script.)

Here is the program:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORT 80    /* the port client will be connecting to */

#define MAXDATASIZE 2000 /* max number of bytes we can get at once */

int main(int argc, char *argv[])
{
int sockfd, numbytes;
int len, bytes_sent, sent, total_sent = 0;
char buf[MAXDATASIZE];
struct hostent *he;
char *msg = "POST /cgi-bin/cgiwrap/~tatjana/TestAnswer HTTP/1.0\r\nContent_type:
application/x-www-form-urlencoded\r\nContent_length:52\r\n\r\nintlPrefix=%2B6100
4&TEL=%2B61000123454&Message=TEST2";
struct sockaddr_in their_addr; /* connector's address information */

if (argc != 2) {
     fprintf(stderr,"usage: client hostname\n");
     exit(1);
}

if ((he=gethostbyname(argv[1])) == NULL) {  /* get the host info */
      herror("gethostbyname");
      exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
      perror("socket");
      exit(1);
}

their_addr.sin_family = AF_INET;      /* host byte order */
their_addr.sin_port = htons(PORT);    /* short, network byte order */
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */

if (connect(sockfd, (struct sockaddr *)&their_addr, \
                             sizeof(struct sockaddr)) == -1) {
      perror("connect");
      exit(1);
}

len = strlen(msg);
bytes_sent = send(sockfd, msg, len, 0);
if (bytes_sent < len)
{
        total_sent += bytes_sent;
        sent = bytes_sent;
        do {
                len = strlen(msg);
                bytes_sent = send(sockfd, msg+sent, len, 0);
        } while (bytes_sent < len);
}
else
        total_sent = bytes_sent;
printf("\nBYTES SENT: %d", total_sent);
if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
      perror("recv");
      exit(1);
}

buf[numbytes] = '\0';
printf("NUMBER OF BYTES RECEIVED: %d", numbytes);
printf("Received: %s",buf);
if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
      perror("recv");
      exit(1);
}
close(sockfd);

return 0;
}

0
idek1
Asked:
idek1
  • 2
1 Solution
 
rdelfinoCommented:

Instead of trying to receive all the response in one/two recv() call(s)
do the following to receive the server response

----8<----------

while ((numbytes = recv(sockfd, buf, MAXDATASIZE, 0)) > 0)
{
    /*
      do whatever you need with the buffer,
      I suggest you append the buffer to a file and procces the file
      after the loop ends
   */
}

close(sockfd);

----8<-----

this way you won't miss anything the server sends you.

I hope this helps

Reginaldo

0
 
idek1Author Commented:
rdelfino,
The code is appreciated, however, it only tunes up the receiving part of the program. I believe the problem must lie either in the sending part of the program or in the information being sent to the server...
At the moment, when the program is run, the server responds with "Bad Request, Your browser sent a query that this server could not understand."
When running the program I use command:
client www-cgi.monash.edu.au

0
 
rdelfinoCommented:

So the problem isn't a socket problem. It's a protocol error. The request you sent
to the server is not correct.

See RFC2068 for complete http1.1 specification. You can find it at

http://www.rfc-editor.org/

I hope now it helps

Reginaldo

0
 
mliberiCommented:
Yes, it is a protocol error.
You declared: char *msg=" ... Content_length:52 ..."

please replace the underscore with a minus.
So declare  : char *msg=" ... Content-length:52 ..."
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now