Jelajahi Sumber

Add client interface to standalone server and fix ssl init for clients

bel2125 7 tahun lalu
induk
melakukan
9fc4d3e250
4 mengubah file dengan 240 tambahan dan 115 penghapusan
  1. 83 55
      src/civetweb.c
  2. 33 33
      src/handle_form.inl
  3. 110 13
      src/main.c
  4. 14 14
      src/mod_lua.inl

+ 83 - 55
src/civetweb.c

@@ -8082,6 +8082,7 @@ connect_socket(struct mg_context *ctx /* may be NULL */,
                )
 {
 	int ip_ver = 0;
+	int conn_ret = -1;
 	*sock = INVALID_SOCKET;
 	memset(sa, 0, sizeof(*sa));
 
@@ -8195,47 +8196,56 @@ connect_socket(struct mg_context *ctx /* may be NULL */,
 		return 0;
 	}
 
+	if (0 != set_non_blocking_mode(*sock)) {
+		mg_snprintf(NULL,
+		            NULL, /* No truncation check for ebuf */
+		            ebuf,
+		            ebuf_len,
+		            "Cannot set socket to non-blocking: %s",
+		            strerror(ERRNO));
+		closesocket(*sock);
+		*sock = INVALID_SOCKET;
+		return 0;
+	}
+
 	set_close_on_exec(*sock, fc(ctx));
 
-	if ((ip_ver == 4)
-	    && (connect(*sock, (struct sockaddr *)&sa->sin, sizeof(sa->sin))
-	        == 0)) {
+	if (ip_ver == 4) {
 		/* connected with IPv4 */
-		if (0 == set_non_blocking_mode(*sock)) {
-			/* Ok */
-			return 1;
-		}
-		/* failed */
-		/* TODO: specific error message */
+		conn_ret = connect(*sock, (struct sockaddr *)&sa->sin, sizeof(sa->sin));
 	}
-
 #ifdef USE_IPV6
-	if ((ip_ver == 6)
-	    && (connect(*sock, (struct sockaddr *)&sa->sin6, sizeof(sa->sin6))
-	        == 0)) {
+	else if (ip_ver == 6) {
 		/* connected with IPv6 */
-		if (0 == set_non_blocking_mode(*sock)) {
-			/* Ok */
-			return 1;
-		}
-		/* failed */
-		/* TODO: specific error message */
+		conn_ret =
+		    connect(*sock, (struct sockaddr *)&sa->sin6, sizeof(sa->sin6));
 	}
 #endif
 
-	/* Not connected */
-	mg_snprintf(NULL,
-	            NULL, /* No truncation check for ebuf */
-	            ebuf,
-	            ebuf_len,
-	            "connect(%s:%d): %s",
-	            host,
-	            port,
-	            strerror(ERRNO));
-	closesocket(*sock);
-	*sock = INVALID_SOCKET;
+	if (conn_ret != 0) {
+		fd_set fdset;
+		struct timeval timeout;
+		FD_ZERO(&fdset);
+		FD_SET(*sock, &fdset);
+		timeout.tv_sec = 10; /* 10 second timeout */
+		timeout.tv_usec = 0;
 
-	return 0;
+		if (select(*sock + 1, NULL, &fdset, NULL, &timeout) != 1) {
+			/* Not connected */
+			mg_snprintf(NULL,
+			            NULL, /* No truncation check for ebuf */
+			            ebuf,
+			            ebuf_len,
+			            "connect(%s:%d): failed",
+			            host,
+			            port);
+			closesocket(*sock);
+			*sock = INVALID_SOCKET;
+			return 0;
+		}
+	}
+
+	return 1;
 }
 
 
@@ -11375,7 +11385,7 @@ read_websocket(struct mg_connection *conn,
 			}
 
 			if (exit_by_callback
-                || ((mop & 0xf) == MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE)) {
+			    || ((mop & 0xf) == MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE)) {
 				/* Opcode == 8, connection close */
 				break;
 			}
@@ -14061,6 +14071,14 @@ initialize_ssl(char *ebuf, size_t ebuf_len)
 	if (!cryptolib_dll_handle) {
 		cryptolib_dll_handle = load_dll(ebuf, ebuf_len, CRYPTO_LIB, crypto_sw);
 		if (!cryptolib_dll_handle) {
+			mg_snprintf(NULL,
+			            NULL, /* No truncation check for ebuf */
+			            ebuf,
+			            ebuf_len,
+			            "%s: error loading library %s",
+			            __func__,
+			            CRYPTO_LIB);
+			DEBUG_TRACE("%s", ebuf);
 			return 0;
 		}
 	}
@@ -14082,6 +14100,14 @@ initialize_ssl(char *ebuf, size_t ebuf_len)
 	if (!cryptolib_dll_handle) {
 		cryptolib_dll_handle = load_dll(ebuf, ebuf_len, CRYPTO_LIB, crypto_sw);
 		if (!cryptolib_dll_handle) {
+			mg_snprintf(NULL,
+			            NULL, /* No truncation check for ebuf */
+			            ebuf,
+			            ebuf_len,
+			            "%s: error loading library %s",
+			            __func__,
+			            CRYPTO_LIB);
+			DEBUG_TRACE("%s", ebuf);
 			return 0;
 		}
 	}
@@ -14110,7 +14136,7 @@ initialize_ssl(char *ebuf, size_t ebuf_len)
 		            "%s: cannot allocate mutexes: %s",
 		            __func__,
 		            ssl_error());
-
+		DEBUG_TRACE("%s", ebuf);
 		return 0;
 	}
 
