Google自定义搜索结果为C

时间:2012-05-23 05:55:25

标签: c google-search-api

我正在尝试在C中编写一个简单的客户端,该客户端将与Google Search API连接并返回搜索结果。我能够发送一个搜索请求,并获得一个200 OK代码和一些标题文本的回复,但没有搜索结果。我做错了吗?

这是我的代码:

#include sys/socket.h
#include sys/types.h
#include netinet/in.h
#include netdb.h
#include stdio.h
#include string.h
#include stdlib.h
#include unistd.h
#include errno.h
#include openssl/rand.h
#include openssl/ssl.h
#include openssl/err.h

// Simple structure to keep track of the handle, and
// of what needs to be freed later.
typedef struct {
    int socket;
    SSL *sslHandle;
    SSL_CTX *sslContext;
} connection;

// For this example, we'll be testing on openssl.org
#define KEY     "/customsearch/v1?key=AIzaSyAOdB5MgAEmvzglw05rR1OPYEYgFuZrT9o&cx=003397780648636422832:u25rx3s92ro&q="
#define SERVER  "www.googleapis.com"
#define PORT 443

// Establish a regular tcp connection
int tcpConnect ()
{
  int error, handle;
  struct hostent *host;
  struct sockaddr_in server;

  host = gethostbyname (SERVER);
  handle = socket (AF_INET, SOCK_STREAM, 0);
  if (handle == -1)
    {
      perror ("Socket");
      handle = 0;
    }
  else
    {
      server.sin_family = AF_INET;
      server.sin_port = htons (PORT);
      server.sin_addr = *((struct in_addr *) host->h_addr);
      bzero (&(server.sin_zero), 8);

      error = connect (handle, (struct sockaddr *) &server,
                       sizeof (struct sockaddr));
      if (error == -1)
        {
          perror ("Connect");
          handle = 0;
        }
    }

  return handle;
}

// Establish a connection using an SSL layer
connection *sslConnect (void)
{
  connection *c;

  c = malloc (sizeof (connection));
  c->sslHandle = NULL;
  c->sslContext = NULL;

  c->socket = tcpConnect ();
  if (c->socket)
    {
      // Register the error strings for libcrypto & libssl
      SSL_load_error_strings ();
      // Register the available ciphers and digests
      SSL_library_init ();

      // New context saying we are a client, and using SSL 2 or 3
      c->sslContext = SSL_CTX_new (SSLv23_client_method ());
      if (c->sslContext == NULL)
        ERR_print_errors_fp (stderr);

      // Create an SSL struct for the connection
      c->sslHandle = SSL_new (c->sslContext);
      if (c->sslHandle == NULL)
        ERR_print_errors_fp (stderr);

      // Connect the SSL struct to our connection
      if (!SSL_set_fd (c->sslHandle, c->socket))
        ERR_print_errors_fp (stderr);

      // Initiate SSL handshake
      if (SSL_connect (c->sslHandle) != 1)
        ERR_print_errors_fp (stderr);
    }
  else
    {
      perror ("Connect failed");
    }

  return c;
}

// Disconnect & free connection struct
void sslDisconnect (connection *c)
{
  if (c->socket)
    close (c->socket);
  if (c->sslHandle)
    {
      SSL_shutdown (c->sslHandle);
      SSL_free (c->sslHandle);
    }
  if (c->sslContext)
    SSL_CTX_free (c->sslContext);

  free (c);
}

// Read all available text from the connection
char *sslRead (connection *c)
{
  const int readSize = 2048;
  char *rc = NULL;
  int received, count = 0;
  char buffer[2048];

  if (c)
    {
      while (1)
        {
          if (!rc)
            rc = malloc (readSize * sizeof (char) + 1);
          else
            rc = realloc (rc, (count + 1) *
                          readSize * sizeof (char) + 1);

          received = SSL_read (c->sslHandle, buffer, readSize);
          buffer[received] = '\0';

          if (received > 0)
            strcat (rc, buffer);

          if (received < readSize)
            break;
          count++;
        }
    }

  return rc;
}

// Write text to the connection
void sslWrite (connection *c, char *text)
{
  if (c)
    SSL_write (c->sslHandle, text, strlen (text)
}

// Very basic main: we send GET / and print the response.
int main (int argc, char **argv)
{
  connection *c;
  char *response;
  char request[512]="";

  c = sslConnect ();

  sprintf(request, "GET https://%s%s%s\r\n\r\n", SERVER, KEY, argv[1]);
  printf("%s", request);

  sslWrite (c, request);

  response = sslRead (c);

  printf ("%s\n", response);

  sslDisconnect (c);
  free (response);

  return 0;
}

以下是我的结果(运行“app_name灶具”):

  

¸hÆÁ* HTTP / 1.0 200 OK

     

到期日:2012年5月23日星期三05:49:58 GMT

     

日期:2012年5月23日星期三05:49:58 GMT

     

Cache-Control:private,max-age = 0,must-revalidate,no-transform

     

ETag:“ewDGMApuuzSJ2mUepyXm8PLTiIU / uPd2cbC0DjaL0y0Y6HiAvzSqSts”

     

Content-Type:application / json;字符集= UTF-8

     

X-Content-Type-Options:nosniff

     

X-Frame-Options:SAMEORIGIN

     

X-XSS-Protection:1;模式=块

     

服务器:GSE


肯定有更多关于炉灶的信息,对吧?

1 个答案:

答案 0 :(得分:0)

上面代码中的两个问题是#1)rc的开始在malloc之后和使用strcat之前没有初始化为零 - 这导致了垃圾字符和#2)行if (received < readSize)应该是if (received == 0),因为服务器可能会将标头和内容作为单独的块发送。