Skip to content

Commit

Permalink
httpd: implement simple http server
Browse files Browse the repository at this point in the history
Running on port 81.
This is required for lpb130 based devices.
  • Loading branch information
ljalves committed Jan 22, 2022
1 parent aa0666b commit 8762b9f
Showing 1 changed file with 199 additions and 1 deletion.
200 changes: 199 additions & 1 deletion src/httpd.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@

#include "hfeasy.h"

#define HTTP_SERVER_PORT 81
#define HTTPD_MAX_PAGES 10

#define HTTPS_RECV_TIMEOUT 3000
#define HTTPS_RECV_BUF_LEN 2048

static char https_recv_buf[HTTPS_RECV_BUF_LEN];

#define HttpRspDataFormat "HTTP/1.1 200 OK\r\n"\
"Content-type: text/html\r\n"\
"Content-length: 72\r\n"\
"\r\n"\
"<html><body>Hello World, System RunTime: %02d:%02d:%02d !</body></html>"



static const char *http_header = "HTTP/1.1 200 OK\r\n"\
"Server: HTTPD\r\n"
"Content-type: text/html\r\n"\
"Server: HFEASY\r\n"
"Connection: close\r\n\r\n";


Expand Down Expand Up @@ -105,6 +120,183 @@ static int USER_FUNC httpd_callback(char *url, char *rsp)
return -1;
}

static int http_get_alldata_len(char *data)
{
char *p1 = NULL, *p2 = NULL;
int headLen=0, bodyLen = 0;

p1 = strstr(data,"\r\n\r\n");
if(p1 == NULL)
return -1;

headLen = p1 - data + 4;

p1 = strstr(data,"Content-Length");
if(p1 == NULL)
p1 = strstr(data,"Content-length");
if(p1 == NULL)
return -1;

p2 = p1 + strlen("Content-Length") + 2;
bodyLen = atoi(p2);

return headLen + bodyLen;
}

static int https_recv_data(int fd, char *buffer, int len, int timeout_ms)
{
fd_set fdR;
struct timeval timeout;
int ret, tmpLen, contenLen, recvLen = 0;

while(1) {
FD_ZERO(&fdR);
FD_SET(fd, &fdR);
if(recvLen <= 0) {
timeout.tv_sec = timeout_ms / 1000;
timeout.tv_usec = timeout_ms % 1000 * 1000;
} else {
//fast close
timeout.tv_sec = 0;
timeout.tv_usec = 500 * 1000;
}

ret = select(fd + 1, &fdR, NULL, NULL, &timeout);
if (ret <= 0) {
break;
} else if (FD_ISSET(fd, &fdR)) {
tmpLen = read(fd, buffer + recvLen, len - recvLen);
if(tmpLen <= 0)
break;
recvLen += tmpLen;

contenLen = http_get_alldata_len(buffer);
if((contenLen > 0) && (recvLen >= contenLen))
break;
}
}

u_printf("\r\n******* contentLen=%u recvLen=%u \r\n", contenLen, recvLen);

buffer[recvLen] = '\0';

u_printf("size=%d\r\n", strlen(buffer));



int i;
char buffer2[101];
for (i = 0; i < recvLen; i+=100) {
strncpy(buffer2, buffer+i, recvLen-i < 100 ? recvLen-i : 100);
buffer2[100] = '\0';
u_printf("%s", buffer2);
}
u_printf("\r\n-----------------------\r\n");
msleep(1000);

char *sp1, *sp2;
sp1 = strchr(buffer, ' ');
if (sp1 == NULL) {
u_printf("sp1 not found!\r\n");
return -1;
}
sp2 = strchr(sp1+1, ' ');
if (sp2 == NULL) {
u_printf("sp2 not found!\r\n");
return -1;
}
*sp2 = '\0';

//ignore favicon.ico
//if((recvLen > strlen("GET /favicon.ico")) && (memcmp(buffer, "GET /favicon.ico", strlen("GET /favicon.ico"))==0))
// return 0;

//u_printf("buffer='%s' size=%d\r\n", buffer, strlen(buffer));

if (recvLen > 5) {
struct httpd_page *p = httpd_pages;
char buf[50], *a;
char *r = buffer;
char url[50];

strncpy(url, sp1+1, 50);

u_printf("url='%s' size=%d\r\n", url, strlen(url));

while (p->url != NULL) {
strncpy(buf, url, 50);
buf[49] = '\0';
a = strchr(buf, '?');
if (a != NULL)
*a = '\0';
if (strcmp(p->url, buf) == 0) {
strcpy(r, http_header);
r += strlen(http_header);
p->callback(url, r);
write(fd, buffer, strlen(buffer));
u_printf("'%s' size=%d\r\n", url, strlen(buffer));
msleep(1000);
return 0;
}
p++;
}
}
return -1;
}

static void hf_http_server(void)
{
struct sockaddr_in local_addr, remote_addr;
int listenfd, remotefd;

if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
u_printf("HTTP: socket creat failed!\r\n");
hfthread_destroy(NULL);
return;
}
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(HTTP_SERVER_PORT);
local_addr.sin_len = sizeof(local_addr);
local_addr.sin_addr.s_addr = INADDR_ANY;

if(bind(listenfd, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
u_printf("HTTP: socket bind failed!\r\n");
hfthread_destroy(NULL);
return ;
}

if(listen(listenfd, 10) == -1) {
u_printf("HTTP: socket listen failed!\r\n");
hfthread_destroy(NULL);
return;
}

u_printf("HTTP: https_server start, port=%d\r\n", HTTP_SERVER_PORT);

int len = sizeof(remote_addr);
while(1) {
remotefd = accept(listenfd, (struct sockaddr *)&remote_addr, (socklen_t *)(&len));
if(remotefd >= 0) {
memset(https_recv_buf, 0, HTTPS_RECV_BUF_LEN);
https_recv_data(remotefd, https_recv_buf, HTTPS_RECV_BUF_LEN-1, HTTPS_RECV_TIMEOUT);
}

close(remotefd);
}

//u_printf("HTTPS: https_server exit!\r\n");
//hfthread_destroy(NULL);
return;
}










static const char *css_page = "* {font-family:sans-serif; font-size:12pt;}\r\n"\
"h1 {font-size:16pt; color:black;}\r\n"\
Expand All @@ -127,6 +319,12 @@ void USER_FUNC httpd_init(void)
{
struct hfeasy_state* state = config_get_state();


if(hfthread_create((PHFTHREAD_START_ROUTINE)hf_http_server, "hfhttp_server", 2048, NULL, HFTHREAD_PRIORITIES_LOW, NULL, NULL) != HF_SUCCESS) {
u_printf("error starting http server thread\r\n");
}


/* register url handler callback */
if (hfhttpd_url_callback_register(httpd_callback, state->cfg.http_auth) != HF_SUCCESS)
u_printf("error registering url callback\r\n");
Expand Down

0 comments on commit 8762b9f

Please sign in to comment.