add-api-documentation-comments.patch
authorAndy Green <andy@warmcat.com>
Sun, 31 Oct 2010 12:42:52 +0000 (12:42 +0000)
committerAndy Green <andy@warmcat.com>
Sun, 31 Oct 2010 12:42:52 +0000 (12:42 +0000)
Signed-off-by: Andy Green <andy@warmcat.com>
libwebsockets.c
libwebsockets.h
test-server.c

index 7fcf4e1..05be153 100644 (file)
@@ -95,7 +95,8 @@ struct lws_tokens {
 
 /*
  * This is totally opaque to code using the library.  It's exported as a
- * forward-reference pointer-only declaration.
+ * forward-reference pointer-only declaration; the user can use the pointer with
+ * other APIs to get information out of it.
  */
 
 struct libwebsocket {
@@ -130,6 +131,27 @@ const struct lws_tokens lws_tokens[WSI_TOKEN_COUNT] = {
        { "\x0d\x0a", 2 },
 };
 
+/**
+ * libwebsocket_create_server() - Create the listening websockets server
+ * @port:      Port to listen on
+ * @callback:  The callback in user code to perform actual serving
+ * @protocol:  Which version of the websockets protocol (currently 76)
+ * 
+ *     This function forks to create the listening socket and takes care
+ *     of all initialization in one step.
+ * 
+ *     The callback function is called for a handful of events including
+ *     http requests coming in, websocket connections becoming
+ *     established, and data arriving; it's also called periodically to allow
+ *     async transmission.
+ * 
+ *     The server created is a simple http server by default; part of the
+ *     websocket standard is upgrading this http connection to a websocket one.
+ * 
+ *     This allows the same server to provide files like scripts and favicon /
+ *     images or whatever over http and dynamic data over websockets all in
+ *     one place; they're all handled in the user callback.
+ */
 
 int libwebsocket_create_server(int port,
                int (*callback)(struct libwebsocket *,
@@ -238,7 +260,7 @@ int libwebsocket_create_server(int port,
        }
 }
 
-void libwebsocket_close(struct libwebsocket *wsi)
+static void libwebsocket_close(struct libwebsocket *wsi)
 {
        int n;
 
@@ -252,6 +274,16 @@ void libwebsocket_close(struct libwebsocket *wsi)
                        free(wsi->utf8_token[n].token);
 }
 
+/**
+ * libwebsocket_get_uri() - Return the URI path being requested
+ * @wsi:       Websocket instance
+ * 
+ *     The user code can find out the local path being opened from this
+ *     call, it's valid on HTTP or established websocket connections.
+ *     If the client opened the connection with "http://127.0.0.1/xyz/abc.d"
+ *     then this call will return a pointer to "/xyz/abc.d"
+ */
+
 const char * libwebsocket_get_uri(struct libwebsocket *wsi)
 {
        if (wsi->utf8_token[WSI_TOKEN_GET_URI].token)
@@ -509,7 +541,8 @@ static int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi,
  * machine that is completely independent of packet size.
  */
 
-int libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len)
+static int 
+libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len)
 {
        size_t n;
        char *p;
@@ -667,14 +700,29 @@ bail:
        return -1;
 }
 
-
-/*
- * notice, we will use up to LWS_SEND_BUFFER_PRE_PADDING bytes BEFORE the
- * buffer pointer given and LWS_SEND_BUFFER_POST_PADDING bytes AFTER
- * buf + len !!!  Caller must allocate and offset pointer accordingly!
+/**
+ * libwebsocket_write() - Apply protocol then write data to client
+ * @wsi:       Websocket instance (available from user callback)
+ * @buf:       The data to send.  For data being sent on a websocket
+ *             connection (ie, not default http), this buffer MUST have
+ *             LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer
+ *             and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid
+ *             in the buffer after (buf + len).  This is so the protocol
+ *             header and trailer data can be added in-situ.
+ * @len:       Count of the data bytes in the payload starting from buf
+ * @protocol:  Use LWS_WRITE_HTTP to reply to an http connection, and one
+ *             of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate
+ *             data on a websockets connection.  Remember to allow the extra
+ *             bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT
+ *             are used.
+ *
+ *     This function provides the way to issue data back to the client
+ *     for both http and websocket protocols.
  * 
- * This lets us send packets in one write() action including the protocol
- * pre- and post- data without copying the payload around.
+ *     In the case of sending using websocket protocol, be sure to allocate
+ *     valid storage before and after buf as explained above.  This scheme
+ *     allows maximum efficiency of sending data and protocol in a single
+ *     packet while not burdening the user code with any protocol knowledge.
  */
 
 int libwebsocket_write(struct libwebsocket * wsi, unsigned char *buf,
@@ -871,6 +919,17 @@ pout:
        }
 }
 
+/**
+ * libwebsockets_serve_http_file() - Send a file back to the client using http
+ * @wsi:               Websocket instance (available from user callback)
+ * @file:              The file to issue over http
+ * @content_type:      The http content type, eg, text/html
+ * 
+ *     This function is intended to be called from the callback in response
+ *     to http requests from the client.  It allows the callback to issue
+ *     local files down the http link in a single step.
+ */
+
 int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char * file,
                                                      const char * content_type)
 {
index 6ecccd1..ecd837f 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef __LIBWEBSOCKET_H__
+#define __LIBWEBSOCKET_H__
+
 
 enum libwebsocket_callback_reasons {
        LWS_CALLBACK_ESTABLISHED,
@@ -33,12 +36,12 @@ extern int libwebsocket_create_server(int port,
  * So for example you need this kind of code to use libwebsocket_write with a
  * 128-byte payload 
  * 
- * char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
+ *   char buf[LWS_SEND_BUFFER_PRE_PADDING + 128 + LWS_SEND_BUFFER_POST_PADDING];
  * 
- * // fill your part of the buffer... for example here it's all zeros
- * memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
+ *   // fill your part of the buffer... for example here it's all zeros
+ *   memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 0, 128);
  * 
- * libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128);
+ *   libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], 128);
  * 
  * When sending LWS_WRITE_HTTP, there is no protocol addition and you can just
  * use the whole buffer without taking care of the above.