@@ -14122,6 +14148,28 @@ initialize_ssl(char *ebuf, size_t ebuf_len)
 	CRYPTO_set_id_callback(&mg_current_thread_id);
 #endif /* OPENSSL_API_1_1 */
 
+#if !defined(NO_SSL_DL)
+	if (!ssllib_dll_handle) {
+		ssllib_dll_handle = load_dll(ebuf, sizeof(ebuf), SSL_LIB, ssl_sw);
+		if (!ssllib_dll_handle) {
+			DEBUG_TRACE("%s", ebuf);
+			return 0;
+		}
+	}
+#endif /* NO_SSL_DL */
+
+#ifdef OPENSSL_API_1_1
+	/* Initialize SSL library */
+	OPENSSL_init_ssl(0, NULL);
+	OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
+	                     | OPENSSL_INIT_LOAD_CRYPTO_STRINGS,
+	                 NULL);
+#else
+	/* Initialize SSL library */
+	SSL_library_init();
+	SSL_load_error_strings();
+#endif
+
 	return 1;
 }
 
@@ -14285,32 +14333,12 @@ set_ssl_option(struct mg_context *ctx)
 		return 0;
 	}
 
-#if !defined(NO_SSL_DL)
-	if (!ssllib_dll_handle) {
-		ssllib_dll_handle = load_dll(ebuf, sizeof(ebuf), SSL_LIB, ssl_sw);
-		if (!ssllib_dll_handle) {
-			mg_cry(fc(ctx), "%s", ebuf);
-			return 0;
-		}
-	}
-#endif /* NO_SSL_DL */
-
 #ifdef OPENSSL_API_1_1
