int httpd_req_recv(httpd_req_t *r, char *buf, size_t buf_len) { if (r == NULL || buf == NULL) { return HTTPD_SOCK_ERR_INVALID; } if (!httpd_valid_req(r)) { ESP_LOGW(TAG, LOG_FMT("invalid request")); return HTTPD_SOCK_ERR_INVALID; } struct httpd_req_aux *ra = r->aux; ESP_LOGD(TAG, LOG_FMT("remaining length = %d"), ra->remaining_len); if (buf_len > ra->remaining_len) { buf_len = ra->remaining_len; } if (buf_len == 0) { return buf_len; } int ret = httpd_recv(r, buf, buf_len); if (ret < 0) { ESP_LOGD(TAG, LOG_FMT("error in httpd_recv")); return ret; } ra->remaining_len -= ret; ESP_LOGD(TAG, LOG_FMT("received length = %d"), ret); return ret; }
int htsys_getln_soc(int sd, char *data_p, int buflen) { int len = 0; char *c_p; int result; // ASSERT(data_p != NULL); c_p = data_p; /* Read one byte at a time */ while ((result = httpd_recv(sd, c_p, 1, 0)) != 0) { /* error on recv */ if (result == -1) { *c_p = 0; httpd_d("recv failed len: %d, err: 0x%x", len, serr); return -kInProgressErr; } /* If new line... */ if ((*c_p == ISO_nl) || (*c_p == ISO_cr)) { result = httpd_recv(sd, c_p, 1, 0); if ((*c_p != ISO_nl) && (*c_p != ISO_cr)) { httpd_d("should get double CR LF: %d, %d", (int)*c_p, result); } break; } len++; c_p++; /* give up here since we'll at least need 3 more chars to * finish off the line */ if (len >= buflen - 1) { httpd_d("buf full: recv didn't read complete line."); break; } } *c_p = 0; return len; }
void http_xtcp_handler(chanend tcp_svr, xtcp_connection_t *conn, chanend page_svr, chanend led_svr) { // Ignore events that are not directly relevant to http switch (conn->event) { case XTCP_IFUP: case XTCP_IFDOWN: case XTCP_ALREADY_HANDLED: return; default: break; } if (conn->local_port == 80) { switch (conn->event) { case XTCP_NEW_CONNECTION: httpd_init_state(tcp_svr, conn); break; case XTCP_RECV_DATA: httpd_recv(tcp_svr, conn, page_svr, led_svr); break; case XTCP_SENT_DATA: case XTCP_REQUEST_DATA: case XTCP_RESEND_DATA: httpd_handle_send_request(tcp_svr, conn, page_svr, led_svr); break; case XTCP_CLOSED: case XTCP_TIMED_OUT: case XTCP_ABORTED: httpd_free_state(conn); break; default: break; } conn->event = XTCP_ALREADY_HANDLED; } }
/* * @pre Only first line of HTTP header (which has the resource name) has * been read from the socket. We need to read the remaining header and the * data after that. */ void httpd_purge_socket_data(httpd_request_t *req, char *msg_in, int msg_in_len, int conn) { int status = httpd_parse_hdr_tags(req, conn, msg_in, msg_in_len); if (status != WM_SUCCESS) { /* We were unsuccessful in purging the socket.*/ httpd_e("Unable to purge socket: %d", status); return; } unsigned data_remaining = req->body_nbytes; while (data_remaining) { unsigned to_read = msg_in_len >= data_remaining ? data_remaining : msg_in_len; int actually_read = httpd_recv(conn, msg_in, to_read, 0); if (actually_read < 0) { httpd_e("Unable to read content." "Was purging socket data"); return; } data_remaining -= actually_read; } }
// HTTP event handler void tcp_handle_event(chanend tcp_svr, xtcp_connection_t *conn) { // We have received an event from the TCP stack, so respond // appropriately // Ignore events that are not directly relevant to http switch (conn->event) { case XTCP_IFUP: { xtcp_ipconfig_t ipconfig; xtcp_get_ipconfig(tcp_svr, &ipconfig); #if IPV6 unsigned short a; unsigned int i; int f; xtcp_ipaddr_t *addr = &ipconfig.ipaddr; printstr("IPV6 Address = ["); for(i = 0, f = 0; i < sizeof(xtcp_ipaddr_t); i += 2) { a = (addr->u8[i] << 8) + addr->u8[i + 1]; if(a == 0 && f >= 0) { if(f++ == 0) { printstr("::"); } } else { if(f > 0) { f = -1; } else if(i > 0) { printstr(":"); } printhex(a); } } printstrln("]"); #else printstr("IP Address: "); printint(ipconfig.ipaddr[0]);printstr("."); printint(ipconfig.ipaddr[1]);printstr("."); printint(ipconfig.ipaddr[2]);printstr("."); printint(ipconfig.ipaddr[3]);printstr("\n"); #endif } return; case XTCP_IFDOWN: case XTCP_ALREADY_HANDLED: return; default: break; } // Check if the connection is a http connection if (conn->local_port == 80) { switch (conn->event) { case XTCP_NEW_CONNECTION: httpd_init_state(tcp_svr, conn); break; case XTCP_RECV_DATA: httpd_recv(tcp_svr, conn); break; case XTCP_SENT_DATA: case XTCP_REQUEST_DATA: case XTCP_RESEND_DATA: httpd_send(tcp_svr, conn); break; case XTCP_TIMED_OUT: case XTCP_ABORTED: case XTCP_CLOSED: httpd_free_state(conn); break; default: // Ignore anything else break; } conn->event = XTCP_ALREADY_HANDLED; } //// return; }