@@ -52,6 +55,9 @@ libwebsocket_write(struct libwebsocket *, unsigned char *buf, size_t len,
                                     enum libwebsocket_write_protocol protocol);
 extern const char *
 libwebsocket_get_uri(struct libwebsocket *wsi);
+
 extern int
 libwebsockets_serve_http_file(struct libwebsocket *wsi, const char * file,
                                                     const char * content_type);
+
+#endif
index 5bbda6f..4c16e2c 100644 (file)
@@ -4,7 +4,6 @@
 #include <getopt.h>
 #include <string.h>
 
-
 #include "libwebsockets.h"
 
 /*
  * Shows how to use libwebsocket 
  */
 
-
 static int port = 7681;
 static int ws_protocol = 76;
 
+/*
+ * libwebsockets needs this one callback in your server application, it's
+ * called for a handful of different reasons during the connection lifecycle.
+ * 
+ * All the serving actions occur in the callback but the websocket protocol
+ * stuff is already handled by the library.
+ */
+
 static int websocket_callback(struct libwebsocket * wsi,
-              enum libwebsocket_callback_reasons reason, void *in, size_t len)
+               enum libwebsocket_callback_reasons reason, void *in, size_t len)
 {
        int n;
-       char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 + LWS_SEND_BUFFER_POST_PADDING];
+       char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
+                                                 LWS_SEND_BUFFER_POST_PADDING];
        static int bump;
