3

How can I write simple HTTP request and response in C language.

In Java I can use :

    String url = "http://www.google.com/search?q=mkyong";

    URL obj = new URL(url);
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();

    con.setRequestMethod("GET");

    con.setRequestProperty("User-Agent", USER_AGENT);

    int responseCode = con.getResponseCode();
    System.out.println("\nSending 'GET' request to URL : " + url);
    System.out.println("Response Code : " + responseCode);

    BufferedReader in = new BufferedReader(
            new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();

How can I do it using C language ?

I already try Here : But it not properly work.

response mostly :

HTTP/1.1 301 Moved Permanently Location: http://www.google.co.in/ Content-Type: text/html; charset=UTF-8 Date: Mon, 27 Jun 2016 13:53:36 GMT Expires: Wed, 27 Jul 2016 13:53:36 GMT Cache-Control: public, max-age=2592000 Server: gws Content-Length: 221 X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>301 Moved</TITLE></HEAD><BODY> <H1>301 Moved</H1> The document has moved <A HREF="http://www.google.co.in/">here</A>. </BODY></HTML>
Arya GM
  • 81
  • 1
  • 9
  • What exactly did not work in what you tried? – s7amuser Jun 27 '16 at 13:46
  • [This Link](http://coding.debuntu.org/c-linux-socket-programming-tcp-simple-http-client) – Arya GM Jun 27 '16 at 13:46
  • 5
    What do you mean by "not properly work"? What did you try and what happened? Posting a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) in your question itself is good. – MikeCAT Jun 27 '16 at 13:47
  • 1
    http://stackoverflow.com/questions/22077802/simple-c-example-of-doing-an-http-post-and-consuming-the-response – Ishay Peled Jun 27 '16 at 13:47
  • For example, I set Hostname "google.co.in" the output response not a google home HTML page and response code is not 200 – Arya GM Jun 27 '16 at 13:50
  • 2
    It would be preferable that you copy paste your current C code instead of your old java code, and explain us what did you expect and what you got – Garf365 Jun 27 '16 at 13:51
  • 2
    Use [`libcurl`](https://curl.haxx.se/libcurl/c/). – John Bode Jun 27 '16 at 13:54
  • 2
    Did you read the response got? What if you try `www.google.co.in`? – MikeCAT Jun 27 '16 at 13:58
  • Please define "work". What do you expect? – MikeCAT Jun 27 '16 at 14:09
  • The program is working well. The response is just like what my Google Chrome got when I type `google.co.in` to its address bar and hit the Enter key. – MikeCAT Jun 27 '16 at 14:12
  • Here are [a part of request from Google Chrome](http://i.imgur.com/zWTuVhY.png) and [a part of responce for the request](http://i.imgur.com/FS4sOuo.png). – MikeCAT Jun 27 '16 at 14:17
  • Linking code is disliked at SO. And ... well ... "*it's not working*" is not a useful trouble report, to not say the worth you could deliver. – alk Jun 27 '16 at 17:29

1 Answers1

2

You will need an external library to solve your problem and libcurl is an excellent alternative.

Give a try in this piece of (tested) code:

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

#include <curl/curl.h>


typedef struct string_buffer_s
{
    char * ptr;
    size_t len;
} string_buffer_t;


static void string_buffer_initialize( string_buffer_t * sb )
{
    sb->len = 0;
    sb->ptr = malloc(sb->len+1);
    sb->ptr[0] = '\0';
}


static void string_buffer_finish( string_buffer_t * sb )
{
    free(sb->ptr);
    sb->len = 0;
    sb->ptr = NULL;
}


static size_t string_buffer_callback( void * buf, size_t size, size_t nmemb, void * data )
{
    string_buffer_t * sb = data;
    size_t new_len = sb->len + size * nmemb;

    sb->ptr = realloc( sb->ptr, new_len + 1 );

    memcpy( sb->ptr + sb->len, buf, size * nmemb );

    sb->ptr[ new_len ] = '\0';
    sb->len = new_len;

    return size * nmemb;

}


static size_t header_callback(char * buf, size_t size, size_t nmemb, void * data )
{
    return string_buffer_callback( buf, size, nmemb, data );
}


static size_t write_callback( void * buf, size_t size, size_t nmemb, void * data )
{
    return string_buffer_callback( buf, size, nmemb, data );
}


int main( int argc, char * argv[] )
{
    CURL * curl;
    CURLcode res;
    string_buffer_t strbuf;

    char * myurl = argv[1];

    string_buffer_initialize( &strbuf );

    curl = curl_easy_init();

    if(!curl)
    {
        fprintf(stderr, "Fatal: curl_easy_init() error.\n");
        string_buffer_finish( &strbuf );
        return EXIT_FAILURE;
    }

    curl_easy_setopt(curl, CURLOPT_URL, myurl );
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L );
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback );
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback );
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &strbuf );
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &strbuf );

    res = curl_easy_perform(curl);

    if( res != CURLE_OK )
    {
        fprintf( stderr, "Request failed: curl_easy_perform(): %s\n", curl_easy_strerror(res) );

        curl_easy_cleanup( curl );
        string_buffer_finish( &strbuf );

        return EXIT_FAILURE;
    }

    printf( "%s\n\n", strbuf.ptr );

    curl_easy_cleanup( curl );
    string_buffer_finish( &strbuf );

    return EXIT_SUCCESS;
}

/* eof */

If libcurl is not installed yet (curl.h cannot be found):

$ sudo apt-get install libcurl4-openssl-dev

Compiling (gcc/linux):

$ gcc -Wall httpget.c -lcurl -o httpget

Testing:

$ ./httpget "http://www.google.com/search?q=mkyong"
Lacobus
  • 1,590
  • 12
  • 20