mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-16 00:00:07 +01:00
refactor allow http parse also for client
This commit is contained in:
parent
78dcaf45c4
commit
dd32c24df6
2 changed files with 2 additions and 199 deletions
|
@ -278,7 +278,7 @@ set(SOURCES
|
|||
lib/context.c
|
||||
lib/sha-1.c
|
||||
lib/alloc.c
|
||||
)
|
||||
lib/header.c)
|
||||
|
||||
if (NOT LWS_WITHOUT_CLIENT)
|
||||
list(APPEND SOURCES
|
||||
|
|
199
lib/server.c
199
lib/server.c
|
@ -838,210 +838,13 @@ try_pollout:
|
|||
goto fail;
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
fail:
|
||||
libwebsocket_close_and_free_session(context, wsi,
|
||||
LWS_CLOSE_STATUS_NOSTATUS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include "lextable-strings.h"
|
||||
|
||||
const unsigned char *lws_token_to_string(enum lws_token_indexes token)
|
||||
{
|
||||
if ((unsigned int)token >= ARRAY_SIZE(set))
|
||||
return NULL;
|
||||
|
||||
return (unsigned char *)set[token];
|
||||
}
|
||||
|
||||
int lws_add_http_header_by_name(struct libwebsocket_context *context,
|
||||
struct libwebsocket *wsi,
|
||||
const unsigned char *name,
|
||||
const unsigned char *value,
|
||||
int length,
|
||||
unsigned char **p,
|
||||
unsigned char *end)
|
||||
{
|
||||
#ifdef LWS_USE_HTTP2
|
||||
if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
|
||||
return lws_add_http2_header_by_name(context, wsi, name, value, length, p, end);
|
||||
#endif
|
||||
if (name) {
|
||||
while (*p < end && *name)
|
||||
*((*p)++) = *name++;
|
||||
|
||||
if (*p == end)
|
||||
return 1;
|
||||
|
||||
*((*p)++) = ' ';
|
||||
}
|
||||
if (*p + length + 3 >= end)
|
||||
return 1;
|
||||
|
||||
memcpy(*p, value, length);
|
||||
*p += length;
|
||||
|
||||
*((*p)++) = '\x0d';
|
||||
*((*p)++) = '\x0a';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lws_finalize_http_header(struct libwebsocket_context *context,
|
||||
struct libwebsocket *wsi,
|
||||
unsigned char **p,
|
||||
unsigned char *end)
|
||||
{
|
||||
#ifdef LWS_USE_HTTP2
|
||||
if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if ((long)(end - *p) < 3)
|
||||
return 1;
|
||||
|
||||
*((*p)++) = '\x0d';
|
||||
*((*p)++) = '\x0a';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lws_add_http_header_by_token(struct libwebsocket_context *context,
|
||||
struct libwebsocket *wsi,
|
||||
enum lws_token_indexes token,
|
||||
const unsigned char *value,
|
||||
int length,
|
||||
unsigned char **p,
|
||||
unsigned char *end)
|
||||
{
|
||||
const unsigned char *name;
|
||||
#ifdef LWS_USE_HTTP2
|
||||
if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
|
||||
return lws_add_http2_header_by_token(context, wsi, token, value, length, p, end);
|
||||
#endif
|
||||
name = lws_token_to_string(token);
|
||||
if (!name)
|
||||
return 1;
|
||||
|
||||
return lws_add_http_header_by_name(context, wsi, name, value, length, p, end);
|
||||
}
|
||||
|
||||
int lws_add_http_header_content_length(struct libwebsocket_context *context,
|
||||
struct libwebsocket *wsi,
|
||||
unsigned long content_length,
|
||||
unsigned char **p,
|
||||
unsigned char *end)
|
||||
{
|
||||
char b[24];
|
||||
int n;
|
||||
|
||||
n = sprintf(b, "%lu", content_length);
|
||||
if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH, (unsigned char *)b, n, p, end))
|
||||
return 1;
|
||||
wsi->u.http.content_length = content_length;
|
||||
wsi->u.http.content_remain = content_length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *err400[] = {
|
||||
"Bad Request",
|
||||
"Unauthorized",
|
||||
"Payment Required",
|
||||
"Forbidden",
|
||||
"Not Found",
|
||||
"Method Not Allowed",
|
||||
"Not Acceptable",
|
||||
"Proxy Auth Required",
|
||||
"Request Timeout",
|
||||
"Conflict",
|
||||
"Gone",
|
||||
"Length Required",
|
||||
"Precondition Failed",
|
||||
"Request Entity Too Large",
|
||||
"Request URI too Long",
|
||||
"Unsupported Media Type",
|
||||
"Requested Range Not Satisfiable",
|
||||
"Expectation Failed"
|
||||
};
|
||||
|
||||
static const char *err500[] = {
|
||||
"Internal Server Error",
|
||||
"Not Implemented",
|
||||
"Bad Gateway",
|
||||
"Service Unavailable",
|
||||
"Gateway Timeout",
|
||||
"HTTP Version Not Supported"
|
||||
};
|
||||
|
||||
int lws_add_http_header_status(struct libwebsocket_context *context,
|
||||
struct libwebsocket *wsi,
|
||||
unsigned int code,
|
||||
unsigned char **p,
|
||||
unsigned char *end)
|
||||
{
|
||||
unsigned char code_and_desc[60];
|
||||
const char *description = "";
|
||||
int n;
|
||||
|
||||
#ifdef LWS_USE_HTTP2
|
||||
if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
|
||||
return lws_add_http2_header_status(context, wsi, code, p, end);
|
||||
#endif
|
||||
if (code >= 400 && code < (400 + ARRAY_SIZE(err400)))
|
||||
description = err400[code - 400];
|
||||
if (code >= 500 && code < (500 + ARRAY_SIZE(err500)))
|
||||
description = err500[code - 500];
|
||||
|
||||
n = sprintf((char *)code_and_desc, "HTTP/1.0 %u %s", code, description);
|
||||
|
||||
return lws_add_http_header_by_name(context, wsi, NULL, code_and_desc, n, p, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* libwebsockets_return_http_status() - Return simple http status
|
||||
* @context: libwebsockets context
|
||||
* @wsi: Websocket instance (available from user callback)
|
||||
* @code: Status index, eg, 404
|
||||
* @html_body: User-readable HTML description < 1KB, or NULL
|
||||
*
|
||||
* Helper to report HTTP errors back to the client cleanly and
|
||||
* consistently
|
||||
*/
|
||||
LWS_VISIBLE int libwebsockets_return_http_status(
|
||||
struct libwebsocket_context *context, struct libwebsocket *wsi,
|
||||
unsigned int code, const char *html_body)
|
||||
{
|
||||
int n, m;
|
||||
|
||||
unsigned char *p = context->service_buffer + LWS_SEND_BUFFER_PRE_PADDING;
|
||||
unsigned char *start = p;
|
||||
unsigned char *end = p + sizeof(context->service_buffer) -
|
||||
LWS_SEND_BUFFER_PRE_PADDING;
|
||||
|
||||
if (!html_body)
|
||||
html_body = "";
|
||||
|
||||
if (lws_add_http_header_status(context, wsi, code, &p, end))
|
||||
return 1;
|
||||
if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *)"libwebsockets", 13, &p, end))
|
||||
return 1;
|
||||
if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)"text/html", 9, &p, end))
|
||||
return 1;
|
||||
if (lws_finalize_http_header(context, wsi, &p, end))
|
||||
return 1;
|
||||
|
||||
m = libwebsocket_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS);
|
||||
if (m != (int)(p - start))
|
||||
return 1;
|
||||
|
||||
n = sprintf((char *)start, "<html><body><h1>%u</h1>%s</body></html>", code, html_body);
|
||||
m = libwebsocket_write(wsi, start, n, LWS_WRITE_HTTP);
|
||||
|
||||
return m != n;
|
||||
}
|
||||
|
||||
/**
|
||||
* libwebsockets_serve_http_file() - Send a file back to the client using http
|
||||
* @context: libwebsockets context
|
||||
|
|
Loading…
Add table
Reference in a new issue