-       static int slow;
        char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
        const char *uri;
        
        switch (reason) {
+       /*
+        * Websockets session handshake completed and is established
+        */
        case LWS_CALLBACK_ESTABLISHED:
                fprintf(stderr, "Websocket connection established\n");
-               slow = 100;
                break;
 
+       /*
+        * Websockets session is closed
+        */
        case LWS_CALLBACK_CLOSED:
                fprintf(stderr, "Websocket connection closed\n");
                break;
 
+       /*
+        * Opportunity for us to send something on the connection
+        */
        case LWS_CALLBACK_SEND: 
-//             slow--;
-//             if (slow) {
-//                     usleep(10000);
-//                     break;
-//             }
-//             slow = 20;
                n = sprintf(p, "%d", bump++);
                n = libwebsocket_write(wsi, (unsigned char *)p, n, 0);
                if (n < 0) {
@@ -51,38 +59,43 @@ static int websocket_callback(struct libwebsocket * wsi,
                        exit(1);
                }
                break;
-
+       /*
+        * Something has arrived for us on the connection, it's len bytes long
+        * and is available at *in
+        */
        case LWS_CALLBACK_RECEIVE:
                fprintf(stderr, "Received %d bytes payload\n", (int)len);
                break;
+
+       /*
+        * The client has asked us for something in normal HTTP mode,
+        * not websockets mode.  Normally it means we want to send
+        * our script / html to the client, and when that script runs
+        * it will start up separate websocket connections.
+        * 
+        * Interpret the URI string to figure out what is needed to send
+        */
+                
        case LWS_CALLBACK_HTTP:
-               /*
-                * The client has asked us for something in normal HTTP mode,
-                * not websockets mode.  Normally it means we want to send
-                * our script / html to the client, and when that script runs
-                * it will start up separate websocket connections.
-                */
+
                uri = libwebsocket_get_uri(wsi);
-               if (uri == NULL)
-                       fprintf(stderr, "LWS_CALLBACK_HTTP NULL URI\n");
-               else
-                       fprintf(stderr, "LWS_CALLBACK_HTTP  '%s'\n", uri);
-                       
                if (uri && strcmp(uri, "/favicon.ico") == 0) {
-                       if (libwebsockets_serve_http_file(wsi, "./favicon.ico", "image/x-icon")) {
-                               fprintf(stderr, "Failed to send favicon file\n");
-                       }
+                       if (libwebsockets_serve_http_file(wsi, "./favicon.ico",
+                                                               "image/x-icon"))
+                               fprintf(stderr, "Failed to send favicon\n");
                        break;
                }
                
                /* send the script... when it runs it'll start websockets */
 
-               if (libwebsockets_serve_http_file(wsi, "./test.html", "text/html")) {
+               if (libwebsockets_serve_http_file(wsi, "./test.html",
+                                                                "text/html")) {
                        fprintf(stderr, "Failed to send HTTP file\n");
                }
 
                break;
        }
+
        return 0;
 }
 
@@ -97,7 +110,9 @@ int main(int argc, char **argv)
 {
        int n = 0;
 
-       fprintf(stderr, "libwebsockets test server\nCopyright 2010 Andy Green <andy@warmcat.com> licensed under GPL2\n");
+       fprintf(stderr, "libwebsockets test server\n"
+                       "Copyright 2010 Andy Green <andy@warmcat.com> "
+                                                      "licensed under GPL2\n");
        
        while (n >= 0) {
                n = getopt_long(argc, argv, "hp:r:", options, NULL);
@@ -111,19 +126,22 @@ int main(int argc, char **argv)
                        ws_protocol = atoi(optarg);
                        break;
                case 'h':
-                       fprintf(stderr, "Usage: test-server [--port=<p>] [--protocol=<v>]\n");
+                       fprintf(stderr, "Usage: test-server "
+                                            "[--port=<p>] [--protocol=<v>]\n");
                        exit(1);
                }
-               
        }
        
-       if (libwebsocket_create_server(port, websocket_callback, ws_protocol) < 0) {
+       if (libwebsocket_create_server(port, websocket_callback, ws_protocol) <
+                                                                           0) {
                fprintf(stderr, "libwebsocket init failed\n");
                return -1;
        }
+       
+       /* just sit there until killed */
                
        while (1)
-               sleep(1);
+               sleep(10);
 
        return 0;
 }