blob: dfef2681a8de01a6486038512f825797b47ccb28 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include "../lib/libwebsockets.h"
/*
* libwebsocket Example server Copyright 2010 Andy Green <andy@warmcat.com>
*
* Licensed under GPL2
*
* Shows how to use libwebsocket
*/
#define LOCAL_RESOURCE_PATH "/usr/share/libwebsockets-test-server"
static int port = 7681;
static int ws_protocol = 76;
static int use_ssl = 0;
struct per_session_data {
int number;
};
/**
* libwebsocket_callback() - User server actions
* @wsi: Opaque websocket instance pointer
* @reason: The reason for the call
* @user: Pointer to per-session user data allocated by library
* @in: Pointer used for some callback reasons
* @len: Length set for some callback reasons
*
* This callback is the way the user controls what is served. All the
* protocol detail is hidden and handled by the library.
*
* For each connection / session there is user data allocated that is
* pointed to by "user". You set the size of this user data area when
* the library is initialized with libwebsocket_create_server.
*
* You get an opportunity to initialize user data when called back with
* LWS_CALLBACK_ESTABLISHED reason.
*
* LWS_CALLBACK_ESTABLISHED: after successful websocket handshake
* LWS_CALLBACK_CLOSED: when the websocket session ends
* LWS_CALLBACK_SEND: opportunity to send to client (you would use
* libwebsocket_write() taking care about the
* special buffer requirements
* LWS_CALLBACK_RECEIVE: data has appeared for the server, it can be
* found at *in and is len bytes long
* LWS_CALLBACK_HTTP: an http request has come from a client that is not
* asking to upgrade the connection to a websocket
* one. This is a chance to serve http content,
* for example, to send a script to the client
* which will then open the websockets connection.
* libwebsocket_get_uri() lets you find out the
* URI path requested and
* libwebsockets_serve_http_file() makes it very
* simple to send back a file to the client.
*/
static int websocket_callback(struct libwebsocket * wsi,
enum libwebsocket_callback_reasons reason, void * user,
void *in, size_t len)
{
int n;
char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
LWS_SEND_BUFFER_POST_PADDING];
char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
const char *uri;
struct per_session_data * pss = user;
switch (reason) {
/*
* Websockets session handshake completed and is established
*/
case LWS_CALLBACK_ESTABLISHED:
fprintf(stderr, "Websocket connection established\n");
pss->number = 0;
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:
n = sprintf(p, "%d", pss->number++);
n = libwebsocket_write(wsi, (unsigned char *)p, n, LWS_WRITE_TEXT);
if (n < 0) {
fprintf(stderr, "ERROR writing to socket");
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:
uri = libwebsocket_get_uri(wsi);
fprintf(stderr, "serving HTTP URI %s\n", uri);
if (uri && strcmp(uri, "/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,
LOCAL_RESOURCE_PATH"/test.html", "text/html"))
fprintf(stderr, "Failed to send HTTP file\n");
break;
}
return 0;
}
static struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "port", required_argument, NULL, 'p' },
{ "protocol", required_argument, NULL, 'r' },
{ "ssl", no_argument, NULL, 's' },
{ NULL, 0, 0, 0 }
};
int main(int argc, char **argv)
{
int n = 0;
const char * cert_path = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
const char * key_path = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
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);
if (n < 0)
continue;
switch (n) {
case 's':
use_ssl = 1;
break;
case 'p':
port = atoi(optarg);
break;
case 'r':
ws_protocol = atoi(optarg);
break;
case 'h':
fprintf(stderr, "Usage: test-server "
"[--port=<p>] [--protocol=<v>]\n");
exit(1);
}
}
if (!use_ssl)
cert_path = key_path = NULL;
if (libwebsocket_create_server(port, websocket_callback, ws_protocol,
sizeof(struct per_session_data),
cert_path, key_path, -1, -1) < 0) {
fprintf(stderr, "libwebsocket init failed\n");
return -1;
}
/* just sit there until killed */
while (1)
sleep(10);
return 0;
}