-	/* Initialize SSL library */
-	OPENSSL_init_ssl(0, NULL);
-	OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
-	                     | OPENSSL_INIT_LOAD_CRYPTO_STRINGS,
-	                 NULL);
-
 	if ((ctx->ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) {
 		mg_cry(fc(ctx), "SSL_CTX_new (server) error: %s", ssl_error());
 		return 0;
 	}
 #else
-	/* Initialize SSL library */
-	SSL_library_init();
-	SSL_load_error_strings();
-
 	if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
 		mg_cry(fc(ctx), "SSL_CTX_new (server) error: %s", ssl_error());
 		return 0;
@@ -16753,10 +16781,10 @@ mg_start(const struct mg_callbacks *callbacks,
 
 		if (is_ssl_port_used(ports_option)) {
 			/* Initialize with SSL support */
-			mg_init_library(2);
+			mg_init_library(MG_FEATURES_TLS);
 		} else {
 			/* Initialize without SSL support */
-			mg_init_library(0);
+			mg_init_library(MG_FEATURES_DEFAULT);
 		}
 	}
 

+ 33 - 33
src/handle_form.inl

@@ -40,7 +40,7 @@ url_encoded_field_found(const struct mg_connection *conn,
 	    mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
 
 	if (((size_t)key_dec_len >= (size_t)sizeof(key_dec)) || (key_dec_len < 0)) {
-        return MG_FORM_FIELD_STORAGE_SKIP;
+		return MG_FORM_FIELD_STORAGE_SKIP;
 	}
 
 	if (filename) {
@@ -54,7 +54,7 @@ url_encoded_field_found(const struct mg_connection *conn,
 		    || (filename_dec_len < 0)) {
 			/* Log error message and skip this field. */
 			mg_cry(conn, "%s: Cannot decode filename", __func__);
-            return MG_FORM_FIELD_STORAGE_SKIP;
+			return MG_FORM_FIELD_STORAGE_SKIP;
 		}
 	} else {
 		filename_dec[0] = 0;
@@ -63,16 +63,16 @@ url_encoded_field_found(const struct mg_connection *conn,
 	ret =
 	    fdh->field_found(key_dec, filename_dec, path, path_len, fdh->user_data);
 
-    if ((ret & 0xF) == MG_FORM_FIELD_STORAGE_GET) {
+	if ((ret & 0xF) == MG_FORM_FIELD_STORAGE_GET) {
 		if (fdh->field_get == NULL) {
 			mg_cry(conn, "%s: Function \"Get\" not available", __func__);
-            return MG_FORM_FIELD_STORAGE_SKIP;
+			return MG_FORM_FIELD_STORAGE_SKIP;
 		}
 	}
-    if ((ret & 0xF) == MG_FORM_FIELD_STORAGE_STORE) {
+	if ((ret & 0xF) == MG_FORM_FIELD_STORAGE_STORE) {
 		if (fdh->field_store == NULL) {
 			mg_cry(conn, "%s: Function \"Store\" not available", __func__);
-            return MG_FORM_FIELD_STORAGE_SKIP;
+			return MG_FORM_FIELD_STORAGE_SKIP;
 		}
 	}
 
@@ -99,7 +99,7 @@ url_encoded_field_get(const struct mg_connection *conn,
 		       "%s: Not enough memory (required: %lu)",
 		       __func__,
 		       (unsigned long)(value_len + 1));
-        return MG_FORM_FIELD_STORAGE_ABORT;
+		return MG_FORM_FIELD_STORAGE_ABORT;
 	}
 
 	mg_url_decode(key, (int)key_len, key_dec, (int)sizeof(key_dec), 1);
@@ -232,16 +232,16 @@ mg_handle_form_request(struct mg_connection *conn,
 
 			/* In every "field_found" callback we ask what to do with the
 			 * data ("field_storage"). This could be:
-             * MG_FORM_FIELD_STORAGE_SKIP (0):
-             *   ignore the value of this field
-             * MG_FORM_FIELD_STORAGE_GET (1):
-             *   read the data and call the get callback function
-             * MG_FORM_FIELD_STORAGE_STORE (2):
-             *   store the data in a file
-             * MG_FORM_FIELD_STORAGE_READ (3):
-             *   let the user read the data (for parsing long data on the fly)
-             * MG_FORM_FIELD_STORAGE_ABORT (flag):
-             *   stop parsing
+			 * MG_FORM_FIELD_STORAGE_SKIP (0):
+			 *   ignore the value of this field
+			 * MG_FORM_FIELD_STORAGE_GET (1):
+			 *   read the data and call the get callback function
+			 * MG_FORM_FIELD_STORAGE_STORE (2):
+			 *   store the data in a file
+			 * MG_FORM_FIELD_STORAGE_READ (3):
+			 *   let the user read the data (for parsing long data on the fly)
+			 * MG_FORM_FIELD_STORAGE_ABORT (flag):
+			 *   stop parsing
 			 */
 			memset(path, 0, sizeof(path));
 			field_count++;
@@ -264,12 +264,12 @@ mg_handle_form_request(struct mg_connection *conn,
 				next = val + vallen;
 			}
 
-            if (field_storage == MG_FORM_FIELD_STORAGE_GET) {
+			if (field_storage == MG_FORM_FIELD_STORAGE_GET) {
 				/* Call callback */
 				url_encoded_field_get(
 				    conn, data, (size_t)keylen, val, (size_t)vallen, fdh);
 			}
-            if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
+			if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
 				/* Store the content to a file */
 				if (mg_fopen(conn, path, MG_FOPEN_MODE_WRITE, &fstore) == 0) {
 					fstore.access.fp = NULL;
@@ -308,7 +308,7 @@ mg_handle_form_request(struct mg_connection *conn,
 				}
 			}
 
-            /* if (field_storage == MG_FORM_FIELD_STORAGE_READ) { */
+			/* if (field_storage == MG_FORM_FIELD_STORAGE_READ) { */
 			/* The idea of "field_storage=read" is to let the API user read
 			 * data chunk by chunk and to some data processing on the fly.
 			 * This should avoid the need to store data in the server:
@@ -321,8 +321,8 @@ mg_handle_form_request(struct mg_connection *conn,
 			 */
 			/* } */
 
-            if ((field_storage & MG_FORM_FIELD_STORAGE_ABORT)
-                == MG_FORM_FIELD_STORAGE_ABORT) {
+			if ((field_storage & MG_FORM_FIELD_STORAGE_ABORT)
+			    == MG_FORM_FIELD_STORAGE_ABORT) {
 				/* Stop parsing the request */
 				break;
 			}
@@ -399,13 +399,13 @@ mg_handle_form_request(struct mg_connection *conn,
 			                                        sizeof(path) - 1,
 			                                        fdh);
 
-            if ((field_storage & MG_FORM_FIELD_STORAGE_ABORT)
-                == MG_FORM_FIELD_STORAGE_ABORT) {
+			if ((field_storage & MG_FORM_FIELD_STORAGE_ABORT)
+			    == MG_FORM_FIELD_STORAGE_ABORT) {
 				/* Stop parsing the request */
 				break;
 			}
 
-            if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
+			if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
 				if (mg_fopen(conn, path, MG_FOPEN_MODE_WRITE, &fstore) == 0) {
 					fstore.access.fp = NULL;
 				}
@@ -428,7 +428,7 @@ mg_handle_form_request(struct mg_connection *conn,
 					next = val + vallen;
 				}
 
-                if (field_storage == MG_FORM_FIELD_STORAGE_GET) {
+				if (field_storage == MG_FORM_FIELD_STORAGE_GET) {
 #if 0
 					if (!end_of_key_value_pair_found && !all_data_read) {
 						/* This callback will deliver partial contents */
@@ -808,7 +808,7 @@ mg_handle_form_request(struct mg_connection *conn,
 			                       boundary,
 			                       bl);
 
-            if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
+			if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
 				/* Store the content to a file */
 				if (mg_fopen(conn, path, MG_FOPEN_MODE_WRITE, &fstore) == 0) {
 					fstore.access.fp = NULL;
@@ -830,7 +830,7 @@ mg_handle_form_request(struct mg_connection *conn,
 				 * in the buffer. */
 				towrite -= bl + 4;
 
-                if (field_storage == MG_FORM_FIELD_STORAGE_GET) {
+				if (field_storage == MG_FORM_FIELD_STORAGE_GET) {
 					unencoded_field_get(conn,
 					                    ((get_block > 0) ? NULL : nbeg),
 					                    ((get_block > 0)
@@ -842,7 +842,7 @@ mg_handle_form_request(struct mg_connection *conn,
 					get_block++;
 				}
 
-                if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
+				if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
 					if (fstore.access.fp) {
 
 						/* Store the content of the buffer. */
@@ -886,7 +886,7 @@ mg_handle_form_request(struct mg_connection *conn,
 
 			towrite = (size_t)(next - hend);
 
-            if (field_storage == MG_FORM_FIELD_STORAGE_GET) {
+			if (field_storage == MG_FORM_FIELD_STORAGE_GET) {
 				/* Call callback */
 				unencoded_field_get(conn,
 				                    ((get_block > 0) ? NULL : nbeg),
@@ -897,7 +897,7 @@ mg_handle_form_request(struct mg_connection *conn,
 				                    fdh);
 			}
 
-            if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
+			if (field_storage == MG_FORM_FIELD_STORAGE_STORE) {
 
 				if (fstore.access.fp) {
 					n = (size_t)fwrite(hend, 1, towrite, fstore.access.fp);
@@ -926,8 +926,8 @@ mg_handle_form_request(struct mg_connection *conn,
 				}
 			}
 
-            if ((field_storage & MG_FORM_FIELD_STORAGE_ABORT)
-                == MG_FORM_FIELD_STORAGE_ABORT) {
+			if ((field_storage & MG_FORM_FIELD_STORAGE_ABORT)
+			    == MG_FORM_FIELD_STORAGE_ABORT) {
 				/* Stop parsing the request */
 				break;
 			}

+ 110 - 13
src/main.c

@@ -529,47 +529,47 @@ set_option(char **options, const char *name, const char *value)
 		}
 	}
 
-    type = MG_CONFIG_TYPE_UNKNOWN;
+	type = MG_CONFIG_TYPE_UNKNOWN;
 	for (i = 0; default_options[i].name != NULL; i++) {
 		if (!strcmp(default_options[i].name, name)) {
 			type = default_options[i].type;
 		}
 	}
 	switch (type) {
-    case MG_CONFIG_TYPE_UNKNOWN:
+	case MG_CONFIG_TYPE_UNKNOWN:
 		/* unknown option */
 		return 0;
-    case MG_CONFIG_TYPE_NUMBER:
+	case MG_CONFIG_TYPE_NUMBER:
 		/* integer number >= 0, e.g. number of threads */
 		if (atol(value) < 0) {
 			/* invalid number */
 			return 0;
 		}
 		break;
-    case MG_CONFIG_TYPE_STRING:
+	case MG_CONFIG_TYPE_STRING:
 		/* any text */
 		break;
-    case MG_CONFIG_TYPE_STRING_LIST:
+	case MG_CONFIG_TYPE_STRING_LIST:
 		/* list of text items, separated by , */
 		multi_sep = ",";
 		break;
-    case MG_CONFIG_TYPE_STRING_MULTILINE:
+	case MG_CONFIG_TYPE_STRING_MULTILINE:
 		/* lines of text, separated by carriage return line feed */
 		multi_sep = "\r\n";
 		break;
-    case MG_CONFIG_TYPE_BOOLEAN:
+	case MG_CONFIG_TYPE_BOOLEAN:
 		/* boolean value, yes or no */
 		if ((0 != strcmp(value, "yes")) && (0 != strcmp(value, "no"))) {
 			/* invalid boolean */
 			return 0;
 		}
 		break;
-    case MG_CONFIG_TYPE_FILE:
-    case MG_CONFIG_TYPE_DIRECTORY:
+	case MG_CONFIG_TYPE_FILE:
+	case MG_CONFIG_TYPE_DIRECTORY:
 		/* TODO (low): check this option when it is set, instead of calling
 		 * verify_existence later */
 		break;
-    case MG_CONFIG_TYPE_EXT_PATTERN:
+	case MG_CONFIG_TYPE_EXT_PATTERN:
 		/* list of patterns, separated by | */
 		multi_sep = "|";
 		break;
@@ -991,20 +991,117 @@ finished:
 
 
 static int
-run_client(const char *url)
+run_client(const char *url_arg)
 {
+	/* connection data */
+	char *url = sdup(url_arg);
+	char *host;
+	char *resource;
 	int is_ssl = 0;
+	unsigned long port = 0;
+	size_t sep;
+	char *endp = 0;
+
+	/* connection object */
+	struct mg_connection *conn;
+	char ebuf[1024] = {0};
+
+	/* Check parameter */
+	if (!url) {
+		fprintf(stderr, "Out of memory\n");
+		return 0;
+	}
+
 	if (!strncmp(url, "http://", 7)) {
-		url += 7;
+		host = url + 7;
+		port = 80;
 	} else if (!strncmp(url, "https://", 8)) {
-		url += 8;
+		host = url + 8;
 		is_ssl = 1;
+		port = 443;
 	} else {
 		fprintf(stderr, "URL must start with http:// or https://\n");
+		free(url);
+		return 0;
+	}
+	if ((host[0] <= 32) || (host[0] > 126) || (host[0] == '/')
+	    || (host[0] == ':')) {
+		fprintf(stderr, "Invalid host\n");
+		free(url);
+		return 0;
+	}
+
+	sep = strcspn(host, "/:");
+	switch (host[sep]) {
+	case 0:
+		resource = "";
+		break;
+	case '/':
+		host[sep] = 0;
+		resource = host + sep + 1;
+		break;
+	case ':':
+		host[sep] = 0;
+		port = strtoul(host + sep + 1, &endp, 10);
+		if (!endp || (*endp != '/' && *endp != 0) || (port < 1)
+		    || (port > 0xFFFF)) {
+			fprintf(stderr, "Invalid port\n");
+			free(url);
+			return 0;
+		}
+		if (*endp) {
+			*endp = 0;
+			resource = endp + 1;
+		} else {
+			resource = "";
+		}
+		break;
+	default:
+		fprintf(stderr, "Syntax error\n");
+		free(url);
 		return 0;
 	}
 
+	fprintf(stdout, "Protocol: %s\n", is_ssl ? "https" : "http");
+	fprintf(stdout, "Host: %s\n", host);
+	fprintf(stdout, "Port: %lu\n", port);
+	fprintf(stdout, "Resource: %s\n", resource);
+
+	/* Initialize library */
+	if (is_ssl) {
+		mg_init_library(MG_FEATURES_TLS);
+	} else {
+		mg_init_library(MG_FEATURES_DEFAULT);
+	}
+
+	/* Connect to host */
+	conn = mg_connect_client(host, (int)port, is_ssl, ebuf, sizeof(ebuf));
+	if (conn) {
+		char buf[1024] = {0};
+		int ret;
+
+		fprintf(stdout, "Connected to %s\n", host);
+		mg_printf(conn, "GET /%s HTTP/1.0\r\n\r\n", resource);
+
+		fprintf(stdout, "Reading from %s\n", host);
+		ret = mg_read(conn, buf, sizeof(buf));
+		fprintf(stdout, "ret=%i\n", ret);
+		while (ret > 0) {
+			ret = fwrite(buf, 1, ret, stdout);
+			fprintf(stdout, "wri=%i\n", ret);
+			ret = mg_read(conn, buf, sizeof(buf));
+			fprintf(stdout, "ret=%i\n", ret);
+		}
+
+		fprintf(stdout, "Closing connection to %s\n", host);
+		mg_close_connection(conn);
+	} else {
+		fprintf(stderr, "Error connecting to %s:\n%s\n", host, ebuf);
+	}
 
+	/* Free memory and exit library */
+	free(url);
+	mg_exit_library();
 	return 1;
 }
 

+ 14 - 14
src/mod_lua.inl

@@ -1362,7 +1362,7 @@ lwebsock_write(lua_State *L)
 	if (num_args == 1) {
 		/* just one text: send it to all client */
 		if (lua_isstring(L, 1)) {
-            opcode = MG_WEBSOCKET_OPCODE_TEXT;
+			opcode = MG_WEBSOCKET_OPCODE_TEXT;
 		}
 	} else if (num_args == 2) {
 		if (lua_isnumber(L, 1)) {
@@ -1372,21 +1372,21 @@ lwebsock_write(lua_State *L)
 			/* opcode string and message text */
 			str = lua_tostring(L, 1);
 			if (!mg_strncasecmp(str, "text", 4))
-                opcode = MG_WEBSOCKET_OPCODE_TEXT;
+				opcode = MG_WEBSOCKET_OPCODE_TEXT;
 			else if (!mg_strncasecmp(str, "bin", 3))
-                opcode = MG_WEBSOCKET_OPCODE_BINARY;
+				opcode = MG_WEBSOCKET_OPCODE_BINARY;
 			else if (!mg_strncasecmp(str, "close", 5))
-                opcode = MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE;
+				opcode = MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE;
 			else if (!mg_strncasecmp(str, "ping", 4))
-                opcode = MG_WEBSOCKET_OPCODE_PING;
+				opcode = MG_WEBSOCKET_OPCODE_PING;
 			else if (!mg_strncasecmp(str, "pong", 4))
-                opcode = MG_WEBSOCKET_OPCODE_PONG;
+				opcode = MG_WEBSOCKET_OPCODE_PONG;
 			else if (!mg_strncasecmp(str, "cont", 4))
-                opcode = MG_WEBSOCKET_OPCODE_CONTINUATION;
+				opcode = MG_WEBSOCKET_OPCODE_CONTINUATION;
 		} else if (lua_isuserdata(L, 1)) {
 			/* client id and message text */
 			client = (struct mg_connection *)lua_touserdata(L, 1);
-            opcode = MG_WEBSOCKET_OPCODE_TEXT;
+			opcode = MG_WEBSOCKET_OPCODE_TEXT;
 		}
 	} else if (num_args == 3) {
 		if (lua_isuserdata(L, 1)) {
@@ -1398,17 +1398,17 @@ lwebsock_write(lua_State *L)
 				/* client id, opcode string and message text */
 				str = lua_tostring(L, 2);
 				if (!mg_strncasecmp(str, "text", 4))
-                    opcode = MG_WEBSOCKET_OPCODE_TEXT;
+					opcode = MG_WEBSOCKET_OPCODE_TEXT;
 				else if (!mg_strncasecmp(str, "bin", 3))
-                    opcode = MG_WEBSOCKET_OPCODE_BINARY;
+					opcode = MG_WEBSOCKET_OPCODE_BINARY;
 				else if (!mg_strncasecmp(str, "close", 5))
-                    opcode = MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE;
+					opcode = MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE;
 				else if (!mg_strncasecmp(str, "ping", 4))
-                    opcode = MG_WEBSOCKET_OPCODE_PING;
+					opcode = MG_WEBSOCKET_OPCODE_PING;
 				else if (!mg_strncasecmp(str, "pong", 4))
-                    opcode = MG_WEBSOCKET_OPCODE_PONG;
+					opcode = MG_WEBSOCKET_OPCODE_PONG;
 				else if (!mg_strncasecmp(str, "cont", 4))
-                    opcode = MG_WEBSOCKET_OPCODE_CONTINUATION;
+					opcode = MG_WEBSOCKET_OPCODE_CONTINUATION;
 			}
 		}
 	}