diff --git a/lib/handshake.c b/lib/handshake.c index 60f3fdaa..67e78923 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -1,6 +1,6 @@ /* * libwebsockets - small server side websockets and web server implementation - * + * * Copyright (C) 2010 Andy Green * * This library is free software; you can redistribute it and/or @@ -21,8 +21,6 @@ #include "private-libwebsockets.h" -void libwebsockets_md5(const unsigned char *input, int ilen, - unsigned char output[16]); static int interpret_key(const char *key, unsigned int *result) { @@ -30,7 +28,7 @@ static int interpret_key(const char *key, unsigned int *result) int digit_pos = 0; const char *p = key; int spaces = 0; - + while (*p) { if (isdigit(*p)) { if (digit_pos == sizeof(digits) - 1) @@ -42,18 +40,18 @@ static int interpret_key(const char *key, unsigned int *result) digits[digit_pos] = '\0'; if (!digit_pos) return -2; - + while (*key) { if (*key == ' ') spaces++; key++; } - + if (!spaces) return -3; - + *result = atol(digits) / spaces; - + return 0; } @@ -64,7 +62,7 @@ static int interpret_key(const char *key, unsigned int *result) * machine that is completely independent of packet size. */ -int +int libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) { size_t n; @@ -72,38 +70,38 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) unsigned int key1, key2; unsigned char sum[16]; char *response; - + switch (wsi->state) { case WSI_STATE_HTTP: wsi->state = WSI_STATE_HTTP_HEADERS; wsi->parser_state = WSI_TOKEN_NAME_PART; /* fallthru */ case WSI_STATE_HTTP_HEADERS: - - debug("issuing %d bytes to parser\n", (int)len); + + debug("issuing %d bytes to parser\n", (int)len); #ifdef DEBUG fwrite(buf, 1, len, stderr); #endif - for (n = 0; n< len; n++) + for (n = 0; n < len; n++) libwebsocket_parse(wsi, *buf++); - + if (wsi->parser_state != WSI_PARSING_COMPLETE) break; /* is this websocket protocol or normal http 1.0? */ - + if (!wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len || !wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len) { if (wsi->protocol->callback) - (wsi->protocol->callback)(wsi, LWS_CALLBACK_HTTP, - wsi->user_space, + (wsi->protocol->callback)(wsi, + LWS_CALLBACK_HTTP, wsi->user_space, wsi->utf8_token[WSI_TOKEN_GET_URI].token, 0); wsi->state = WSI_STATE_HTTP; return 0; } /* Websocket - confirm we have all the necessary pieces */ - + if (!wsi->utf8_token[WSI_TOKEN_ORIGIN].token_len || !wsi->utf8_token[WSI_TOKEN_HOST].token_len || !wsi->utf8_token[WSI_TOKEN_CHALLENGE].token_len || @@ -119,7 +117,6 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) atoi(wsi->utf8_token[WSI_TOKEN_DRAFT].token); switch (wsi->ietf_spec_revision) { case 76: - break; case 2: break; default: @@ -142,12 +139,12 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) wsi->utf8_token[WSI_TOKEN_PROTOCOL].token, wsi->protocol->name) == 0) break; - + wsi->protocol++; } /* we didn't find a protocol he wanted? */ - + if (wsi->protocol->callback == NULL) { if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token == NULL) fprintf(stderr, "[no protocol] " @@ -171,11 +168,11 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) } } else wsi->user_space = NULL; - + /* create the response packet */ - + /* make a buffer big enough for everything */ - + response = malloc(256 + wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len + wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len + @@ -187,7 +184,7 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) fprintf(stderr, "Out of memory for response buffer\n"); goto bail; } - + p = response; strcpy(p, "HTTP/1.1 101 WebSocket Protocol Handshake\x0d\x0a" "Upgrade: WebSocket\x0d\x0a"); @@ -224,14 +221,14 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) strcpy(p, "\x0d\x0a\x0d\x0a"); p += strlen("\x0d\x0a\x0d\x0a"); - + /* convert the two keys into 32-bit integers */ - + if (interpret_key(wsi->utf8_token[WSI_TOKEN_KEY1].token, &key1)) goto bail; if (interpret_key(wsi->utf8_token[WSI_TOKEN_KEY2].token, &key2)) goto bail; - + /* lay them out in network byte order (MSB first */ sum[0] = key1 >> 24; @@ -242,12 +239,12 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) sum[5] = key2 >> 16; sum[6] = key2 >> 8; sum[7] = key2; - + /* follow them with the challenge token we were sent */ - + memcpy(&sum[8], wsi->utf8_token[WSI_TOKEN_CHALLENGE].token, 8); - /* + /* * compute the md5sum of that 16-byte series and use as our * payload after our headers */ @@ -256,9 +253,8 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) p += 16; /* it's complete: go ahead and send it */ - - debug("issuing response packet %d len\n", - (int)(p - response)); + + debug("issuing response packet %d len\n", (int)(p - response)); #ifdef DEBUG fwrite(response, 1, p - response, stderr); #endif @@ -268,15 +264,15 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) fprintf(stderr, "ERROR writing to socket"); goto bail; } - + /* alright clean up and set ourselves into established state */ free(response); wsi->state = WSI_STATE_ESTABLISHED; wsi->lws_rx_parse_state = LWS_RXPS_NEW; - + /* notify user code that we're ready to roll */ - + if (wsi->protocol->callback) wsi->protocol->callback(wsi, LWS_CALLBACK_ESTABLISHED, wsi->user_space, NULL, 0); @@ -289,9 +285,9 @@ libwebsocket_read(struct libwebsocket *wsi, unsigned char * buf, size_t len) default: break; } - + return 0; - + bail: libwebsocket_close_and_free_session(wsi); return -1; diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index f4d8c716..ee950b65 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -82,8 +82,8 @@ libwebsocket_close_and_free_session(struct libwebsocket *wsi) wsi->state = WSI_STATE_DEAD_SOCKET; if (wsi->protocol->callback && n == WSI_STATE_ESTABLISHED) - wsi->protocol->callback(wsi, LWS_CALLBACK_CLOSED, wsi->user_space, - NULL, 0); + wsi->protocol->callback(wsi, LWS_CALLBACK_CLOSED, + wsi->user_space, NULL, 0); for (n = 0; n < WSI_TOKEN_COUNT; n++) if (wsi->utf8_token[n].token) @@ -248,6 +248,7 @@ int libwebsocket_create_server(int port, serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(port); + n = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if (n < 0) { fprintf(stderr, "ERROR on binding to port %d (%d %d)\n", port, n, @@ -255,7 +256,7 @@ int libwebsocket_create_server(int port, return -1; } - /* drop any root privs for this thread */ + /* drop any root privs for this process */ if (gid != -1) if (setgid(gid)) @@ -309,7 +310,6 @@ int libwebsocket_create_server(int port, if (!wsi[fds_count]) return -1; - #ifdef LWS_OPENSSL_SUPPORT if (use_ssl) { @@ -455,8 +455,10 @@ poll_out: if (wsi[client]->state != WSI_STATE_ESTABLISHED) continue; - wsi[client]->protocol->callback(wsi[client], LWS_CALLBACK_SEND, - wsi[client]->user_space, NULL, 0); + wsi[client]->protocol->callback(wsi[client], + LWS_CALLBACK_SEND, + wsi[client]->user_space, + NULL, 0); } continue; diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index 24042fc7..c1b70e52 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -1,6 +1,6 @@ /* * libwebsockets - small server side websockets and web server implementation - * + * * Copyright (C) 2010 Andy Green * * This library is free software; you can redistribute it and/or @@ -51,7 +51,7 @@ struct libwebsocket; * this much memory allocated on connection establishment and * freed on connection takedown. A pointer to this per-connection * allocation is passed into the callback in the 'user' parameter - * + * * This structure represents one protocol supported by the server. An * array of these structures is passed to libwebsocket_create_server() * allows as many protocols as you like to be handled by one server. @@ -59,37 +59,37 @@ struct libwebsocket; struct libwebsocket_protocols { const char *name; - int (*callback)(struct libwebsocket * wsi, - enum libwebsocket_callback_reasons reason, void * user, + int (*callback)(struct libwebsocket *wsi, + enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len); size_t per_session_data_size; }; extern int libwebsocket_create_server(int port, const struct libwebsocket_protocols *protocols, - const char * ssl_cert_filepath, - const char * ssl_private_key_filepath, int gid, int uid); + const char *ssl_cert_filepath, + const char *ssl_private_key_filepath, int gid, int uid); /* * IMPORTANT NOTICE! - * + * * When sending with websocket protocol (LWS_WRITE_TEXT or LWS_WRITE_BINARY) * the send buffer has to have LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE * buf, and LWS_SEND_BUFFER_POST_PADDING bytes valid AFTER (buf + len). - * + * * This allows us to add protocol info before and after the data, and send as * one packet on the network without payload copying, for maximum efficiency. - * + * * So for example you need this kind of code to use libwebsocket_write with a - * 128-byte payload - * + * 128-byte payload + * * 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); - * + * * 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. */ @@ -98,11 +98,11 @@ extern int libwebsocket_create_server(int port, #define LWS_SEND_BUFFER_POST_PADDING 1 extern int -libwebsocket_write(struct libwebsocket *, unsigned char *buf, size_t len, +libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len, enum libwebsocket_write_protocol protocol); extern int -libwebsockets_serve_http_file(struct libwebsocket *wsi, const char * file, - const char * content_type); +libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file, + const char *content_type); #endif diff --git a/lib/md5.c b/lib/md5.c index bebcb77e..342392ea 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -9,39 +9,37 @@ #include -struct md5_context -{ +struct md5_context { unsigned long total[2]; unsigned long state[4]; unsigned char buffer[64]; }; - /* * 32-bit integer manipulation macros (little endian) */ #ifndef GET_ULONG_LE -#define GET_ULONG_LE(n,b,i) \ +#define GET_ULONG_LE(n, b, i) \ { \ - (n) = ( (unsigned long) (b)[i]) \ - | ( (unsigned long) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long) (b)[(i) + 3] << 24 ); \ + (n) = ((unsigned long)(b)[i]) \ + | ((unsigned long)(b)[(i) + 1] << 8) \ + | ((unsigned long)(b)[(i) + 2] << 16) \ + | ((unsigned long)(b)[(i) + 3] << 24); \ } #endif #ifndef PUT_ULONG_LE -#define PUT_ULONG_LE(n,b,i) \ +#define PUT_ULONG_LE(n, b, i) \ { \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ + (b)[i] = (unsigned char)(n); \ + (b)[(i) + 1] = (unsigned char)((n) >> 8); \ + (b)[(i) + 2] = (unsigned char)((n) >> 16); \ + (b)[(i) + 3] = (unsigned char)((n) >> 24); \ } #endif -static void md5_process(struct md5_context *ctx, const unsigned char data[64] ) +static void md5_process(struct md5_context *ctx, const unsigned char data[64]) { unsigned long X[16], A, B, C, D; @@ -62,11 +60,11 @@ static void md5_process(struct md5_context *ctx, const unsigned char data[64] ) GET_ULONG_LE(X[14], data, 56); GET_ULONG_LE(X[15], data, 60); -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) +#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) -#define P(a,b,c,d,k,s,t) \ +#define P(a, b, c, d, k, s, t) \ { \ - a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ + a += F(b, c, d) + X[k] + t; a = S(a, s) + b; \ } A = ctx->state[0]; @@ -74,87 +72,87 @@ static void md5_process(struct md5_context *ctx, const unsigned char data[64] ) C = ctx->state[2]; D = ctx->state[3]; -#define F(x,y,z) (z ^ (x & (y ^ z))) +#define F(x, y, z) (z ^ (x & (y ^ z))) - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); + P(A, B, C, D, 0, 7, 0xD76AA478); + P(D, A, B, C, 1, 12, 0xE8C7B756); + P(C, D, A, B, 2, 17, 0x242070DB); + P(B, C, D, A, 3, 22, 0xC1BDCEEE); + P(A, B, C, D, 4, 7, 0xF57C0FAF); + P(D, A, B, C, 5, 12, 0x4787C62A); + P(C, D, A, B, 6, 17, 0xA8304613); + P(B, C, D, A, 7, 22, 0xFD469501); + P(A, B, C, D, 8, 7, 0x698098D8); + P(D, A, B, C, 9, 12, 0x8B44F7AF); + P(C, D, A, B, 10, 17, 0xFFFF5BB1); + P(B, C, D, A, 11, 22, 0x895CD7BE); + P(A, B, C, D, 12, 7, 0x6B901122); + P(D, A, B, C, 13, 12, 0xFD987193); + P(C, D, A, B, 14, 17, 0xA679438E); + P(B, C, D, A, 15, 22, 0x49B40821); #undef F -#define F(x,y,z) (y ^ (z & (x ^ y))) +#define F(x, y, z) (y ^ (z & (x ^ y))) - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) (x ^ y ^ z) - - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); + P(A, B, C, D, 1, 5, 0xF61E2562); + P(D, A, B, C, 6, 9, 0xC040B340); + P(C, D, A, B, 11, 14, 0x265E5A51); + P(B, C, D, A, 0, 20, 0xE9B6C7AA); + P(A, B, C, D, 5, 5, 0xD62F105D); + P(D, A, B, C, 10, 9, 0x02441453); + P(C, D, A, B, 15, 14, 0xD8A1E681); + P(B, C, D, A, 4, 20, 0xE7D3FBC8); + P(A, B, C, D, 9, 5, 0x21E1CDE6); + P(D, A, B, C, 14, 9, 0xC33707D6); + P(C, D, A, B, 3, 14, 0xF4D50D87); + P(B, C, D, A, 8, 20, 0x455A14ED); + P(A, B, C, D, 13, 5, 0xA9E3E905); + P(D, A, B, C, 2, 9, 0xFCEFA3F8); + P(C, D, A, B, 7, 14, 0x676F02D9); + P(B, C, D, A, 12, 20, 0x8D2A4C8A); #undef F -#define F(x,y,z) (y ^ (x | ~z)) +#define F(x, y, z) (x ^ y ^ z) - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); + P(A, B, C, D, 5, 4, 0xFFFA3942); + P(D, A, B, C, 8, 11, 0x8771F681); + P(C, D, A, B, 11, 16, 0x6D9D6122); + P(B, C, D, A, 14, 23, 0xFDE5380C); + P(A, B, C, D, 1, 4, 0xA4BEEA44); + P(D, A, B, C, 4, 11, 0x4BDECFA9); + P(C, D, A, B, 7, 16, 0xF6BB4B60); + P(B, C, D, A, 10, 23, 0xBEBFBC70); + P(A, B, C, D, 13, 4, 0x289B7EC6); + P(D, A, B, C, 0, 11, 0xEAA127FA); + P(C, D, A, B, 3, 16, 0xD4EF3085); + P(B, C, D, A, 6, 23, 0x04881D05); + P(A, B, C, D, 9, 4, 0xD9D4D039); + P(D, A, B, C, 12, 11, 0xE6DB99E5); + P(C, D, A, B, 15, 16, 0x1FA27CF8); + P(B, C, D, A, 2, 23, 0xC4AC5665); + +#undef F + +#define F(x, y, z) (y ^ (x | ~z)) + + P(A, B, C, D, 0, 6, 0xF4292244); + P(D, A, B, C, 7, 10, 0x432AFF97); + P(C, D, A, B, 14, 15, 0xAB9423A7); + P(B, C, D, A, 5, 21, 0xFC93A039); + P(A, B, C, D, 12, 6, 0x655B59C3); + P(D, A, B, C, 3, 10, 0x8F0CCC92); + P(C, D, A, B, 10, 15, 0xFFEFF47D); + P(B, C, D, A, 1, 21, 0x85845DD1); + P(A, B, C, D, 8, 6, 0x6FA87E4F); + P(D, A, B, C, 15, 10, 0xFE2CE6E0); + P(C, D, A, B, 6, 15, 0xA3014314); + P(B, C, D, A, 13, 21, 0x4E0811A1); + P(A, B, C, D, 4, 6, 0xF7537E82); + P(D, A, B, C, 11, 10, 0xBD3AF235); + P(C, D, A, B, 2, 15, 0x2AD7D2BB); + P(B, C, D, A, 9, 21, 0xEB86D391); #undef F @@ -207,7 +205,8 @@ static const unsigned char md5_padding[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -void libwebsockets_md5(const unsigned char *input, int ilen, unsigned char output[16]) +void +libwebsockets_md5(const unsigned char *input, int ilen, unsigned char *output) { struct md5_context ctx; unsigned long last, padn; diff --git a/lib/parsers.c b/lib/parsers.c index 5a98f6f9..1cb01e1a 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -1,6 +1,6 @@ /* * libwebsockets - small server side websockets and web server implementation - * + * * Copyright (C) 2010 Andy Green * * This library is free software; you can redistribute it and/or @@ -49,14 +49,14 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c) case WSI_TOKEN_ORIGIN: case WSI_TOKEN_DRAFT: case WSI_TOKEN_CHALLENGE: - + debug("WSI_TOKEN_(%d) '%c'\n", wsi->parser_state, c); /* collect into malloc'd buffers */ /* optional space swallow */ if (!wsi->utf8_token[wsi->parser_state].token_len && c == ' ') break; - + /* special case space terminator for get-uri */ if (wsi->parser_state == WSI_TOKEN_GET_URI && c == ' ') { wsi->utf8_token[wsi->parser_state].token[ @@ -100,7 +100,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c) wsi->parser_state = WSI_PARSING_COMPLETE; break; } - + break; /* collecting and checking a name part */ @@ -114,7 +114,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c) } wsi->name_buffer[wsi->name_buffer_pos++] = c; wsi->name_buffer[wsi->name_buffer_pos] = '\0'; - + for (n = 0; n < WSI_TOKEN_COUNT; n++) { if (wsi->name_buffer_pos != lws_tokens[n].token_len) continue; @@ -137,9 +137,9 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c) wsi->parser_state = WSI_TOKEN_SKIPPING; break; } - + /* don't look for payload when it can just be http headers */ - + if (wsi->parser_state == WSI_TOKEN_CHALLENGE && !wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len) { /* they're HTTP headers, not websocket upgrade! */ @@ -148,7 +148,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c) wsi->parser_state = WSI_PARSING_COMPLETE; } break; - + /* skipping arg part of a name we didn't recognize */ case WSI_TOKEN_SKIPPING: debug("WSI_TOKEN_SKIPPING '%c'\n", c); @@ -167,11 +167,11 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c) case WSI_PARSING_COMPLETE: debug("WSI_PARSING_COMPLETE '%c'\n", c); break; - + default: /* keep gcc happy */ break; } - + return 0; } @@ -183,7 +183,7 @@ static int libwebsocket_rx_sm(struct libwebsocket *wsi, unsigned char c) switch (wsi->lws_rx_parse_state) { case LWS_RXPS_NEW: - + switch (wsi->ietf_spec_revision) { /* Firefox 4.0b6 likes this as of 30 Oct */ case 76: @@ -255,13 +255,13 @@ int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, fprintf(stderr, "\n"); #endif /* let the rx protocol state machine have as much as it needs */ - + n = 0; while (wsi->lws_rx_parse_state != LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED && n < len) if (libwebsocket_rx_sm(wsi, buf[n++]) < 0) return -1; - + return -0; } @@ -285,26 +285,26 @@ int libwebsocket_interpret_incoming_packet(struct libwebsocket *wsi, * * This function provides the way to issue data back to the client * for both http and websocket protocols. - * + * * 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, +int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, size_t len, enum libwebsocket_write_protocol protocol) { int n; int pre = 0; int post = 0; unsigned int shift = 7; - + if (protocol == LWS_WRITE_HTTP) goto send_raw; - + /* websocket protocol, either binary or text */ - + if (wsi->state != WSI_STATE_ESTABLISHED) return -1; @@ -361,7 +361,7 @@ int libwebsocket_write(struct libwebsocket * wsi, unsigned char *buf, buf[-1] = len; pre = 9; break; - + /* just an unimplemented spec right now apparently */ case 2: n = 4; /* text */ @@ -405,7 +405,7 @@ int libwebsocket_write(struct libwebsocket * wsi, unsigned char *buf, #if 0 for (n = 0; n < (len + pre + post); n++) fprintf(stderr, "%02X ", buf[n - pre]); - + fprintf(stderr, "\n"); #endif @@ -427,8 +427,8 @@ send_raw: #ifdef LWS_OPENSSL_SUPPORT } #endif -// fprintf(stderr, "written %d bytes to client\n", (int)len); - + debug("written %d bytes to client\n", (int)len); + return 0; } @@ -438,14 +438,14 @@ send_raw: * @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) +int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char *file, + const char *content_type) { int fd; struct stat stat; @@ -461,7 +461,7 @@ int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char * file, ); libwebsocket_write(wsi, (unsigned char *)buf, p - buf, LWS_WRITE_HTTP); - + return -1; } @@ -471,7 +471,7 @@ int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char * file, "Content-Type: %s\x0d\x0a" "Content-Length: %u\x0d\x0a" "\x0d\x0a", content_type, (unsigned int)stat.st_size); - + libwebsocket_write(wsi, (unsigned char *)buf, p - buf, LWS_WRITE_HTTP); n = 1; @@ -480,8 +480,8 @@ int libwebsockets_serve_http_file(struct libwebsocket *wsi, const char * file, libwebsocket_write(wsi, (unsigned char *)buf, n, LWS_WRITE_HTTP); } - + close(fd); - + return 0; } diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index d3789f18..af0a6016 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -1,6 +1,6 @@ /* * libwebsockets - small server side websockets and web server implementation - * + * * Copyright (C) 2010 Andy Green * * This library is free software; you can redistribute it and/or @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -45,14 +45,14 @@ #include "libwebsockets.h" -//#define DEBUG +/* #define DEBUG */ #ifdef DEBUG #define debug(format, args...) \ fprintf(stderr, format , ## args) #else -#define debug(format, args...) +#define debug(format, args...) #endif #ifdef LWS_OPENSSL_SUPPORT @@ -87,7 +87,7 @@ enum lws_token_indexes { WSI_TOKEN_ORIGIN, WSI_TOKEN_DRAFT, WSI_TOKEN_CHALLENGE, - + /* always last real token index*/ WSI_TOKEN_COUNT, /* parser state additions */ @@ -99,17 +99,17 @@ enum lws_token_indexes { enum lws_rx_parse_state { LWS_RXPS_NEW, - + LWS_RXPS_SEEN_76_FF, LWS_RXPS_PULLING_76_LENGTH, LWS_RXPS_EAT_UNTIL_76_FF, - + LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED }; struct lws_tokens { - char * token; + char *token; int token_len; }; @@ -139,7 +139,7 @@ struct libwebsocket { enum lws_rx_parse_state lws_rx_parse_state; size_t rx_packet_length; - + #ifdef LWS_OPENSSL_SUPPORT SSL *ssl; #endif @@ -147,5 +147,8 @@ struct libwebsocket { void *user_space; }; -extern void +extern void libwebsocket_close_and_free_session(struct libwebsocket *wsi); + +extern void +libwebsockets_md5(const unsigned char *input, int ilen, unsigned char *output); diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index b418db67..e291f2ac 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -181,7 +181,7 @@ local files down the http link in a single step.

struct libwebsocket_protocols - List of protocols and handlers server supports.

struct libwebsocket_protocols {
    const char * name;
-    int (*callback) (struct libwebsocket * wsi,enum libwebsocket_callback_reasons reason, void * user,void *in, size_t len);
+    int (*callback) (struct libwebsocket *wsi,enum libwebsocket_callback_reasons reason, void *user,void *in, size_t len);
    size_t per_session_data_size;
};

Members

diff --git a/test-server/test-server.c b/test-server/test-server.c index 5806d810..79737fcf 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -1,6 +1,6 @@ /* * libwebsockets-test-server - libwebsockets test implementation - * + * * Copyright (C) 2010 Andy Green * * This library is free software; you can redistribute it and/or @@ -45,25 +45,25 @@ #define LOCAL_RESOURCE_PATH "/usr/share/libwebsockets-test-server" static int port = 7681; -static int use_ssl = 0; +static int use_ssl; /* this protocol server (always the first one) just knows how to do HTTP */ -static int callback_http(struct libwebsocket * wsi, - enum libwebsocket_callback_reasons reason, void * user, +static int callback_http(struct libwebsocket *wsi, + enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { switch (reason) { case LWS_CALLBACK_HTTP: fprintf(stderr, "serving HTTP URI %s\n", in); - + if (in && strcmp(in, "/favicon.ico") == 0) { if (libwebsockets_serve_http_file(wsi, LOCAL_RESOURCE_PATH"/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, @@ -85,23 +85,23 @@ struct per_session_data__dumb_increment { }; static int -callback_dumb_increment(struct libwebsocket * wsi, +callback_dumb_increment(struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, - void * user, void *in, size_t len) + void *user, void *in, size_t len) { int n; char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 + LWS_SEND_BUFFER_POST_PADDING]; unsigned char *p = (unsigned char *)&buf[LWS_SEND_BUFFER_PRE_PADDING]; - struct per_session_data__dumb_increment * pss = user; - + struct per_session_data__dumb_increment *pss = user; + switch (reason) { case LWS_CALLBACK_ESTABLISHED: pss->number = 0; break; - case LWS_CALLBACK_SEND: + case LWS_CALLBACK_SEND: n = sprintf(p, "%d", pss->number++); n = libwebsocket_write(wsi, p, n, LWS_WRITE_TEXT); if (n < 0) { @@ -131,12 +131,12 @@ callback_dumb_increment(struct libwebsocket * wsi, #define MAX_MESSAGE_QUEUE 64 struct per_session_data__lws_mirror { - struct libwebsocket * wsi; + struct libwebsocket *wsi; int ringbuffer_tail; }; struct a_message { - void * payload; + void *payload; size_t len; }; @@ -145,16 +145,16 @@ static int ringbuffer_head; static int -callback_lws_mirror(struct libwebsocket * wsi, +callback_lws_mirror(struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, - void * user, void *in, size_t len) + void *user, void *in, size_t len) { int n; char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 + LWS_SEND_BUFFER_POST_PADDING]; unsigned char *p = (unsigned char *)&buf[LWS_SEND_BUFFER_PRE_PADDING]; - struct per_session_data__lws_mirror * pss = user; - + struct per_session_data__lws_mirror *pss = user; + switch (reason) { case LWS_CALLBACK_ESTABLISHED: @@ -162,15 +162,15 @@ callback_lws_mirror(struct libwebsocket * wsi, pss->ringbuffer_tail = ringbuffer_head; break; - case LWS_CALLBACK_SEND: + case LWS_CALLBACK_SEND: /* send everything that's pending */ while (pss->ringbuffer_tail != ringbuffer_head) { - n = libwebsocket_write(wsi, - (unsigned char *)ringbuffer[pss->ringbuffer_tail].payload + - LWS_SEND_BUFFER_PRE_PADDING, + n = libwebsocket_write(wsi, (unsigned char *) + ringbuffer[pss->ringbuffer_tail].payload + + LWS_SEND_BUFFER_PRE_PADDING, ringbuffer[pss->ringbuffer_tail].len, - LWS_WRITE_TEXT); + LWS_WRITE_TEXT); if (n < 0) { fprintf(stderr, "ERROR writing to socket"); exit(1); @@ -185,7 +185,7 @@ callback_lws_mirror(struct libwebsocket * wsi, case LWS_CALLBACK_RECEIVE: if (ringbuffer[ringbuffer_head].payload) - free(ringbuffer[ringbuffer_head].payload ); + free(ringbuffer[ringbuffer_head].payload); ringbuffer[ringbuffer_head].payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + @@ -242,15 +242,15 @@ static struct option options[] = { int main(int argc, char **argv) { int n = 0; - const char * cert_path = + const char *cert_path = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem"; - const char * key_path = + const char *key_path = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem"; fprintf(stderr, "libwebsockets test server\n" "(C) Copyright 2010 Andy Green " "licensed under LGPL2.1\n"); - + while (n >= 0) { n = getopt_long(argc, argv, "hp:", options, NULL); if (n < 0) @@ -271,7 +271,7 @@ int main(int argc, char **argv) if (!use_ssl) cert_path = key_path = NULL; - + if (libwebsocket_create_server(port, protocols, cert_path, key_path, -1, -1) < 0) { fprintf(stderr, "libwebsocket init failed\n");