client http

Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
Andy Green 2016-04-18 17:26:14 +08:00
parent 451cee5d47
commit c673125ce0
6 changed files with 81 additions and 13 deletions

View file

@ -416,3 +416,46 @@ The extension may decide to alter or disallow the change, in the
example above permessage-deflate restricts the size of his rx
output buffer also considering the protocol's rx_buf_size member.
Client connections as HTTP[S] rather than WS[S]
-----------------------------------------------
You may open a generic http client connection using the same
struct lws_client_connect_info used to create client ws[s]
connections.
To stay in http[s], set the optional info member "method" to
point to the string "GET" instead of the default NULL.
After the server headers are processed, when payload from the
server is available the callback LWS_CALLBACK_RECEIVE_CLIENT_HTTP
will be made.
You can choose whether to process the data immediately, or
queue a callback when an outgoing socket is writeable to provide
flow control, and process the data in the writable callback.
Either way you use the api lws_http_client_read() to access the
data, eg
case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
{
char buffer[1024 + LWS_PRE];
char *px = buffer + LWS_PRE;
int lenx = sizeof(buffer) - LWS_PRE;
lwsl_notice("LWS_CALLBACK_RECEIVE_CLIENT_HTTP\n");
/*
* Often you need to flow control this by something
* else being writable. In that case call the api
* to get a callback when writable here, and do the
* pending client read in the writeable callback of
* the output.
*/
if (lws_http_client_read(wsi, &px, &lenx) < 0)
return -1;
while (lenx--)
putchar(*px++);
}
break;

View file

@ -440,12 +440,12 @@ lws_client_interpret_server_handshake(struct lws *wsi)
}
#ifdef LWS_WITH_HTTP_PROXY
wsi->perform_rewrite = 0;
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE)) {
if (!strncmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE),
"text/html", 9))
wsi->perform_rewrite = 1;
}
wsi->perform_rewrite = 0;
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE)) {
if (!strncmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE),
"text/html", 9))
wsi->perform_rewrite = 1;
}
#endif
/* allocate the per-connection user memory (if any) */
@ -491,7 +491,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
/* call him back to inform him he is up */
if (wsi->protocol->callback(wsi,
LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP,
LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP,
wsi->user_space, NULL, 0))
goto bail3;

View file

@ -95,6 +95,9 @@ lws_read(struct lws *wsi, unsigned char *buf, size_t len)
break;
#endif
case LWSS_CLIENT_HTTP_ESTABLISHED:
break;
case LWSS_HTTP:
wsi->hdr_parsing_completed = 0;
/* fallthru */
@ -104,6 +107,7 @@ lws_read(struct lws *wsi, unsigned char *buf, size_t len)
wsi->u.hdr.lextable_pos = 0;
/* fallthru */
case LWSS_HTTP_HEADERS:
assert(wsi->u.hdr.ah);
lwsl_parser("issuing %d bytes to parser\n", (int)len);
@ -227,7 +231,7 @@ postbody_completion:
}
break;
default:
lwsl_err("%s: Unhandled state\n", __func__);
lwsl_err("%s: Unhandled state %d\n", __func__, wsi->state);
break;
}

View file

@ -492,6 +492,8 @@ lws_http_client_read(struct lws *wsi, char **buf, int *len)
{
int rlen, n;
rlen = lws_ssl_capable_read(wsi, (unsigned char *)*buf, *len);
if (rlen < 0)
return -1;
@ -911,7 +913,8 @@ drain:
/* let user code know, he'll usually ask for writeable
* callback and drain / reenable it there
*/
if (user_callback_handle_rxflow(wsi->protocol->callback,
if (user_callback_handle_rxflow(
wsi->protocol->callback,
wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP,
wsi->user_space, NULL, 0))
goto close_and_handled;

View file

@ -243,6 +243,8 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
pss->reason_bf &= ~1;
break;
}
#endif
#ifndef LWS_NO_CLIENT
if (pss->reason_bf & 2) {
@ -269,6 +271,7 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
break;
#ifndef LWS_NO_CLIENT
case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: {
char ctype[64], ctlen = 0;
lwsl_err("LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP\n");

View file

@ -83,8 +83,6 @@ static int
callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
char *buf = (char *)in;
switch (reason) {
case LWS_CALLBACK_CLIENT_ESTABLISHED:
@ -126,8 +124,25 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
break;
case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
while (len--)
putchar(*buf++);
{
char buffer[1024 + LWS_PRE];
char *px = buffer + LWS_PRE;
int lenx = sizeof(buffer) - LWS_PRE;
lwsl_notice("LWS_CALLBACK_RECEIVE_CLIENT_HTTP\n");
/*
* Often you need to flow control this by something
* else being writable. In that case call the api
* to get a callback when writable here, and do the
* pending client read in the writeable callback of
* the output.
*/
if (lws_http_client_read(wsi, &px, &lenx) < 0)
return -1;
while (lenx--)
putchar(*px++);
}
break;
case LWS_CALLBACK_COMPLETED_CLIENT_HTTP: