Send Http “Post” Request To Php Code in C or C++

2020-03-30 04:54发布

问题:

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 )

回答1:

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).



回答2:

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).