2

I'm trying to send a "post" reguest to my php file and get the info back, it works fine, but

it also print something before printing my response from the php file. this is what it print

first:

HTTP/1.1 200 OK
Date: Fri, 20 Apr 2012 10:19:12 GMT
Server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
X-Powered-By: PHP/5.3.6
Content-Length: 12
Connection: close
Content-Type: text/html

and then my response:

hello world

how can i only print what i'm getting from myphp code, without:

HTTP/1.1 200 OK
Date: Fri, 20 Apr 2012 10:19:12 GMT
Server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
X-Powered-By: PHP/5.3.6
Content-Length: 12
Connection: close
Content-Type: text/html

the code i'm using is:

#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netdb.h>
#include <unistd.h>

#define SA      struct sockaddr
#define MAXLINE 4096
#define MAXSUB  200


#define LISTENQ         1024

extern int h_errno;


ssize_t process_http(int sockfd, char *host, char *page, char *poststr)
{
     char sendline[MAXLINE + 1], recvline[MAXLINE + 1];
    ssize_t n;
    snprintf(sendline, MAXSUB,
             "POST %s HTTP/1.0\r\n"
             "Host: %s\r\n"
             "Content-type: application/x-www-form-urlencoded\r\n"
             "Content-length: %d\r\n\r\n"
             "%s", page, host, strlen(poststr), poststr);

    write(sockfd, sendline, strlen(sendline));
    while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
        recvline[n] = '\0';
        printf("%s", recvline);  // <-- this
    }
    return n;

}





int main(void)
{



    int sockfd;
    struct sockaddr_in servaddr;

    char **pptr;
    //********** You can change. Puy any values here *******
    char *hname = "localhost";
    char *page = "/mysql_update.php";
    char *poststr = "server=dd sd sdsdt\n";
    //*******************************************************

    char str[50];
    struct hostent *hptr;
    if ((hptr = gethostbyname(hname)) == NULL) {
        fprintf(stderr, " Server down error for host: %s: %s",
                hname, hstrerror(h_errno));
        exit(1);
    }
    printf("hostname: %s \n", hptr->h_name);
    if (hptr->h_addrtype == AF_INET
        && (pptr = hptr->h_addr_list) != NULL) {
        printf("address: %s\n",
               inet_ntop(hptr->h_addrtype, *pptr, str,
                         sizeof(str)));
    } else {
        fprintf(stderr, "Error call inet_ntop \n");
    }

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(80);
    inet_pton(AF_INET, str, &servaddr.sin_addr);

    connect(sockfd, (SA *) & servaddr, sizeof(servaddr));
    process_http(sockfd, hname, page, poststr);
    close(sockfd);
    exit(0);


}

Please help me to fix this problem, step by step so' i can understand it, give me information and please if you can' show me a example. ( this will help me and others )

4
  • 3
    It would probably be useful if you learned a bit on how the http protocol works, and what a header is. Commented Apr 20, 2012 at 10:37
  • I'm sure are right, but that really did not answer anything or help me out. Commented Apr 20, 2012 at 10:38
  • 2
    PlasmaHH is right and what he says lights your way. You can not expect a complete solution on your lap... Commented Apr 20, 2012 at 11:41
  • Isn't this a duplicate of stackoverflow.com/questions/2395207/… Commented Apr 20, 2012 at 11:44

2 Answers 2

6

First part of the response you received is made up of HTTP version, Server Response Status Code and various HTTP response headers.

HTTP/1.1 200 OK Date: Fri, 20 Apr 2012 10:19:12 GMT Server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6 X-Powered-By: PHP/5.3.6 Content-Length: 12 Connection: close Content-Type: text/html

After headers follows HTTP response body (which you need to extract):

hello world

HTTP headers and body are separated with the following sequence of characters: \r\n\r\n. So all you need to do is to search for it and extract everything that is behind it.

You can do this yourself (sockets, parsing...) but my advice is to use some of HTTP libraries: WinInet, WinHttp (both are Microsoft's) or libCurl (open source).

Sign up to request clarification or add additional context in comments.

4 Comments

Your incoming message is short so I guess you're receiving it in a single iteration in a loop (but don't rely on this! - TCP can break sent message in many smaller packets) and after it your recvline buffer contains entire response message. Just search for a sequence \r\n\r\n in the buffer and extract all characters after it. Btw, better and safer approach would be storing incoming characters in std::string or std::vector<char> as you can dynamically resize them depending on the number of bytes received.
And here you have an example of how easy and quick is to extract body from a HTTP response by using WinHTTP: msdn.microsoft.com/en-us/library/windows/desktop/…
the problem is. that i'm using mac
libCurl is the option in that case
1

The responses header bit is separated from the content by a blank line.

Need to take into account different line endings. Basically ignore \rs.

So 1st read lines until you get a blank one then start printing them!

EDIT

You have a response as follows

HTTP/1.1 200 OK
Date: Fri, 20 Apr 2012 10:19:12 GMT
...
Content-Type: text/html

Hello World

Notice that there is a blank line between the HTTP headers and the response (HTML in this case).

4 Comments

I dont understand really, could you explain more, please point to the problem also and with code i would get it better my friend
Before your while loop set a boolean to false. Before doing the printf check to see if you have a blank line. If so, set the boolean to true. Then only do the printf if that boolean is true.
i cant see a blank line i tried: ssize_t process_http(int sockfd, char *host, char *page, char *poststr) { char sendline[MAXLINE + 1], recvline[MAXLINE + 1]; ssize_t n; snprintf(sendline, MAXSUB, "POST %s HTTP/1.0\r\n" "Host: %s\r\n" "Content-type: application/x-www-form-urlencoded\r\n" "Content-length: %d\r\n\r\n" "%s", page, host, strlen(poststr), poststr); write(sockfd, sendline, strlen(sendline)); while ( 0) { recvline[n] = '\0'; printf("%s", recvline); // <-- this } n = read(sockfd, recvline, MAXLINE); printf("%s", recvline); // <-- this return n; }
Try using fiddler (google it!) to find out and learn what is going on when you use a browser. It will give you pointers on how to mimic it in C++. Also read the spec for HTTP. I think that you request is incorrect as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.