httpd 是 Apache HTTP Server 的守护进程名称,Apache HTTP Server 是一种广泛使用的开源网页服务器软件。
本项目是从LwIP中抽取的HTTP服务器代码;
`Hi3861 SDK`中已经包含了一份预编译的lwip,但没有开启HTTP服务器功能(静态库无法修改);
HTTP 服务器特性
目前已测试通过的功能有:
- 通过HTTP访问静态资源文件
- 通过cgi回调函数处理表单和页面跳转
静态资源文件:
- 本服务器实现不支持实际的服务端本地文件系统访问;
- 取而代之的是,一种简单的虚拟文件系统:
- \\third_party\httpd\src\http\fs.c 文件提供了一套文件系统接口,使用数组直接存储文件数据
- \\third_party\httpd\src\http\fsdata.c文件是由 makefsdata命令生成的虚拟文件系统元数据文件
- makefsdata 命令行工具,用于将一个目录下的静态资源文件转换为 fsdata.c文件
代码编写
修改D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
lite_component("demo") {
features = [
#"base_00_helloworld:base_helloworld_example",
#"base_01_led:base_led_example",
#"base_02_loopkey:base_loopkey_example",
#"base_03_irqkey:base_irqkey_example",
#"base_04_adc:base_adc_example",
#"base_05_pwm:base_pwm_example",
#"base_06_ssd1306:base_ssd1306_example",
#"kernel_01_task:kernel_task_example",
#"kernel_02_timer:kernel_timer_example",
#"kernel_03_event:kernel_event_example",
#"kernel_04_mutex:kernel_mutex_example",
#"kernel_05_semaphore_as_mutex:kernel_semaphore_as_mutex_example",
#"kernel_06_semaphore_for_sync:kernel_semaphore_for_sync_example",
#"kernel_07_semaphore_for_count:kernel_semaphore_for_count_example",
#"kernel_08_message_queue:kernel_message_queue_example",
#"wifi_09_hotspot:wifi_hotspot_example",
#"wifi_10_sta:wifi_sta_example",
#"tcp_11_server:tcp_server_example",
#"tcp_12_client:tcp_client_example",
#"udp_13_server:udp_server_example",
#"udp_14_client:udp_client_example",
#"network_15_mqtt:network_mqtt_example",
#"network_16_sntp:network_sntp_example",
"network_17_httpd:network_httpd_example",
]
}
创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_17_httpd文件夹
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_17_httpd\BUILD.gn文件
# Copyright (c) 2020, HiHope Community.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static_library("network_httpd_example") {
sources = [
"network_httpd_example.c",
"wifi_connecter.c",
"//third_party/httpd/src/core/altcp.c",
"//third_party/httpd/src/core/altcp_tcp.c",
"//third_party/httpd/src/http/fs.c",
"//third_party/httpd/src/http/httpd.c",
"//third_party/httpd/src/tcp_port.c",
# "//third_party/httpd/src/pbuf_port.c",
]
defines = [
"LWIP_DEBUG",
"HTTPD_DEBUG=0xA0",
"LWIP_DBG_TYPES_ON=LWIP_DBG_ON",
"LWIP_HTTPD_SSI"
]
include_dirs = [
"//third_party/httpd/include",
"//third_party/httpd/include/lwip/apps",
"//foundation/communication/wifi_lite/interfaces/wifiservice",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
]
}
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_17_httpd\wifi_connecter.h文件,该头文件包含wifi连接的宏。文件同network_16_sntp\wifi_connecter.h
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_17_httpd\wifi_connecter.c文件,文件同network_16_sntp\wifi_connecter.c
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\network_17_httpd\network_httpd_example.c文件
/*
* Copyright (c) 2020, HiHope Community.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
// #include "wifiiot_at.h"
#include "httpd.h"
#include "wifi_connecter.h"
static int g_netId = -1;
#define STACK_SIZE (4096)
#ifdef LWIP_HTTPD_CGI
const char *HelloHandler(int iIndex, int nParams, char *pcParam[], char *pcValue[])
{
printf("HelloHandler\r\n");
printf("iIndex = %d\r\n", iIndex);
for (int i = 0; i < nParams; i++) {
printf("pcParam[%d] = '%s'\r\n", i, pcParam[i]);
printf("pcValue[%d] = '%s'\r\n", i, pcValue[i]);
}
return "/index.html"; // forward to home page.
}
static tCGI g_cgiHandlers[] = {
{ "/hello", HelloHandler },
};
#endif
#if LWIP_HTTPD_SSI
u16_t FooSsiHandler(
#if LWIP_HTTPD_SSI_RAW
const char* tag,
#else /* LWIP_HTTPD_SSI_RAW */
int tag,
#endif /* LWIP_HTTPD_SSI_RAW */
char *pcInsert, int iInsertLen
#if LWIP_HTTPD_SSI_MULTIPART
, u16_t currentTagPart, u16_t *nextTagPart
#endif /* LWIP_HTTPD_SSI_MULTIPART */
#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
, void *connectionState
#endif /* LWIP_HTTPD_FILE_STATE */
)
{
printf("FooSsiHandler\r\n");
#if LWIP_HTTPD_SSI_RAW
printf("tag = %s\r\n", tag);
#else
printf("tag = %d\r\n", tag);
#endif
printf("insertLen = %d\r\n", iInsertLen);
printf("insertText = %s\r\n", pcInsert);
return 0;
}
#endif
static void HttpdTask(void)
{
WifiDeviceConfig config = {0};
// 准备AP的配置参数
// strcpy(config.ssid, PARAM_HOTSPOT_SSID);
// strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);
strcpy_s(config.ssid, WIFI_MAX_SSID_LEN, PARAM_HOTSPOT_SSID);
strcpy_s(config.preSharedKey, WIFI_MAX_KEY_LEN, PARAM_HOTSPOT_PSK);
config.securityType = PARAM_HOTSPOT_TYPE;
g_netId = ConnectToHotspot(&config);
printf("netId = %d\r\n", g_netId);
#ifdef LWIP_HTTPD_CGI
http_set_cgi_handlers(g_cgiHandlers, LWIP_ARRAYSIZE(g_cgiHandlers));
#endif
#ifdef LWIP_HTTPD_SSI
http_set_ssi_handler(FooSsiHandler, NULL, 0);
#endif
httpd_init();
}
static void HttpdEntry(void)
{
osThreadAttr_t attr = {0};
attr.name = "HttpdTask";
attr.stack_size = STACK_SIZE;
attr.priority = osPriorityNormal;
if (osThreadNew(HttpdTask, NULL, &attr) == NULL) {
printf("[HttpdEntry] create HttpdTask failed!\n");
}
}
SYS_RUN(HttpdEntry);
使用build,编译成功后,使用upload进行烧录。
访问网页
串口输出