//Callback called when there's data available on a socket. static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short len) { debugConn(arg, "httpdRecvCb"); struct espconn* pCon = (struct espconn *)arg; HttpdConnData *conn = (HttpdConnData *)pCon->reverse; if (conn == NULL) return; // aborted connection char sendBuff[MAX_SENDBUFF_LEN]; httpdSetOutputBuffer(conn, sendBuff, sizeof(sendBuff)); //This is slightly evil/dirty: we abuse conn->post->len as a state variable for where in the http communications we are: //<0 (-1): Post len unknown because we're still receiving headers //==0: No post data //>0: Need to receive post data //ToDo: See if we can use something more elegant for this. for (int x = 0; x<len; x++) { if (conn->post->len<0) { //This byte is a header byte. if (conn->priv->headPos != MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++] = data[x]; conn->priv->head[conn->priv->headPos] = 0; //Scan for /r/n/r/n. Receiving this indicate the headers end. if (data[x] == '\n' && (char *)os_strstr(conn->priv->head, "\r\n\r\n") != NULL) { //Indicate we're done with the headers. conn->post->len = 0; conn->post->multipartBoundary = NULL; //Reset url data conn->url = NULL; //Iterate over all received headers and parse them. char *p = conn->priv->head; while (p<(&conn->priv->head[conn->priv->headPos - 4])) { char *e = (char *)os_strstr(p, "\r\n"); //Find end of header line if (e == NULL) break; //Shouldn't happen. e[0] = 0; //Zero-terminate header httpdParseHeader(p, conn); //and parse it. p = e + 2; //Skip /r/n (now /0/n) } //If we don't need to receive post data, we can send the response now. if (conn->post->len == 0) { httpdProcessRequest(conn); } } } else if (conn->post->len != 0) { //This byte is a POST byte. conn->post->buff[conn->post->buffLen++] = data[x]; conn->post->received++; if (conn->post->buffLen >= conn->post->buffSize || conn->post->received == conn->post->len) { //Received a chunk of post data conn->post->buff[conn->post->buffLen] = 0; //zero-terminate, in case the cgi handler knows it can use strings //Send the response. httpdProcessRequest(conn); conn->post->buffLen = 0; } } } }
//Callback called when there's data available on a socket. static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short len) { int x; char *p, *e; char sendBuff[MAX_SENDBUFF_LEN]; HttpdConnData *conn=httpdFindConnData(arg); if (conn==NULL) return; conn->priv->sendBuff=sendBuff; conn->priv->sendBuffLen=0; for (x=0; x<len; x++) { if (conn->post->len<0) { //This byte is a header byte. if (conn->priv->headPos!=MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++]=data[x]; conn->priv->head[conn->priv->headPos]=0; //Scan for /r/n/r/n if (data[x]=='\n' && (char *)os_strstr(conn->priv->head, "\r\n\r\n")!=NULL) { //Indicate we're done with the headers. conn->post->len=0; //Reset url data conn->url=NULL; //Find end of next header line p=conn->priv->head; while(p<(&conn->priv->head[conn->priv->headPos-4])) { e=(char *)os_strstr(p, "\r\n"); if (e==NULL) break; e[0]=0; httpdParseHeader(p, conn); p=e+2; } //If we don't need to receive post data, we can send the response now. if (conn->post->len==0) { httpdProcessRequest(conn); } } } else if (conn->post->len!=0) { //This byte is a POST byte. conn->post->buff[conn->post->buffLen++]=data[x]; conn->post->received++; if (conn->post->buffLen >= conn->post->buffSize || conn->post->received == conn->post->len) { //Received a chunk of post data conn->post->buff[conn->post->buffLen]=0; //zero-terminate, in case the cgi handler knows it can use strings //Send the response. httpdProcessRequest(conn); conn->post->buffLen = 0; } } } }
void* remoteConfigThread(void* param) { RemoteConfigImpl* self = (RemoteConfigImpl*)param; while(!self->base.requestExit) { struct timeval to = {0, 1000}; if (httpdGetConnection(self->base.http, &to) <= 0) continue; if(httpdReadRequest(self->base.http) < 0) { httpdEndRequest(self->base.http); continue; } remoteConfigLockImpl(self); httpdProcessRequest(self->base.http); remoteConfigUnlockImpl(self); httpdEndRequest(self->base.http); } return nullptr; }
/** Main request handling thread. @param args Two item array of void-cast pointers to the httpd and request struct */ void thread_httpd(void *args) { void **params; httpd *webserver; request *r; params = (void **)args; webserver = *params; r = *(params + 1); free(params); /* XXX We must release this ourselves. */ if (httpdReadRequest(webserver, r) == 0) { /* * We read the request fine */ debug(LOG_DEBUG, "Processing request from %s", r->clientAddr); debug(LOG_DEBUG, "Calling httpdProcessRequest() for %s", r->clientAddr); //前面有通过函数httpdAddCContent设置访问页面的回调函数..如果请求的不是页面没有设置, //那就会调用404错误... //该函数httpdSetErrorFunction会设定404错误的回调函数. httpdProcessRequest(webserver, r); debug(LOG_DEBUG, "Returned from httpdProcessRequest() for %s", r->clientAddr); } else { debug(LOG_DEBUG, "No valid request received from %s", r->clientAddr); } debug(LOG_DEBUG, "Closing connection with %s", r->clientAddr); httpdEndRequest(r); }
int ICACHE_FLASH_ATTR httpdSetCGIResponse(HttpdConnData * conn, void * response) { char sendBuff[MAX_SENDBUFF_LEN]; conn->priv->sendBuff = sendBuff; conn->priv->sendBuffLen = 0; conn->cgiResponse = response; httpdProcessRequest(conn); conn->cgiResponse = NULL; return HTTPD_CGI_DONE; }
int main( int argc, char *argv[]) { httpd *server; /* ** Create a server and setup our logging */ server = httpdCreate(NULL,1234); if (server == NULL) { perror("Can't create server"); exit(1); } httpdSetAccessLog(server, stdout); httpdSetErrorLog(server, stderr); /* ** Setup some content for the server */ httpdAddCContent(server,"/", "dummy", HTTP_TRUE, NULL, dummy_html); httpdSetFileBase(server, "/home/prabinb/queralyzer/queralyzerUI/"); httpdAddFileContent(server, "/", "index.html", HTTP_TRUE, NULL, "index.html" ); httpdAddWildcardContent(server, "/css", NULL, "css"); httpdAddWildcardContent(server, "/img", NULL, "img"); httpdAddWildcardContent(server, "/js", NULL, "js"); httpdAddWildcardContent(server, "/js/lib", NULL, "js/lib"); httpdAddWildcardContent(server, "/bootstrap", NULL, "bootstrap"); httpdAddWildcardContent(server, "/bootstrap/css", NULL, "bootstrap/css"); httpdAddWildcardContent(server, "/bootstrap/img", NULL, "bootstrap/img"); httpdAddWildcardContent(server, "/bootstrap/js", NULL, "bootstrap/js"); httpdAddCContent(server,"/", "query", HTTP_TRUE, NULL, query_html); httpdAddCContent(server,"/", "tablemetadata", HTTP_TRUE, NULL, table_data_html); httpdAddCContent(server,"/", "indexmetadata", HTTP_TRUE, NULL, index_data_html); /* ** Go into our service loop */ while(1 == 1) { if (httpdGetConnection(server, 0) < 0) continue; if(httpdReadRequest(server) < 0) { httpdEndRequest(server); continue; } else { httpdProcessRequest(server); httpdEndRequest(server); } } }
/************************************************ * name: httpdRecvCb * parameters: ptArgument - connection data * pbData - data available * cbDataLength - data length * return value: none * purpose: callback when data available on a socket ************************************************/ static void ICACHE_FLASH_ATTR httpdRecvCb(void * ptArgument, char * pbData, unsigned short cbDataLength) { /* initialization */ int iIndex = 0; char * pbTmpHeader = NULL; char * pbEndOfHeader = NULL; char pbSendBuffer[HTTPD_MAX_SEND_BUFFER_LENGTH] = { 0 }; HttpdConnection * ptConnection = NULL; ptConnection = httpdFindConnData(ptArgument); if (NULL == ptConnection) { return; } ptConnection->ptPrivate->pbSendBuffer = pbSendBuffer; ptConnection->ptPrivate->cbSendBufferLength = 0; for (iIndex = 0; iIndex < cbDataLength; iIndex++) { if (0 > ptConnection->ptPost->cbPostLength) { /* header byte */ if (HTTPD_MAX_HEADER_LENGTH != ptConnection->ptPrivate->cbHeaderLength) { ptConnection->ptPrivate->pbHeader[ptConnection->ptPrivate->cbHeaderLength++]=pbData[iIndex]; } ptConnection->ptPrivate->pbHeader[ptConnection->ptPrivate->cbHeaderLength] = 0; /* scan for /r/n/r/n */ if (((*NEWLINE_SYMBOL_STRING) == pbData[iIndex]) && (NULL != (char *)os_strstr(ptConnection->ptPrivate->pbHeader, "\r\n\r\n"))) { /* indicate we're done with the headers */ ptConnection->ptPost->cbPostLength = 0; /* reset url data */ ptConnection->pszUrl = NULL; /* find end of next header line */ pbTmpHeader = ptConnection->ptPrivate->pbHeader; while (pbTmpHeader < (&ptConnection->ptPrivate->pbHeader[ptConnection->ptPrivate->cbHeaderLength-4])) { pbEndOfHeader = (char *)os_strstr(pbTmpHeader, "\r\n"); if (NULL == pbEndOfHeader) { break; } pbEndOfHeader[0] = 0; httpdParseHeader(pbTmpHeader, ptConnection); pbTmpHeader = pbEndOfHeader + 2; } /* if receive post data unncessary send the response */ if (0 == ptConnection->ptPost->cbPostLength) { httpdProcessRequest(ptConnection); } } } else if (0 != ptConnection->ptPost->cbPostLength) { /* this is a POST byte */ ptConnection->ptPost->pbBuffer[ptConnection->ptPost->cbBufferLength++] = pbData[iIndex]; ptConnection->ptPost->cbReceived++; if ((ptConnection->ptPost->cbBufferLength >= ptConnection->ptPost->cbMaxBufferSize) || (ptConnection->ptPost->cbReceived == ptConnection->ptPost->cbPostLength)) { /* received a chunk of post data */ /* zero-terminate, in case the cgi handler knows it can use strings */ ptConnection->ptPost->pbBuffer[ptConnection->ptPost->cbBufferLength] = 0; /* send the response */ httpdProcessRequest(ptConnection); ptConnection->ptPost->cbBufferLength = 0; } } } }