mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
Use native file functions on Windows
Add a special implementation with CreateFile(), ReadFile() and CloseFile() for serving HTTP file request to allow compilation on all Windows platforms.
This commit is contained in:
parent
3ef96e8095
commit
81338aa886
5 changed files with 64 additions and 22 deletions
|
@ -219,7 +219,7 @@ http_postbody:
|
|||
memset(&wsi->u, 0, sizeof(wsi->u));
|
||||
wsi->mode = LWS_CONNMODE_HTTP_SERVING_ACCEPTED;
|
||||
wsi->state = WSI_STATE_HTTP;
|
||||
wsi->u.http.fd = -1;
|
||||
wsi->u.http.fd = LWS_INVALID_FILE;
|
||||
|
||||
/* expose it at the same offset as u.hdr */
|
||||
wsi->u.http.ah = ah;
|
||||
|
|
|
@ -286,10 +286,14 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context,
|
|||
free(wsi->u.http.post_buffer);
|
||||
wsi->u.http.post_buffer = NULL;
|
||||
}
|
||||
if (wsi->u.http.fd >= 0) {
|
||||
lwsl_debug("closing http fd %d\n", wsi->u.http.fd);
|
||||
if (wsi->u.http.fd != LWS_INVALID_FILE) {
|
||||
lwsl_debug("closing http file\n");
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
CloseHandle(wsi->u.http.fd);
|
||||
#else
|
||||
close(wsi->u.http.fd);
|
||||
wsi->u.http.fd = -1;
|
||||
#endif
|
||||
wsi->u.http.fd = LWS_INVALID_FILE;
|
||||
context->protocols[0].callback(context, wsi,
|
||||
LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0);
|
||||
}
|
||||
|
|
28
lib/output.c
28
lib/output.c
|
@ -629,7 +629,12 @@ send_raw:
|
|||
LWS_VISIBLE int libwebsockets_serve_http_file_fragment(
|
||||
struct libwebsocket_context *context, struct libwebsocket *wsi)
|
||||
{
|
||||
int n, m;
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
DWORD n;
|
||||
#else
|
||||
int n;
|
||||
#endif
|
||||
int m;
|
||||
|
||||
while (!lws_send_pipe_choked(wsi)) {
|
||||
|
||||
|
@ -643,22 +648,33 @@ LWS_VISIBLE int libwebsockets_serve_http_file_fragment(
|
|||
if (wsi->u.http.filepos == wsi->u.http.filelen)
|
||||
goto all_sent;
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
if (!ReadFile(wsi->u.http.fd, context->service_buffer,
|
||||
sizeof(context->service_buffer), &n, NULL))
|
||||
return -1; /* caller will close */
|
||||
#else
|
||||
n = read(wsi->u.http.fd, context->service_buffer,
|
||||
sizeof(context->service_buffer));
|
||||
if (n > 0) {
|
||||
|
||||
if (n < 0)
|
||||
return -1; /* caller will close */
|
||||
#endif
|
||||
if (n) {
|
||||
m = libwebsocket_write(wsi, context->service_buffer, n,
|
||||
LWS_WRITE_HTTP);
|
||||
if (m < 0)
|
||||
return -1;
|
||||
|
||||
wsi->u.http.filepos += m;
|
||||
if (m != n)
|
||||
if (m != n) {
|
||||
/* adjust for what was not sent */
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
SetFilePointer(wsi->u.http.fd, m - n, NULL, FILE_CURRENT);
|
||||
#else
|
||||
lseek(wsi->u.http.fd, m - n, SEEK_CUR);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
return -1; /* caller will close */
|
||||
all_sent:
|
||||
if (!wsi->truncated_send_malloc &&
|
||||
wsi->u.http.filepos == wsi->u.http.filelen) {
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
#include <winsock2.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <windows.h>
|
||||
#define LWS_INVALID_FILE INVALID_HANDLE_VALUE
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -99,6 +100,7 @@
|
|||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define LWS_INVALID_FILE -1
|
||||
#define compatible_close(fd) close(fd);
|
||||
#endif
|
||||
|
||||
|
@ -344,7 +346,11 @@ struct allocated_headers {
|
|||
|
||||
struct _lws_http_mode_related {
|
||||
struct allocated_headers *ah; /* mirroring _lws_header_related */
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
HANDLE fd;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
unsigned long filepos;
|
||||
unsigned long filelen;
|
||||
|
||||
|
|
40
lib/server.c
40
lib/server.c
|
@ -485,6 +485,31 @@ LWS_VISIBLE int libwebsockets_return_http_status(
|
|||
return m;
|
||||
}
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
static inline HANDLE lws_open_file(const char* filename, unsigned long* filelen)
|
||||
{
|
||||
HANDLE ret = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (ret != LWS_INVALID_FILE)
|
||||
*filelen = GetFileSize(ret, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int lws_open_file(const char* filename, unsigned long* filelen)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
int ret = open(filename, O_RDONLY);
|
||||
|
||||
if (ret < 0)
|
||||
return LWS_INVALID_FILE;
|
||||
|
||||
fstat(ret, &stat_buf);
|
||||
*filelen = stat_buf.st_size;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* libwebsockets_serve_http_file() - Send a file back to the client using http
|
||||
* @context: libwebsockets context
|
||||
|
@ -508,27 +533,19 @@ LWS_VISIBLE int libwebsockets_serve_http_file(
|
|||
struct libwebsocket *wsi, const char *file,
|
||||
const char *content_type, const char *other_headers)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
unsigned char *p = context->service_buffer;
|
||||
int ret = 0;
|
||||
int n;
|
||||
|
||||
wsi->u.http.fd = open(file, O_RDONLY
|
||||
#ifdef WIN32
|
||||
| _O_BINARY
|
||||
#endif
|
||||
);
|
||||
wsi->u.http.fd = lws_open_file(file, &wsi->u.http.filelen);
|
||||
|
||||
if (wsi->u.http.fd < 1) {
|
||||
if (wsi->u.http.fd == LWS_INVALID_FILE) {
|
||||
lwsl_err("Unable to open '%s'\n", file);
|
||||
libwebsockets_return_http_status(context, wsi,
|
||||
HTTP_STATUS_NOT_FOUND, NULL);
|
||||
wsi->u.http.fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
fstat(wsi->u.http.fd, &stat_buf);
|
||||
wsi->u.http.filelen = stat_buf.st_size;
|
||||
p += sprintf((char *)p,
|
||||
"HTTP/1.0 200 OK\x0d\x0aServer: libwebsockets\x0d\x0a""Content-Type: %s\x0d\x0a",
|
||||
content_type);
|
||||
|
@ -538,8 +555,7 @@ LWS_VISIBLE int libwebsockets_serve_http_file(
|
|||
p += n;
|
||||
}
|
||||
p += sprintf((char *)p,
|
||||
"Content-Length: %u\x0d\x0a\x0d\x0a",
|
||||
(unsigned int)stat_buf.st_size);
|
||||
"Content-Length: %lu\x0d\x0a\x0d\x0a", wsi->u.http.filelen);
|
||||
|
||||
ret = libwebsocket_write(wsi, context->service_buffer,
|
||||
p - context->service_buffer, LWS_WRITE_HTTP);
|
||||
|
|
Loading…
Add table
Reference in a new issue