Procházet zdrojové kódy

Specify in detail and document return values of callback functions

bel před 10 roky
rodič
revize
f9a02ac8aa
3 změnil soubory, kde provedl 57 přidání a 34 odebrání
  1. 1 0
      RELEASE_NOTES.md
  2. 44 31
      include/civetweb.h
  3. 12 3
      src/civetweb.c

+ 1 - 0
RELEASE_NOTES.md

@@ -5,6 +5,7 @@ Release Notes v1.7 (Under Development)
 Changes
 -------
 
+- Specify in detail and document return values of callback functions
 - Set names for all threads (unless NO_THREAD_NAME is defined)
 - New API functions for TCP/HTTP clients
 - Fix upload of huge files

+ 44 - 31
include/civetweb.h

@@ -61,9 +61,9 @@ struct mg_request_info {
                                    NULL */
     const char *remote_user;    /* Authenticated user, or NULL if no auth
                                    used */
-    char remote_addr[48];       /* Client's IP address as a string. */
-    long remote_ip;             /* Client's IP address. Deprecated: use remote_addr instead */
-
+    char remote_addr[48];       /* Client's IP address as a string. */
+    long remote_ip;             /* Client's IP address. Deprecated: use remote_addr instead */
+
     long long content_length;   /* Length (in bytes) of the request body,
                                    can be -1 if no length was given. */
     int remote_port;            /* Client's port */
@@ -80,15 +80,18 @@ struct mg_request_info {
 
 
 /* This structure needs to be passed to mg_start(), to let civetweb know
-   which callbacks to invoke. For detailed description, see
+   which callbacks to invoke. For a detailed description, see
    https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md */
 struct mg_callbacks {
     /* Called when civetweb has received new HTTP request.
        If callback returns non-zero,
        callback must process the request by sending valid HTTP headers and
        body, and civetweb will not do any further processing.
-       If callback returns 0, civetweb processes the request itself. In this
-       case, callback must not send any data to the client. */
+       Return value:
+         0: civetweb will process the request itself. In this case,
+            the callback must not send any data to the client.
+         1: callback already processed the request. Civetweb will
+            not send any data after the callback returned. */
     int  (*begin_request)(struct mg_connection *);
 
     /* Called when civetweb has finished processing request. */
@@ -98,12 +101,19 @@ struct mg_callbacks {
        non-zero, civetweb does not log anything. */
     int  (*log_message)(const struct mg_connection *, const char *message);
 
-    /* Called when civetweb initializes SSL library. */
+    /* Called when civetweb initializes SSL library.
+       Parameters:
+         user_data: parameter user_data passed when starting the server.
+       Return value:
+         0: civetweb will set up the SSL certificate.
+         1: civetweb assumes the callback already set up the certificate.
+        -1: initializing ssl fails. */
     int  (*init_ssl)(void *ssl_context, void *user_data);
 
     /* Called when websocket request is received, before websocket handshake.
-       If callback returns 0, civetweb proceeds with handshake, otherwise
-       cinnection is closed immediately. */
+       Return value:
+         0: civetweb proceeds with websocket handshake.
+         1: connection is closed immediately. */
     int (*websocket_connect)(const struct mg_connection *);
 
     /* Called when websocket handshake is successfully completed, and
@@ -112,12 +122,12 @@ struct mg_callbacks {
 
     /* Called when data frame has been received from the client.
        Parameters:
-          bits: first byte of the websocket frame, see websocket RFC at
-                http://tools.ietf.org/html/rfc6455, section 5.2
-          data, data_len: payload, with mask (if any) already applied.
+         bits: first byte of the websocket frame, see websocket RFC at
+               http://tools.ietf.org/html/rfc6455, section 5.2
+         data, data_len: payload, with mask (if any) already applied.
        Return value:
-          non-0: keep this websocket connection opened.
-          0:     close this websocket connection. */
+         1: keep this websocket connection open.
+         0: close this websocket connection. */
     int  (*websocket_data)(struct mg_connection *, int bits,
                            char *data, size_t data_len);
 
@@ -134,13 +144,13 @@ struct mg_callbacks {
           data_len: Placeholder for the file size, if file is served from
                     memory.
        Return value:
-          NULL: do not serve file from memory, proceed with normal file open.
-          non-NULL: pointer to the file contents in memory. data_len must be
-          initilized with the size of the memory block. */
+         NULL: do not serve file from memory, proceed with normal file open.
+         non-NULL: pointer to the file contents in memory. data_len must be
+           initilized with the size of the memory block. */
     const char * (*open_file)(const struct mg_connection *,
                               const char *path, size_t *data_len);
 
-    /* Called when civetweb is about to serve Lua server page (.lp file), if
+    /* Called when civetweb is about to serve Lua server page, if
        Lua support is enabled.
        Parameters:
          lua_context: "lua_State *" pointer. */
@@ -149,13 +159,16 @@ struct mg_callbacks {
     /* Called when civetweb has uploaded a file to a temporary directory as a
        result of mg_upload() call.
        Parameters:
-          file_file: full path name to the uploaded file. */
+         file_name: full path name to the uploaded file. */
     void (*upload)(struct mg_connection *, const char *file_name);
 
     /* Called when civetweb is about to send HTTP error to the client.
        Implementing this callback allows to create custom error pages.
        Parameters:
-         status: HTTP error status code. */
+         status: HTTP error status code.
+       Return value:
+         1: run civetweb error handler.
+         0: callback already handled the error. */
     int  (*http_error)(struct mg_connection *, int status);
 
     /* Called after civetweb context has been created, before requests
@@ -621,17 +634,17 @@ enum {
     TIMEOUT_INFINITE = -1
 };
 
-/* Wait for a response from the server
-   Parameters:
-     conn: connection
-     ebuf, ebuf_len: error message placeholder.
-     timeout: time to wait for a response in milliseconds (if < 0 then wait forever)
-
-   Return:
-     On success, >= 0
-     On error/timeout, < 0
-*/
-CIVETWEB_API int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout);
+/* Wait for a response from the server
+   Parameters:
+     conn: connection
+     ebuf, ebuf_len: error message placeholder.
+     timeout: time to wait for a response in milliseconds (if < 0 then wait forever)
+
+   Return:
+     On success, >= 0
+     On error/timeout, < 0
+*/
+CIVETWEB_API int mg_get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int timeout);
 
 
 #ifdef __cplusplus

+ 12 - 3
src/civetweb.c

@@ -6347,6 +6347,7 @@ static int initialize_ssl(struct mg_context *ctx)
 static int set_ssl_option(struct mg_context *ctx)
 {
     const char *pem;
+    int callback_ret;
 
     /* If PEM file is not specified and the init_ssl callback
        is not specified, skip SSL initialization. */
@@ -6377,9 +6378,17 @@ static int set_ssl_option(struct mg_context *ctx)
         return 0;
     }
 
-    /* If user callback returned non-NULL, that means that user callback has
-       set up certificate itself. In this case, skip sertificate setting. */
-    if ((ctx->callbacks.init_ssl == NULL) || (!ctx->callbacks.init_ssl(ctx->ssl_ctx, ctx->user_data))) {
+    /* If a callback has been specified, call it. */
+    callback_ret = (ctx->callbacks.init_ssl == NULL) ? 0 : (ctx->callbacks.init_ssl(ctx->ssl_ctx, ctx->user_data));
+
+    /* If callback returns 0, civetweb sets up the SSL certificate.
+       If it returns 1, civetweb assumes the calback already did this.
+       If it returns -1, initializing ssl fails. */
+    if (callback_ret < 0) {
+        mg_cry(fc(ctx), "SSL callback returned error: %i", callback_ret);
+        return 0;
+    }
+    if (callback_ret == 0) {
         if (pem != NULL) {
             if ((SSL_CTX_use_certificate_file(ctx->ssl_ctx, pem, 1) == 0) || (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, pem, 1) == 0)) {
                 mg_cry(fc(ctx), "%s: cannot open %s: %s", __func__, pem, ssl_error());