ESP8266学习笔记(10)——官方WebServer

作者: Leung_ManWah | 来源:发表于2019-02-27 10:28 被阅读6次

    一、背景


    WebServer作为HTTP服务器,接收手机APP请求,配置网关接入网络。

    Post请求和Get请求:


    二、流程

    ① 初始化WebServer,绑定本地端口
    ② 开启监听
    ③ 解析请求数据包
    ④ 回发响应数据包

    三、初始化WebServer

    文件所在 ESP8266_NONOS_SDK-2.1.0\IoT_Demo\user/user_webserver.c
    创建TCP服务端,参考ESP8266学习笔记(5)——TCP/UDP接口使用
    传入参数,本地端口80。

    void ICACHE_FLASH_ATTR
    user_webserver_init(uint32 port)
    {
        tcp_websvr_espconn.type = ESPCONN_TCP;
        tcp_websvr_espconn.state = ESPCONN_NONE;
        tcp_websvr_espconn.proto.tcp = &esptcp;
        tcp_websvr_espconn.proto.tcp->local_port = port;                  // 设置本地端口
    
        espconn_regist_connectcb(&tcp_websvr_espconn, webserver_listen);  // 注册监听成功回调函数
        espconn_accept(&tcp_websvr_espconn);                              // 创建 TCP server,建立监听
    }
    

    四、开启监听

    4.1 监听成功回调函数

    LOCAL void ICACHE_FLASH_ATTR
    webserver_listen(void *arg)
    {
        struct espconn *pesp_conn = arg;
    
        espconn_regist_recvcb(pesp_conn, webserver_recv);      // 注册接收回调函数
        espconn_regist_reconcb(pesp_conn, webserver_recon);    // 注册发送回调函数
        espconn_regist_disconcb(pesp_conn, webserver_discon);  // 注册断连回调函数
    }
    

    4.2 接收回调函数

    里面POST请求中解析JSON数据参考ESP8266学习笔记(7)——JSON接口使用

    /******************************************************************************
     * FunctionName : webserver_recv
     * Description  : Processing the received data from the server
     * Parameters   : arg -- Additional argument to pass to the callback function
     *                pusrdata -- The received data (or NULL when the connection has been closed!)
     *                length -- The length of received data
     * Returns      : none
    *******************************************************************************/
    LOCAL void ICACHE_FLASH_ATTR
    webserver_recv(void *arg, char *pusrdata, unsigned short length)
    {
        URL_Frame *pURL_Frame = NULL;
        char *pParseBuffer = NULL;
        bool parse_flag = false;                        // 解析标志
        struct espconn *ptrespconn = arg;
    
        /* 如果设备没有在升级 */
        if (upgrade_lock == 0)
        {
            os_printf("len:%u\n",length);
            /* 校验数据是否缺失,如果失败跳转做处理 */
            if (check_data(pusrdata, length) == false)  // ------------------下述 5.1
            {
                os_printf("goto\n");
                goto _temp_exit;
            }
    
             /* 校验数据长度后存储起来,开启解析标志 */
            parse_flag = save_data(pusrdata, length);   // ------------------下述 5.2
    
            if (parse_flag == false)
            {
                response_send(ptrespconn, false);       // ------------------下述 6.1
            }
            os_printf("pusrdata:%s\n", pusrdata);
    
            /* 为URL框架申请空间 */
            pURL_Frame = (URL_Frame *)os_zalloc(sizeof(URL_Frame));  // ------------------下述 5.3
            /* 解析数据,加入URL框架 */
            parse_url(precvbuffer, pURL_Frame);         // ------------------下述 5.4
            os_printf("Type:%d, Select:%s, Command:%s, Filename:%s ",
                    pURL_Frame->Type,pURL_Frame->pSelect,pURL_Frame->pCommand,pURL_Frame->pFilename);
    
            switch (pURL_Frame->Type)
            {
            case GET:
                os_printf("We have a GET request.\n");
    
                if (os_strcmp(pURL_Frame->pSelect, "client") == 0 &&
                        os_strcmp(pURL_Frame->pCommand, "command") == 0)
                {
                    if (os_strcmp(pURL_Frame->pFilename, "info") == 0)
                    {
                        json_send(ptrespconn, INFOMATION);
                    }
                    if (os_strcmp(pURL_Frame->pFilename, "status") == 0)
                    {
                        json_send(ptrespconn, CONNECT_STATUS);
                    }
                    else if (os_strcmp(pURL_Frame->pFilename, "scan") == 0)
                    {
                        char *strstr = NULL;
                        strstr = (char *)os_strstr(pusrdata, "&");
    
                        if (strstr == NULL)
                        {
                            if (pscaninfo == NULL)
                            {
                                pscaninfo = (scaninfo *)os_zalloc(sizeof(scaninfo));
                            }
    
                            pscaninfo->pespconn = ptrespconn;
                            pscaninfo->pagenum = 0;
                            pscaninfo->page_sn = 0;
                            pscaninfo->data_cnt = 0;
                            wifi_station_scan(NULL, json_scan_cb);
                            } else {
                                strstr ++;
    
                                if (os_strncmp(strstr, "page", 4) == 0) {
                                    if (pscaninfo != NULL) {
                                        pscaninfo->pagenum = *(strstr + 5);
                                        pscaninfo->pagenum -= 0x30;
    
                                        if (pscaninfo->pagenum > pscaninfo->totalpage || pscaninfo->pagenum == 0) {
                                            response_send(ptrespconn, false);
                                        } else {
                                            json_send(ptrespconn, SCAN);
                                        }
                                    } else {
                                        response_send(ptrespconn, false);
                                    }
                                } else if(os_strncmp(strstr, "finish", 6) == 0){
                                    bss_temp = bss_head;
                                    while(bss_temp != NULL) {
                                        bss_head = bss_temp->next.stqe_next;
                                        os_free(bss_temp);
                                        bss_temp = bss_head;
                                    }
                                    bss_head = NULL;
                                    bss_temp = NULL;
                                    response_send(ptrespconn, true);
                                } else {
                                    response_send(ptrespconn, false);
                                }
                            }
                        } else {
                            response_send(ptrespconn, false);
                        }
                    } else if (os_strcmp(pURL_Frame->pSelect, "config") == 0 &&
                               os_strcmp(pURL_Frame->pCommand, "command") == 0) {
                        if (os_strcmp(pURL_Frame->pFilename, "wifi") == 0) {
                            ap_conf = (struct softap_config *)os_zalloc(sizeof(struct softap_config));
                            sta_conf = (struct station_config *)os_zalloc(sizeof(struct station_config));
                            json_send(ptrespconn, WIFI);
                            os_free(sta_conf);
                            os_free(ap_conf);
                            sta_conf = NULL;
                            ap_conf = NULL;
                        }
    
    #if PLUG_DEVICE
                        else if (os_strcmp(pURL_Frame->pFilename, "switch") == 0) {
                            json_send(ptrespconn, SWITCH_STATUS);
                        }
    #endif
                        else if (os_strcmp(pURL_Frame->pFilename, "reboot") == 0) {
                            json_send(ptrespconn, REBOOT);
                        } else {
                            response_send(ptrespconn, false);
                        }
                    } else if (os_strcmp(pURL_Frame->pSelect, "upgrade") == 0 &&
                            os_strcmp(pURL_Frame->pCommand, "command") == 0) {
                            if (os_strcmp(pURL_Frame->pFilename, "getuser") == 0) {
                                json_send(ptrespconn , USER_BIN);
                            }
                    } else {
                        response_send(ptrespconn, false);
                    }
    
                    break;
    
                case POST:
                    os_printf("We have a POST request.\n");
                    pParseBuffer = (char *)os_strstr(precvbuffer, "\r\n\r\n");
    
                    if (pParseBuffer == NULL) {
                        break;
                    }
    
                    pParseBuffer += 4;
    
                    if (os_strcmp(pURL_Frame->pSelect, "config") == 0 &&
                            os_strcmp(pURL_Frame->pCommand, "command") == 0) {
    
                        if (os_strcmp(pURL_Frame->pFilename, "reboot") == 0) {
    
                            if (pParseBuffer != NULL) {
                                if (restart_10ms != NULL) {
                                    os_timer_disarm(restart_10ms);
                                }
    
                                if (rstparm == NULL) {
                                    rstparm = (rst_parm *)os_zalloc(sizeof(rst_parm));
                                }
    
                                rstparm->pespconn = ptrespconn;
    
                                rstparm->parmtype = REBOOT;
    
                                if (restart_10ms == NULL) {
                                    restart_10ms = (os_timer_t *)os_malloc(sizeof(os_timer_t));
                                }
    
                                os_timer_setfn(restart_10ms, (os_timer_func_t *)restart_10ms_cb, NULL);
                                os_timer_arm(restart_10ms, 10, 0);  // delay 10ms, then do
    
                                response_send(ptrespconn, true);
                            } else {
                                response_send(ptrespconn, false);
                            }
                        } else if (os_strcmp(pURL_Frame->pFilename, "wifi") == 0) {
                            if (pParseBuffer != NULL) {
                                struct jsontree_context js;
                                user_esp_platform_set_connect_status(DEVICE_CONNECTING);
    
                                if (restart_10ms != NULL) {
                                    os_timer_disarm(restart_10ms);
                                }
    
                                if (ap_conf == NULL) {
                                    ap_conf = (struct softap_config *)os_zalloc(sizeof(struct softap_config));
                                }
    
                                if (sta_conf == NULL) {
                                    sta_conf = (struct station_config *)os_zalloc(sizeof(struct station_config));
                                }
    
                                jsontree_setup(&js, (struct jsontree_value *)&wifi_req_tree, json_putchar);
                                json_parse(&js, pParseBuffer);
    
                                if (rstparm == NULL) {
                                    rstparm = (rst_parm *)os_zalloc(sizeof(rst_parm));
                                }
    
                                rstparm->pespconn = ptrespconn;
                                rstparm->parmtype = WIFI;
    
                                if (sta_conf->ssid[0] != 0x00 || ap_conf->ssid[0] != 0x00) {
                                    ap_conf->ssid_hidden = 0;
                                    ap_conf->max_connection = 4;
    
                                    if (restart_10ms == NULL) {
                                        restart_10ms = (os_timer_t *)os_malloc(sizeof(os_timer_t));
                                    }
    
                                    os_timer_disarm(restart_10ms);
                                    os_timer_setfn(restart_10ms, (os_timer_func_t *)restart_10ms_cb, NULL);
                                    os_timer_arm(restart_10ms, 10, 0);  // delay 10ms, then do
                                } else {
                                    os_free(ap_conf);
                                    os_free(sta_conf);
                                    os_free(rstparm);
                                    sta_conf = NULL;
                                    ap_conf = NULL;
                                    rstparm =NULL;
                                }
    
                                response_send(ptrespconn, true);
                            } else {
                                response_send(ptrespconn, false);
                            }
                        }
    
                        else if (os_strcmp(pURL_Frame->pFilename, "switch") == 0) {
                            if (pParseBuffer != NULL) {
                                struct jsontree_context js;
                                jsontree_setup(&js, (struct jsontree_value *)&StatusTree, json_putchar);
                                json_parse(&js, pParseBuffer);
                                // ----------Altered by Leung 2018.11.12-------START
                                if (user_plug_get_status() == 1)                    // 获取继电器状态
                                {
                                    data_send(ptrespconn, true, "{\"status\": 1}"); // 返回APP继电器状态——打开
                                }
                                else
                                {
                                    data_send(ptrespconn, true, "{\"status\": 0}"); // 返回APP继电器状态——关闭
                                }
                                // ----------Altered by Leung 2018.11.12-------END
                            } else {
                                response_send(ptrespconn, false);
                            }
                        }
                        else {
                            response_send(ptrespconn, false);
                        }
                    }
                    else if(os_strcmp(pURL_Frame->pSelect, "upgrade") == 0 &&
                            os_strcmp(pURL_Frame->pCommand, "command") == 0){
                        if (os_strcmp(pURL_Frame->pFilename, "start") == 0){
                            response_send(ptrespconn, true);
                            os_printf("local upgrade start\n");
                            upgrade_lock = 1;
                            system_upgrade_init();
                            system_upgrade_flag_set(UPGRADE_FLAG_START);
                            os_timer_disarm(&upgrade_check_timer);
                            os_timer_setfn(&upgrade_check_timer, (os_timer_func_t *)upgrade_check_func, NULL);
                            os_timer_arm(&upgrade_check_timer, 120000, 0);
                        } else if (os_strcmp(pURL_Frame->pFilename, "reset") == 0) {
    
                            response_send(ptrespconn, true);
                            os_printf("local upgrade restart\n");
                            system_upgrade_reboot();
                        } else {
                            response_send(ptrespconn, false);
                        }
                    }else {
                        response_send(ptrespconn, false);
                    }
                     break;
            }
    
            if (precvbuffer != NULL){
                os_free(precvbuffer);
                precvbuffer = NULL;
            }
            os_free(pURL_Frame);
            pURL_Frame = NULL;
            _temp_exit:
                ;
        }
        else if(upgrade_lock == 1){
            local_upgrade_download(ptrespconn,pusrdata, length);
            if (precvbuffer != NULL){
                os_free(precvbuffer);
                precvbuffer = NULL;
            }
            os_free(pURL_Frame);
            pURL_Frame = NULL;
        }
    }
    

    五、解析请求数据包

    5.1 check_data()

    校验收到数据是否正确,判断收到数据的总长度是否等于“Content-Length:”里所描述的长度。

    LOCAL bool ICACHE_FLASH_ATTR
    check_data(char *precv, uint16 length)
    {
        char length_buf[10] = {0};
        char *ptemp = NULL;
        char *pdata = NULL;
        char *tmp_precvbuffer;
        uint16 tmp_length = length;
        uint32 tmp_totallength = 0;
    
        ptemp = (char *)os_strstr(precv, "\r\n\r\n");
        
        if (ptemp != NULL) {
            tmp_length -= ptemp - precv;
            tmp_length -= 4;
            tmp_totallength += tmp_length;
            
            pdata = (char *)os_strstr(precv, "Content-Length: ");
            
            if (pdata != NULL){
                pdata += 16;
                tmp_precvbuffer = (char *)os_strstr(pdata, "\r\n");
                
                if (tmp_precvbuffer != NULL){
                    os_memcpy(length_buf, pdata, tmp_precvbuffer - pdata);
                    dat_sumlength = atoi(length_buf);
                    os_printf("A_dat:%u,tot:%u,lenght:%u\n",dat_sumlength,tmp_totallength,tmp_length);
                    if(dat_sumlength != tmp_totallength){
                        return false;
                    }
                }
            }
        }
        return true;
    }
    

    5.2 save_data()

    将收到的数据校验长度后,存储起来。

    LOCAL char *precvbuffer;
    static uint32 dat_sumlength = 0;
    
    LOCAL bool ICACHE_FLASH_ATTR
    save_data(char *precv, uint16 length)
    {
        bool flag = false;
        char length_buf[10] = {0};
        char *ptemp = NULL;
        char *pdata = NULL;
        uint16 headlength = 0;
        static uint32 totallength = 0;
    
        ptemp = (char *)os_strstr(precv, "\r\n\r\n");
    
        if (ptemp != NULL) {
            length -= ptemp - precv;
            length -= 4;
            totallength += length;
            headlength = ptemp - precv + 4;
            pdata = (char *)os_strstr(precv, "Content-Length: ");
    
            if (pdata != NULL) {
                pdata += 16;
                precvbuffer = (char *)os_strstr(pdata, "\r\n");
    
                if (precvbuffer != NULL) {
                    os_memcpy(length_buf, pdata, precvbuffer - pdata);
                    dat_sumlength = atoi(length_buf);
                }
            } else {
                if (totallength != 0x00){
                    totallength = 0;
                    dat_sumlength = 0;
                    return false;
                }
            }
            if ((dat_sumlength + headlength) >= 1024) {
                precvbuffer = (char *)os_zalloc(headlength + 1);
                os_memcpy(precvbuffer, precv, headlength + 1);
            } else {
                precvbuffer = (char *)os_zalloc(dat_sumlength + headlength + 1);
                os_memcpy(precvbuffer, precv, os_strlen(precv));
            }
        } else {
            if (precvbuffer != NULL) {
                totallength += length;
                os_memcpy(precvbuffer + os_strlen(precvbuffer), precv, length);
            } else {
                totallength = 0;
                dat_sumlength = 0;
                return false;
            }
        }
    
        if (totallength == dat_sumlength) {
            totallength = 0;
            dat_sumlength = 0;
            return true;
        } else {
            return false;
        }
    }
    

    5.3 URL_Frame

    typedef struct URL_Frame {
        enum ProtocolType Type;
        char pSelect[URLSize];
        char pCommand[URLSize];
        char pFilename[URLSize];
    } URL_Frame;
    

    5.4 parse_url()

    /******************************************************************************
     * FunctionName : parse_url
     * Description  : parse the received data from the server
     * Parameters   : precv -- the received data
     *                purl_frame -- the result of parsing the url
     * Returns      : none
    *******************************************************************************/
    LOCAL void ICACHE_FLASH_ATTR
    parse_url(char *precv, URL_Frame *purl_frame)
    {
        char *str = NULL;
        uint8 length = 0;
        char *pbuffer = NULL;
        char *pbufer = NULL;
    
        if (purl_frame == NULL || precv == NULL) {
            return;
        }
    
        pbuffer = (char *)os_strstr(precv, "Host:");
    
        if (pbuffer != NULL) {
            length = pbuffer - precv;
            pbufer = (char *)os_zalloc(length + 1);
            pbuffer = pbufer;
            os_memcpy(pbuffer, precv, length);
            os_memset(purl_frame->pSelect, 0, URLSize);
            os_memset(purl_frame->pCommand, 0, URLSize);
            os_memset(purl_frame->pFilename, 0, URLSize);
    
            if (os_strncmp(pbuffer, "GET ", 4) == 0) {
                purl_frame->Type = GET;
                pbuffer += 4;
            } else if (os_strncmp(pbuffer, "POST ", 5) == 0) {
                purl_frame->Type = POST;
                pbuffer += 5;
            }
    
            pbuffer ++;
            str = (char *)os_strstr(pbuffer, "?");
    
            if (str != NULL) {
                length = str - pbuffer;
                os_memcpy(purl_frame->pSelect, pbuffer, length);
                str ++;
                pbuffer = (char *)os_strstr(str, "=");
    
                if (pbuffer != NULL) {
                    length = pbuffer - str;
                    os_memcpy(purl_frame->pCommand, str, length);
                    pbuffer ++;
                    str = (char *)os_strstr(pbuffer, "&");
    
                    if (str != NULL) {
                        length = str - pbuffer;
                        os_memcpy(purl_frame->pFilename, pbuffer, length);
                    } else {
                        str = (char *)os_strstr(pbuffer, " HTTP");
    
                        if (str != NULL) {
                            length = str - pbuffer;
                            os_memcpy(purl_frame->pFilename, pbuffer, length);
                        }
                    }
                }
            }
    
            os_free(pbufer);
        } else {
            return;
        }
    }
    

    六、回发响应数据包

    6.1 response_send()

    回复简单格式,里面调用data_send()

    /******************************************************************************
     * FunctionName : response_send
     * Description  : processing the send result
     * Parameters   : arg -- argument to set for client or server
     *                responseOK --  true or false
     * Returns      : none
    *******************************************************************************/
    LOCAL void ICACHE_FLASH_ATTR
    response_send(void *arg, bool responseOK)
    {
        struct espconn *ptrespconn = arg;
    
        data_send(ptrespconn, responseOK, NULL);
    }
    

    6.2 json_send()

    里面生成JSON数据json_ws_send()参考ESP8266学习笔记(7)——JSON接口使用

    /******************************************************************************
     * FunctionName : json_send
     * Description  : processing the data as json format and send to the client or server
     * Parameters   : arg -- argument to set for client or server
     *                ParmType -- json format type
     * Returns      : none
    *******************************************************************************/
    LOCAL void ICACHE_FLASH_ATTR
    json_send(void *arg, ParmType ParmType)
    {
        char *pbuf = NULL;
        pbuf = (char *)os_zalloc(jsonSize);
        struct espconn *ptrespconn = arg;
    
        switch (ParmType) {
    
    #if PLUG_DEVICE
            case SWITCH_STATUS:
                json_ws_send((struct jsontree_value *)&StatusTree, "switch", pbuf);
                os_printf("switch:%s", pbuf);
                break;
    #endif
    
            case INFOMATION:
                json_ws_send((struct jsontree_value *)&INFOTree, "info", pbuf);
                break;
    
            case WIFI:
                json_ws_send((struct jsontree_value *)&wifi_info_tree, "wifi", pbuf);
                break;
    
            case CONNECT_STATUS:
                json_ws_send((struct jsontree_value *)&con_status_tree, "info", pbuf);
                break;
    
            case USER_BIN:
                json_ws_send((struct jsontree_value *)&userinfo_tree, "user_info", pbuf);
                break;
            case SCAN: {
                u8 i = 0;
                u8 scancount = 0;
                struct bss_info *bss = NULL;
                bss = bss_head;
                if (bss == NULL) {
                    os_free(pscaninfo);
                    pscaninfo = NULL;
                    os_sprintf(pbuf, "{\n\"successful\": false,\n\"data\": null\n}");
                } else {
                    do {
                        if (pscaninfo->page_sn == pscaninfo->pagenum) {
                            pscaninfo->page_sn = 0;
                            os_sprintf(pbuf, "{\n\"successful\": false,\n\"meessage\": \"repeated page\"\n}");
                            break;
                        }
    
                        scancount = scannum - (pscaninfo->pagenum - 1) * 8;
    
                        if (scancount >= 8) {
                            pscaninfo->data_cnt += 8;
                            pscaninfo->page_sn = pscaninfo->pagenum;
    
                            if (pscaninfo->data_cnt > scannum) {
                                pscaninfo->data_cnt -= 8;
                                os_sprintf(pbuf, "{\n\"successful\": false,\n\"meessage\": \"error page\"\n}");
                                break;
                            }
    
                            json_ws_send((struct jsontree_value *)&scan_tree, "scan", pbuf);
                        } else {
                            pscaninfo->data_cnt += scancount;
                            pscaninfo->page_sn = pscaninfo->pagenum;
    
                            if (pscaninfo->data_cnt > scannum) {
                                pscaninfo->data_cnt -= scancount;
                                os_sprintf(pbuf, "{\n\"successful\": false,\n\"meessage\": \"error page\"\n}");
                                break;
                            }
    
                            char *ptrscanbuf = (char *)os_zalloc(jsonSize);
                            char *pscanbuf = ptrscanbuf;
                            os_sprintf(pscanbuf, ",\n\"ScanResult\": [\n");
                            pscanbuf += os_strlen(pscanbuf);
    
                            for (i = 0; i < scancount; i ++) {
                                JSONTREE_OBJECT(page_tree,
                                                JSONTREE_PAIR("page", &scaninfo_tree));
                                json_ws_send((struct jsontree_value *)&page_tree, "page", pscanbuf);
                                os_sprintf(pscanbuf + os_strlen(pscanbuf), ",\n");
                                pscanbuf += os_strlen(pscanbuf);
                            }
    
                            os_sprintf(pscanbuf - 2, "]\n");
                            JSONTREE_OBJECT(scantree,
                                            JSONTREE_PAIR("TotalPage", &scan_callback),
                                            JSONTREE_PAIR("PageNum", &scan_callback));
                            JSONTREE_OBJECT(scanres_tree,
                                            JSONTREE_PAIR("Response", &scantree));
                            JSONTREE_OBJECT(scan_tree,
                                            JSONTREE_PAIR("scan", &scanres_tree));
                            json_ws_send((struct jsontree_value *)&scan_tree, "scan", pbuf);
                            os_memcpy(pbuf + os_strlen(pbuf) - 4, ptrscanbuf, os_strlen(ptrscanbuf));
                            os_sprintf(pbuf + os_strlen(pbuf), "}\n}");
                            os_free(ptrscanbuf);
                        }
                    } while (0);
                }
    
                break;
            }
    
            default :
                break;
        }
    
        data_send(ptrespconn, true, pbuf);
        os_free(pbuf);
        pbuf = NULL;
    }
    

    6.3 data_send()

    /******************************************************************************
     * FunctionName : data_send
     * Description  : processing the data as http format and send to the client or server
     * Parameters   : arg -- argument to set for client or server
     *                responseOK -- true or false
     *                psend -- The send data
     * Returns      :
    *******************************************************************************/
    LOCAL void ICACHE_FLASH_ATTR
    data_send(void *arg, bool responseOK, char *psend)
    {
        uint16 length = 0;
        char *pbuf = NULL;
        char httphead[256];
        struct espconn *ptrespconn = arg;
        os_memset(httphead, 0, 256);
    
        if (responseOK) {
            os_sprintf(httphead,
                       "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nServer: lwIP/1.4.0\r\n",
                       psend ? os_strlen(psend) : 0);
    
            if (psend) {
                os_sprintf(httphead + os_strlen(httphead),
                           "Content-type: application/json\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n");
                length = os_strlen(httphead) + os_strlen(psend);
                pbuf = (char *)os_zalloc(length + 1);
                os_memcpy(pbuf, httphead, os_strlen(httphead));
                os_memcpy(pbuf + os_strlen(httphead), psend, os_strlen(psend));
            } else {
                os_sprintf(httphead + os_strlen(httphead), "\n");
                length = os_strlen(httphead);
            }
        } else {
            os_sprintf(httphead, "HTTP/1.0 400 BadRequest\r\n\
    Content-Length: 0\r\nServer: lwIP/1.4.0\r\n\n");
            length = os_strlen(httphead);
        }
    
        if (psend) {
            espconn_sent(ptrespconn, pbuf, length);
        } 
        else {
            espconn_sent(ptrespconn, httphead, length);
        }
    
        if (pbuf) {
            os_free(pbuf);
            pbuf = NULL;
        }
    }
    

    七、printf打印内容

    len:491
    A_dat:25,tot:25,lenght:25
    pusrdata:POST /config?command=switch HTTP/1.1
    Accept: application/json,application/xml,application/xhtml+xml,text/html;q=0.9,image/webp,*/*;q=0.8
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh
    Connection: keep-alive
    Content-Type: application/json; charset=utf-8
    User-Agent: Mozilla/5.0 (Linux; U; Android 5.0.2; zh-cn; Redmi Note 2 Build/LRX22G) AppleWebKit/533.1 (KHTML, like Gecko) Version/5.0 Mobile Safari/533.1
    Content-Length: 25
    Host: 192.168.0.52
    
    {"Response":{"status":0}}
    Type:1, Select:config, Command:command, Filename:switch We have a POST request.
    

    • 由 Leung 写于 2019 年 2 月 27 日

    • 参考:ESP8266_NONOS_SDK-2.1.0[vqhl]
        ESP8266 Non-OS SDK API参考[zj6w]

    相关文章

      网友评论

        本文标题:ESP8266学习笔记(10)——官方WebServer

        本文链接:https://www.haomeiwen.com/subject/tdrzyqtx.html