uNetworking / uSockets

Miniscule cross-platform eventing, networking & crypto for async applications
Apache License 2.0
1.29k stars 268 forks source link

Basic HTTP request example #21

Closed websocket98765 closed 6 years ago

websocket98765 commented 6 years ago

A basic HTTP or HTTPS GET request example would be very useful for new users of this lib.

To try to make this, I took the load test from uWebsockets as that's the closest to an example I could find, and tried to modify it to send an HTTP GET request. But it just runs through with no output and event loop doesn't seem to be blocking. Clearly I suck, but a minimal working example would really help in the manual or ReadMe.


// Source: https://github.com/uNetworking/uWebSockets/blob/16bd859b0caf5fa96cf9cbf27b64ef4229629cf1/benchmarks/load_test.c
// Modified, attempting a simple GET request.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../uSockets/src/libusockets.h"

char request[] = "GET / HTTP/1.1\r\n"
                 "Host: google.com\r\n\r\n";
const char * host = "google.com";
int port = 80;

struct http_socket
{
  /* How far we have streamed our request */
  int offset;
};

/* Loop event callbacks. We don't need any of these. */
void on_wakeup(struct us_loop *loop)
{
  //
}

void on_pre(struct us_loop *loop)
{
  //
}

/* This is not HTTP POST, it is merely an event emitted post loop iteration */
void on_post(struct us_loop *loop)
{
  //
}

struct us_socket *on_http_socket_close(struct us_socket *s)
{
  puts("on_http_socket_close was called");
  puts("Closed!");
  return s;
}

struct us_socket *on_http_socket_end(struct us_socket *s)
{
  puts("on_http_socket_end was called");
  return us_socket_close(s);
}

struct us_socket *on_http_socket_writable(struct us_socket *s)
{
  puts("on_http_socket_writable was called");

  struct http_socket *http_socket = (struct http_socket *) us_socket_ext(s);

  /* Stream whatever is remaining of the request */
  http_socket->offset += us_socket_write(s, request + http_socket->offset, sizeof(request) - http_socket->offset, 0);

  return s;
}

struct us_socket *on_http_socket_data(struct us_socket *s, char *data, int length)
{
  puts("on_http_socket_data was called");
  puts(data);

  /* Get socket extension and the socket's context's extension */
  struct http_socket *http_socket = (struct http_socket *) us_socket_ext(s);
  struct http_context *http_context = (struct http_context *) us_socket_context_ext(us_socket_get_context(s));

  /* We treat all data events as a response */
  http_socket->offset = us_socket_write(s, request, sizeof(request), 0);

  return s;
}

struct us_socket *on_http_socket_open(struct us_socket *s, int is_client)
{
  puts("on_http_socket_open was called");

  struct http_socket *http_socket = (struct http_socket *) us_socket_ext(s);

  /* Reset offset */
  http_socket->offset = 0;

  /* Send a request */
  us_socket_write(s, request, sizeof(request) - 1, 0);

  return s;
}

struct us_socket *on_http_socket_timeout(struct us_socket *s)
{
  puts("on_http_socket_timeout was called");
  puts("Socket timeout occurred.");

  us_socket_timeout(s, LIBUS_TIMEOUT_GRANULARITY);

  return s;
}

int main()
{
  /* Create the event loop */
  struct us_loop *loop = us_create_loop(1, on_wakeup, on_pre, on_post, 0);

  // Commented out because the SSL portion causes an error.
  // ("error: cannot initialize a variable of type 'struct us_socket_context *'
  //  with an rvalue of type 'struct us_ssl_socket_context *'")
  /* Create a socket context for HTTP */
  // #ifndef LIBUS_NO_SSL
  //   // HTTPS
  //   struct us_ssl_socket_context_options ssl_options = {};
  //   struct us_socket_context *http_context = us_create_ssl_socket_context(loop, 0, ssl_options);
  // #else
  //   // HTTP
        struct us_socket_context *http_context = us_create_socket_context(loop, 0);
  // #endif

  /* Set up event handlers */
  us_socket_context_on_open(http_context, on_http_socket_open);
  us_socket_context_on_data(http_context, on_http_socket_data);
  us_socket_context_on_writable(http_context, on_http_socket_writable);
  us_socket_context_on_close(http_context, on_http_socket_close);
  us_socket_context_on_timeout(http_context, on_http_socket_timeout);
  us_socket_context_on_end(http_context, on_http_socket_end);

  /* Make an HTTP connection */
  us_socket_context_connect(http_context, host, port, 0, sizeof(struct http_socket));

  us_loop_run(loop);

  return 0;
}
ghost commented 6 years ago

This is out of scope of this project. That's what µWS is for

websocket98765 commented 6 years ago

I'm talking about making requests as a client, not setting up a server.

ghost commented 6 years ago

This is out of scope of this project. That's what µWS is for