Solved

Trouble with sockets CGI program

Posted on 1999-01-07
4
266 Views
Last Modified: 2013-12-26
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
Comment
Question by:idek1
  • 2
4 Comments
 
LVL 2

Expert Comment

by:rdelfino
ID: 1295259

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
 

Author Comment

by:idek1
ID: 1295260
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
 
LVL 2

Expert Comment

by:rdelfino
ID: 1295261

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
 
LVL 3

Accepted Solution

by:
mliberi earned 100 total points
ID: 1295262
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

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It's sometimes a bit tricky to use date functions in Oracle BPEL. I'll explain quickly how you can add N days to the current date. In a BPEL process this can be useful, and you can adapt it to fit your needs. First of all, let's see how to add 1 …
Shoutout to Emily Plummer (http://www.experts-exchange.com/members/eplummer26.html) for giving me this article! She did most of it, I just finished it up and posted it for her :)    Introduction In a previous article (http://www.experts-exchang…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now