mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
add by hand http send example
This adds a demonstration of how to use the http nonblocking send action to the test server. If you ask for /leaf.jpg from the test server, it will send "by hand" a 2.4MB jpeg in HTTP, including the headers. See the test server sources to see how it is done. Although it's a file, and a jpeg image, actually the exact same scheme will work for any data or mime type. Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
parent
e803c82044
commit
fbf48227b3
4 changed files with 96 additions and 6 deletions
|
@ -109,7 +109,7 @@ libwebsockets_test_ping_CFLAGS= -Wall -Werror -std=gnu99 -pedantic -DINSTALL_DAT
|
|||
endif
|
||||
endif
|
||||
|
||||
EXTRA_DIST=test.html favicon.ico libwebsockets.org-logo.png
|
||||
EXTRA_DIST=test.html favicon.ico libwebsockets.org-logo.png leaf.jpg
|
||||
|
||||
#
|
||||
# cook a random test cert and key
|
||||
|
|
BIN
test-server/leaf.jpg
Normal file
BIN
test-server/leaf.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 MiB |
|
@ -28,6 +28,8 @@
|
|||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#ifdef WIN32
|
||||
|
||||
|
@ -104,6 +106,10 @@ static const struct serveable whitelist[] = {
|
|||
{ "/test.html", "text/html" },
|
||||
};
|
||||
|
||||
struct per_session_data__http {
|
||||
int fd;
|
||||
};
|
||||
|
||||
/* this protocol server (always the first one) just knows how to do HTTP */
|
||||
|
||||
static int callback_http(struct libwebsocket_context *context,
|
||||
|
@ -117,6 +123,10 @@ static int callback_http(struct libwebsocket_context *context,
|
|||
#endif
|
||||
char buf[256];
|
||||
int n;
|
||||
unsigned char *p;
|
||||
static unsigned char buffer[8192];
|
||||
struct stat stat_buf;
|
||||
struct per_session_data__http *pss = (struct per_session_data__http *)user;
|
||||
#ifdef EXTERNAL_POLL
|
||||
int m;
|
||||
int fd = (int)(long)user;
|
||||
|
@ -125,6 +135,55 @@ static int callback_http(struct libwebsocket_context *context,
|
|||
switch (reason) {
|
||||
case LWS_CALLBACK_HTTP:
|
||||
|
||||
/* check for the "send a big file by hand" example case */
|
||||
|
||||
if (!strcmp((const char *)in, "/leaf.jpg")) {
|
||||
|
||||
/* well, let's demonstrate how to send the hard way */
|
||||
|
||||
p = buffer;
|
||||
|
||||
pss->fd = open(LOCAL_RESOURCE_PATH"/leaf.jpg", O_RDONLY);
|
||||
if (pss->fd < 0)
|
||||
return -1;
|
||||
|
||||
fstat(pss->fd, &stat_buf);
|
||||
|
||||
/*
|
||||
* we will send a big jpeg file, but it could be
|
||||
* anything. Set the Content-Type: appropriately
|
||||
* so the browser knows what to do with it.
|
||||
*/
|
||||
|
||||
p += sprintf((char *)p,
|
||||
"HTTP/1.0 200 OK\x0d\x0a"
|
||||
"Server: libwebsockets\x0d\x0a"
|
||||
"Content-Type: image-jpeg\x0d\x0a"
|
||||
"Content-Length: %u\x0d\x0a\x0d\x0a",
|
||||
(unsigned int)stat_buf.st_size);
|
||||
|
||||
/*
|
||||
* send the http headers...
|
||||
* this won't block since it's the first payload sent
|
||||
* on the connection since it was established
|
||||
*/
|
||||
|
||||
n = libwebsocket_write(wsi, buffer,
|
||||
p - buffer, LWS_WRITE_HTTP);
|
||||
|
||||
if (n < 0) {
|
||||
close(pss->fd);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* book us a LWS_CALLBACK_HTTP_WRITEABLE callback
|
||||
*/
|
||||
libwebsocket_callback_on_writable(context, wsi);
|
||||
break;
|
||||
}
|
||||
|
||||
/* if not, send a file the easy way */
|
||||
|
||||
for (n = 0; n < (sizeof(whitelist) / sizeof(whitelist[0]) - 1); n++)
|
||||
if (in && strcmp((const char *)in, whitelist[n].urlpath) == 0)
|
||||
break;
|
||||
|
@ -132,7 +191,7 @@ static int callback_http(struct libwebsocket_context *context,
|
|||
sprintf(buf, LOCAL_RESOURCE_PATH"%s", whitelist[n].urlpath);
|
||||
|
||||
if (libwebsockets_serve_http_file(context, wsi, buf, whitelist[n].mimetype))
|
||||
return 1; /* through completion or error, close the socket */
|
||||
return -1; /* through completion or error, close the socket */
|
||||
|
||||
/*
|
||||
* notice that the sending of the file completes asynchronously,
|
||||
|
@ -145,7 +204,37 @@ static int callback_http(struct libwebsocket_context *context,
|
|||
case LWS_CALLBACK_HTTP_FILE_COMPLETION:
|
||||
// lwsl_info("LWS_CALLBACK_HTTP_FILE_COMPLETION seen\n");
|
||||
/* kill the connection after we sent one file */
|
||||
return 1;
|
||||
return -1;
|
||||
|
||||
case LWS_CALLBACK_HTTP_WRITEABLE:
|
||||
/*
|
||||
* we can send more of whatever it is we were sending
|
||||
*/
|
||||
|
||||
do {
|
||||
n = read(pss->fd, buffer, sizeof buffer);
|
||||
/* problem reading, close conn */
|
||||
if (n < 0)
|
||||
goto bail;
|
||||
/* sent it all, close conn */
|
||||
if (n == 0)
|
||||
goto bail;
|
||||
/*
|
||||
* because it's HTTP and not websocket, don't need to take
|
||||
* care about pre and postamble
|
||||
*/
|
||||
n = libwebsocket_write(wsi, buffer, n, LWS_WRITE_HTTP);
|
||||
if (n < 0)
|
||||
/* write failed, close conn */
|
||||
goto bail;
|
||||
|
||||
} while (!lws_send_pipe_choked(wsi));
|
||||
libwebsocket_callback_on_writable(context, wsi);
|
||||
break;
|
||||
|
||||
bail:
|
||||
close(pss->fd);
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* callback for confirming to continue with client IP appear in
|
||||
|
@ -476,7 +565,7 @@ static struct libwebsocket_protocols protocols[] = {
|
|||
{
|
||||
"http-only", /* name */
|
||||
callback_http, /* callback */
|
||||
0, /* per_session_data_size */
|
||||
sizeof (struct per_session_data__http), /* per_session_data_size */
|
||||
0, /* max frame size / rx buffer */
|
||||
},
|
||||
{
|
||||
|
|
|
@ -37,8 +37,9 @@
|
|||
The incrementing number is coming from the server and is individual for
|
||||
each connection to the server... try opening a second browser window.
|
||||
<br/><br/>
|
||||
Click the button to send the server a websocket message to
|
||||
reset the number.
|
||||
The button zeros just this connection's number.
|
||||
<br/><br/>
|
||||
Click <a href="/leaf.jpg" target="_blank">Here</a> to have the test server send a big picture by http.
|
||||
</td></tr></table>
|
||||
</section>
|
||||
<br>
|
||||
|
|
Loading…
Add table
Reference in a new issue