📄 sample_http.c
字号:
#include "lwip/tcpip.h"
#include "ROFS.h"
#include <stdio.h>
struct http_state {
const char *file;
u32_t left;
u8_t retries;
};
static const char msg_not_found[] = "HTTP/1.0 404\r\n";
static void conn_err(void *arg, err_t err)
{
struct http_state *hs;
hs = arg;
mem_free(hs);
}
static void close_conn(struct tcp_pcb *pcb, struct http_state *hs)
{
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
mem_free(hs);
tcp_close(pcb);
}
static void send_data(struct tcp_pcb *pcb, struct http_state *hs)
{
err_t err;
u32_t len;
/* We cannot send more data than space available in the send buffer. */
if(tcp_sndbuf(pcb) < hs->left)
len = tcp_sndbuf(pcb);
else
len = hs->left;
do {
err = tcp_write(pcb, hs->file, len, 0);
if(err == ERR_MEM)
len >>= 1;
} while(err == ERR_MEM && len > 1);
if(err == ERR_OK)
{
hs->file += len;
hs->left -= len;
}
}
static err_t http_poll(void *arg, struct tcp_pcb *pcb)
{
struct http_state *hs = arg;
if(hs && ++hs->retries < 4)
{
send_data(pcb, hs);
return ERR_OK;
}
else
{
tcp_abort(pcb);
return ERR_ABRT;
}
}
static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
struct http_state *hs = arg;
hs->retries = 0;
if(hs->left > 0)
send_data(pcb, hs);
else
close_conn(pcb, hs);
return ERR_OK;
}
static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
int i;
struct http_state *hs = arg;
if(err == ERR_OK && p != NULL)
{
/* Inform TCP that we have taken the data. */
tcp_recved(pcb, p->tot_len);
if(hs->file == NULL)
{
char *data = p->payload;
if(data[0] == 'G' && data[1] == 'E' && data[2] == 'T' && data[3] == ' ')
{
const struct rofs_dir *rof;
char *end;
data += 4;
if(*data == '/')
data++;
for(end = data, data = p->payload; *end != ' ' && *end != '\r' && *end != '\n'; end++)
if(*end == '%')
{
int n = 0;
for(i = 0; i < 2; i++)
{
int m;
end++;
if(*end < 'A')
m = *end - '0';
else if(*end < 'a')
m = *end - ('A' - 10);
else
m = *end - ('a' - 10);
n = n << 4 | m;
}
*data++ = n;
}
else
*data++ = *end;
*data = 0, data = p->payload;
if(!*data)
strcpy(data, "index.htm");
rof = find_rofile(data);
if(rof)
{
hs->file = rof->data;
hs->left = rof->size;
}
else
{
hs->file = msg_not_found;
hs->left = sizeof(msg_not_found) - 1;
}
pbuf_free(p);
send_data(pcb, hs);
/* Tell TCP that we wish be to informed of data that has been
successfully sent by a call to the http_sent() function. */
tcp_sent(pcb, http_sent);
}
else
{
pbuf_free(p);
close_conn(pcb, hs);
}
}
else
pbuf_free(p);
}
if(err == ERR_OK && p == NULL)
close_conn(pcb, hs);
return ERR_OK;
}
static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
struct http_state *hs;
// tcp_setprio(pcb, TCP_PRIO_MIN);
/* Allocate memory for the structure that holds the state of the connection. */
hs = mem_malloc(sizeof(struct http_state));
if(hs == NULL)
return ERR_MEM;
/* Initialize the structure. */
hs->file = NULL;
hs->left = 0;
hs->retries = 0;
/* Tell TCP that this is the structure we wish to be passed for our callbacks. */
tcp_arg(pcb, hs);
/* Tell TCP that we wish to be informed of incoming data by a call to the http_recv() function. */
tcp_recv(pcb, http_recv);
tcp_err(pcb, conn_err);
tcp_poll(pcb, http_poll, 4);
return ERR_OK;
}
void http_init(void)
{
struct tcp_pcb *pcb;
pcb = tcp_new();
tcp_bind(pcb, IP_ADDR_ANY, 80);
pcb = tcp_listen(pcb);
tcp_accept(pcb, http_accept);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -