-1

我正在尝试编写一个简单的客户端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

缓存控制:私有,max-age=0,必须重新验证,无转换

ETag:“ewDGMApuuzSJ2mUepyXm8PLTiIU/uPd2cbC0DjaL0y0Y6HiAvzSqSts”

内容类型:应用程序/json;字符集=UTF-8

X-Content-Type-Options: nosniff

X 框架选项:SAMEORIGIN

X-XSS-防护:1;模式=块

服务器:GSE


肯定有比没有更多关于炉子的信息,对吧?

4

1 回答 1

0

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

于 2013-09-05T17:14:47.850 回答