improve & reduce the http logging

pull/65/head
Thorsten von Eicken 9 years ago
parent f5b4177b8c
commit d9b2a0466b
  1. 134
      httpd/httpd.c
  2. 7
      httpd/httpd.h

@ -33,10 +33,12 @@ static HttpdBuiltInUrl *builtInUrls;
//Private data for http connection //Private data for http connection
struct HttpdPriv { struct HttpdPriv {
char head[MAX_HEAD_LEN]; char head[MAX_HEAD_LEN]; // buffer to accumulate header
int headPos; char from[24]; // source ip&port
char *sendBuff; char *sendBuff; // output buffer
int sendBuffLen; short headPos; // offset into header
short sendBuffLen; // offset into output buffer
short code; // http response code (only for logging)
}; };
//Connection pool //Connection pool
@ -93,56 +95,32 @@ static void debugConn(void *arg, char *what) {
os_sprintf(connStr, "%d.%d.%d.%d:%d ", os_sprintf(connStr, "%d.%d.%d.%d:%d ",
tcp->remote_ip[0], tcp->remote_ip[1], tcp->remote_ip[2], tcp->remote_ip[3], tcp->remote_ip[0], tcp->remote_ip[1], tcp->remote_ip[2], tcp->remote_ip[3],
tcp->remote_port); tcp->remote_port);
//os_printf("%s %s\n", connStr, what); os_printf("%s %s\n", connStr, what);
#else #else
connStr[0] = 0; connStr[0] = 0;
#endif #endif
} }
//Looks up the connData info for a specific esp connection // Retires a connection for re-use
static HttpdConnData ICACHE_FLASH_ATTR *httpdFindConnData(void *arg) { static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) {
struct espconn *espconn = arg; if (conn->conn && conn->conn->reverse == conn)
for (int i = 0; i<MAX_CONN; i++) { conn->conn->reverse = NULL; // break reverse link
if (connData[i].remote_port == espconn->proto.tcp->remote_port &&
os_memcmp(connData[i].remote_ip, espconn->proto.tcp->remote_ip, 4) == 0)
{
#if 0
#ifdef HTTPD_DBG
os_printf("FindConn: 0x%p->0x%p", arg, &connData[i]);
if (arg == connData[i].conn) os_printf("\n");
else os_printf(" *** was 0x%p\n", connData[i].conn);
#endif
#endif
if (arg != connData[i].conn) connData[i].conn = arg; // yes, this happens!?
return &connData[i];
}
}
//Shouldn't happen.
#ifdef HTTPD_DBG #ifdef HTTPD_DBG
os_printf("%s*** Unknown connection 0x%p\n", connStr, arg); // log information about the request we handled
uint32 dt = conn->startTime;
if (dt > 0) dt = (system_get_time() - dt) / 1000;
if (conn->conn && conn->url)
os_printf("HTTP %s %s from %s -> %d in %ums, heap=%ld\n",
conn->requestType == HTTPD_METHOD_GET ? "GET" : "POST", conn->url, conn->priv->from,
conn->priv->code, dt, (unsigned long)system_get_free_heap_size());
#endif #endif
return NULL;
}
//Retires a connection for re-use
static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) {
conn->conn = NULL; // don't try to send anything, the SDK crashes... conn->conn = NULL; // don't try to send anything, the SDK crashes...
if (conn->cgi != NULL) conn->cgi(conn); // free cgi data if (conn->cgi != NULL) conn->cgi(conn); // free cgi data
if (conn->post->buff != NULL) { if (conn->post->buff != NULL) os_free(conn->post->buff);
os_free(conn->post->buff);
}
conn->cgi = NULL; conn->cgi = NULL;
conn->post->buff = NULL; conn->post->buff = NULL;
conn->remote_port = 0;
conn->remote_ip[0] = 0;
uint32 dt = conn->startTime;
if (dt > 0) dt = (system_get_time() - dt) / 1000;
#ifdef HTTPD_DBG
os_printf("%sHTTP %s in %ums, heap=%ld\n", connStr,
conn->requestType == HTTPD_METHOD_GET ? "GET" : "POST", dt,
(unsigned long)system_get_free_heap_size());
#endif
} }
//Stupid li'l helper function that returns the value of a hex char. //Stupid li'l helper function that returns the value of a hex char.
@ -242,6 +220,7 @@ int ICACHE_FLASH_ATTR httpdGetHeader(HttpdConnData *conn, char *header, char *re
void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code) { void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code) {
char buff[128]; char buff[128];
int l; int l;
conn->priv->code = code;
char *status = code < 400 ? "OK" : "ERROR"; char *status = code < 400 ? "OK" : "ERROR";
l = os_sprintf(buff, "HTTP/1.0 %d %s\r\nServer: esp-link\r\nConnection: close\r\n", code, status); l = os_sprintf(buff, "HTTP/1.0 %d %s\r\nServer: esp-link\r\nConnection: close\r\n", code, status);
httpdSend(conn, buff, l); httpdSend(conn, buff, l);
@ -266,7 +245,9 @@ void ICACHE_FLASH_ATTR httpdEndHeaders(HttpdConnData *conn) {
void ICACHE_FLASH_ATTR httpdRedirect(HttpdConnData *conn, char *newUrl) { void ICACHE_FLASH_ATTR httpdRedirect(HttpdConnData *conn, char *newUrl) {
char buff[1024]; char buff[1024];
int l; int l;
l = os_sprintf(buff, "HTTP/1.0 302 Found\r\nServer: esp8266-link\r\nConnection: close\r\nLocation: %s\r\n\r\nRedirecting to %s\r\n", newUrl, newUrl); conn->priv->code = 302;
l = os_sprintf(buff, "HTTP/1.0 302 Found\r\nServer: esp8266-link\r\nConnection: close\r\n"
"Location: %s\r\n\r\nRedirecting to %s\r\n", newUrl, newUrl);
httpdSend(conn, buff, l); httpdSend(conn, buff, l);
} }
@ -314,11 +295,11 @@ static void ICACHE_FLASH_ATTR xmitSendBuff(HttpdConnData *conn) {
//Callback called when the data on a socket has been successfully sent. //Callback called when the data on a socket has been successfully sent.
static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) { static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) {
debugConn(arg, "httpdSentCb"); debugConn(arg, "httpdSentCb");
int r; struct espconn* pCon = (struct espconn *)arg;
HttpdConnData *conn = httpdFindConnData(arg); HttpdConnData *conn = (HttpdConnData *)pCon->reverse;
char sendBuff[MAX_SENDBUFF_LEN]; if (conn == NULL) return; // aborted connection
if (conn == NULL) return; char sendBuff[MAX_SENDBUFF_LEN];
conn->priv->sendBuff = sendBuff; conn->priv->sendBuff = sendBuff;
conn->priv->sendBuffLen = 0; conn->priv->sendBuffLen = 0;
@ -328,7 +309,7 @@ static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) {
return; //No need to call xmitSendBuff. return; //No need to call xmitSendBuff.
} }
r = conn->cgi(conn); //Execute cgi fn. int r = conn->cgi(conn); //Execute cgi fn.
if (r == HTTPD_CGI_DONE) { if (r == HTTPD_CGI_DONE) {
conn->cgi = NULL; //mark for destruction. conn->cgi = NULL; //mark for destruction.
} }
@ -341,7 +322,8 @@ static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) {
xmitSendBuff(conn); xmitSendBuff(conn);
} }
static const char *httpNotFoundHeader = "HTTP/1.0 404 Not Found\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nNot Found.\r\n"; static const char *httpNotFoundHeader = "HTTP/1.0 404 Not Found\r\nConnection: close\r\n"
"Content-Type: text/plain\r\nContent-Length: 12\r\n\r\nNot Found.\r\n";
//This is called when the headers have been received and the connection is ready to send //This is called when the headers have been received and the connection is ready to send
//the result headers and data. //the result headers and data.
@ -438,18 +420,9 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
// Count number of open connections // Count number of open connections
#ifdef HTTPD_DBG #ifdef HTTPD_DBG
#if 0 //esp_tcp *tcp = conn->conn->proto.tcp;
int open = 0; //os_printf("%sHTTP %s %s from %s\n", connStr,
for (int j = 0; j<MAX_CONN; j++) if (connData[j].conn != NULL) open++; // conn->requestType == HTTPD_METHOD_GET ? "GET" : "POST", conn->url, conn->priv->from);
os_printf("%s%s %s (%d conn open)\n", connStr,
conn->requestType == HTTPD_METHOD_GET ? "GET" : "POST", conn->url, open);
#else
esp_tcp *tcp = conn->conn->proto.tcp;
os_printf("%sHTTP %s %s from %d.%d.%d.%d:%d\n", connStr,
conn->requestType == HTTPD_METHOD_GET ? "GET" : "POST", conn->url,
tcp->remote_ip[0], tcp->remote_ip[1], tcp->remote_ip[2], tcp->remote_ip[3],
tcp->remote_port);
#endif
#endif #endif
//Parse out the URL part before the GET parameters. //Parse out the URL part before the GET parameters.
conn->getArgs = (char*)os_strstr(conn->url, "?"); conn->getArgs = (char*)os_strstr(conn->url, "?");
@ -502,11 +475,11 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
//Callback called when there's data available on a socket. //Callback called when there's data available on a socket.
static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short len) { static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short len) {
debugConn(arg, "httpdRecvCb"); debugConn(arg, "httpdRecvCb");
int x; struct espconn* pCon = (struct espconn *)arg;
char *p, *e; HttpdConnData *conn = (HttpdConnData *)pCon->reverse;
if (conn == NULL) return; // aborted connection
char sendBuff[MAX_SENDBUFF_LEN]; char sendBuff[MAX_SENDBUFF_LEN];
HttpdConnData *conn = httpdFindConnData(arg);
if (conn == NULL) return;
conn->priv->sendBuff = sendBuff; conn->priv->sendBuff = sendBuff;
conn->priv->sendBuffLen = 0; conn->priv->sendBuffLen = 0;
@ -516,7 +489,7 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short
//>0: Need to receive post data //>0: Need to receive post data
//ToDo: See if we can use something more elegant for this. //ToDo: See if we can use something more elegant for this.
for (x = 0; x<len; x++) { for (int x = 0; x<len; x++) {
if (conn->post->len<0) { if (conn->post->len<0) {
//This byte is a header byte. //This byte is a header byte.
if (conn->priv->headPos != MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++] = data[x]; if (conn->priv->headPos != MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++] = data[x];
@ -528,9 +501,9 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short
//Reset url data //Reset url data
conn->url = NULL; conn->url = NULL;
//Iterate over all received headers and parse them. //Iterate over all received headers and parse them.
p = conn->priv->head; char *p = conn->priv->head;
while (p<(&conn->priv->head[conn->priv->headPos - 4])) { while (p<(&conn->priv->head[conn->priv->headPos - 4])) {
e = (char *)os_strstr(p, "\r\n"); //Find end of header line char *e = (char *)os_strstr(p, "\r\n"); //Find end of header line
if (e == NULL) break; //Shouldn't happen. if (e == NULL) break; //Shouldn't happen.
e[0] = 0; //Zero-terminate header e[0] = 0; //Zero-terminate header
httpdParseHeader(p, conn); //and parse it. httpdParseHeader(p, conn); //and parse it.
@ -559,8 +532,9 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short
static void ICACHE_FLASH_ATTR httpdDisconCb(void *arg) { static void ICACHE_FLASH_ATTR httpdDisconCb(void *arg) {
debugConn(arg, "httpdDisconCb"); debugConn(arg, "httpdDisconCb");
HttpdConnData *conn = httpdFindConnData(arg); struct espconn* pCon = (struct espconn *)arg;
if (conn == NULL) return; HttpdConnData *conn = (HttpdConnData *)pCon->reverse;
if (conn == NULL) return; // aborted connection
httpdRetireConn(conn); httpdRetireConn(conn);
} }
@ -568,11 +542,13 @@ static void ICACHE_FLASH_ATTR httpdDisconCb(void *arg) {
// of "you need to reconnect". Sigh... Note that there is no DisconCb after ReconCb // of "you need to reconnect". Sigh... Note that there is no DisconCb after ReconCb
static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) { static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) {
debugConn(arg, "httpdReconCb"); debugConn(arg, "httpdReconCb");
HttpdConnData *conn = httpdFindConnData(arg); struct espconn* pCon = (struct espconn *)arg;
HttpdConnData *conn = (HttpdConnData *)pCon->reverse;
if (conn == NULL) return; // aborted connection
#ifdef HTTPD_DBG #ifdef HTTPD_DBG
os_printf("%s***** reset, err=%d\n", connStr, err); os_printf("%s***** reset, err=%d\n", connStr, err);
#endif #endif
if (conn == NULL) return;
httpdRetireConn(conn); httpdRetireConn(conn);
} }
@ -580,14 +556,13 @@ static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) {
static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) { static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) {
debugConn(arg, "httpdConnectCb"); debugConn(arg, "httpdConnectCb");
struct espconn *conn = arg; struct espconn *conn = arg;
// Find empty conndata in pool
int i; int i;
//Find empty conndata in pool
for (i = 0; i<MAX_CONN; i++) if (connData[i].conn == NULL) break; for (i = 0; i<MAX_CONN; i++) if (connData[i].conn == NULL) break;
//os_printf("Con req, conn=%p, pool slot %d\n", conn, i); //os_printf("Con req, conn=%p, pool slot %d\n", conn, i);
if (i == MAX_CONN) { if (i == MAX_CONN) {
#ifdef HTTPD_DBG os_printf("%sHTTP: conn pool overflow!\n", connStr);
os_printf("%sAiee, conn pool overflow!\n", connStr);
#endif
espconn_disconnect(conn); espconn_disconnect(conn);
return; return;
} }
@ -602,9 +577,12 @@ static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) {
connData[i].priv = &connPrivData[i]; connData[i].priv = &connPrivData[i];
connData[i].conn = conn; connData[i].conn = conn;
connData[i].remote_port = conn->proto.tcp->remote_port; conn->reverse = connData+i;
os_memcpy(connData[i].remote_ip, conn->proto.tcp->remote_ip, 4);
connData[i].priv->headPos = 0; connData[i].priv->headPos = 0;
esp_tcp *tcp = conn->proto.tcp;
os_sprintf(connData[i].priv->from, "%d.%d.%d.%d:%d", tcp->remote_ip[0], tcp->remote_ip[1],
tcp->remote_ip[2], tcp->remote_ip[3], tcp->remote_port);
connData[i].post = &connPostData[i]; connData[i].post = &connPostData[i];
connData[i].post->buff = NULL; connData[i].post->buff = NULL;
connData[i].post->buffLen = 0; connData[i].post->buffLen = 0;

@ -21,11 +21,10 @@ typedef int (* cgiSendCallback)(HttpdConnData *connData);
//A struct describing a http connection. This gets passed to cgi functions. //A struct describing a http connection. This gets passed to cgi functions.
struct HttpdConnData { struct HttpdConnData {
struct espconn *conn; struct espconn *conn;
int remote_port; //int remote_port;
uint8 remote_ip[4]; //uint8 remote_ip[4];
uint32 startTime; uint32 startTime;
char requestType; char requestType; // HTTP_METHOD_GET | HTTPD_METHOD_POST
char *url; char *url;
char *getArgs; char *getArgs;
const void *cgiArg; const void *cgiArg;

Loading…
Cancel
Save