DICOM:剖析Orthanc中的Web Server, Mongoose

时间:2021-08-31 10:03:08

背景:

        

        DICOM专栏文章中介绍过解构PACS(分布式PACS)Orthanc的安装和使用,以及相关插件、SQLite数据库等主要模块的分析,此次简单介绍Orthanc中嵌入的Web Server,Mongoose。依托于Mongoose这一轻量级Web Server,Orthanc很好的实现了RESTful API与传统DICOM服务的整合,这也是实现分布式PACS的关键。博文中先给出Mongoose的安装和简单的与C/C++的嵌入式编程,让大家对Mongoose有一个初步的认识,后续再深入分析。

Mongoose Web Server:

        

        Mongoose Web Server的官网地址是http://cesanta.com/mongoose.shtml,开源项目托管在GoogleCode上(http://code.google.com/p/mongoose/),目前国内只能使用VPN打开。Mongoose英文原意代表一种动物的名字,这里Mongoose指的是一个Web服务器,通过提供一个web接口给它,可以轻松嵌入到现有的应用程序中。Mongoose Web Server的执行是自满足的,不依赖于任何其他服务。可随意将其复制到任何目录,它将启动web服务并将当前目录作为主目录、端口号是8080。当然这些配置选项都可以通过配置文件mongoose.conf设置。

DICOM:剖析Orthanc中的Web Server, Mongoose

下载与安装:

        想快速体验一下Mongoose,可到官网中直接下载免费版的安装包双击打开即可,官网中有与Windows、MacOS、Linux系统分别对应的安装包,如下图所示:

DICOM:剖析Orthanc中的Web Server, Mongoose


        作为优秀的开源项目,我们自然希望是下载到源码,对于Mongoose来说源码很少,只有mongoose.h和mongoose.c两个文件。其源码在Github的托管地址是https://github.com/cesanta/mongoose,从代码仓库中可以看到官方源码包中除了包含mongoose.h和mongoose.c源码文件外,还给出了说明文档和测试用例,这里我们下载完整的mongoose源码包,便于后续的学习和使用。在Mongoose的代码仓库中README.md文件给出了一个下载链接DownLoads,该处的链接与官网中下载运行包的流程略有不同,选择好对应版本后需要我们输入联系人方式才可获得下载链接。比较奇葩的是邮箱地址中输入163、126和QQ邮箱都会提示格式错误,看来只能使用国外的邮箱,例如GMail、Hotmail了。鉴于GMail目前在国内的服务稳定性,我直接选择使用Hotmail。


DICOM:剖析Orthanc中的Web Server, Mongoose


        输入正确的邮箱地址后,会收到一封官方发来的邮件,打开其中的链接即可下载Mongoose的源码包。实在不行也可以直接从Github上Clone也可以。

        按照以往对于开源项目的使用流程,接下来应该是本地编译。由于Mongoose源码只有mongoose.h和mongoose.c,且自包含,这里就不单独介绍如何编译这两个源码文件了,对于有编程经验的人来说so easy,当然如果你使用Linux系统也可以参考该博文Mongoose源码剖析:Introduction and Installation

编译尝试:

        在本地创建一个C++的控制台工程,开始直接将Mongoose嵌入其中。此处的参考资料就是源码包中的docs文件夹下的Embed.md。

DICOM:剖析Orthanc中的Web Server, Mongoose


        本地建立MongooseEmbbed工程,为了结构清晰建立mongoose_source文件夹,将mongoose.h和mongoose.c文件拷贝到其中,打开MongooseEmbbed.sln工程,右键添加“现有项目”,分别将mongoose.h和mongoose.c文件添加到头文件和源文件中,如下图所示:

DICOM:剖析Orthanc中的Web Server, Mongoose


        接下来按照Embed.md文件的说明,在工程文件MongooseEmbbed.cpp中输入示例代码,具体代码如下(直接从Embed.md中拷贝所得),

// MongooseEmbbed.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "mongoose.h"


int _tmain(int argc, _TCHAR* argv[])
{
struct mg_server *server= mg_create_server(NULL,NULL);
mg_set_option(server,"document_root",".");
mg_set_option(server,"listening_port","8080");

for(;;)
{
mg_poll_server(server,1000);
}
mg_destroy_server(&server);

return 0;
}

        按下F6启动工程编译,竟然出现了错误,接下来让我们看一下如何解决错误。

编译错误与解决方案:


错误1:        

        首先遇到的错误如下图,

DICOM:剖析Orthanc中的Web Server, Mongoose


        从错误提示中可以看出这应该是预编译头出现的错误,该问题最简单的解决方案就是在工程属性的“预编译头”中取消预编译,当然取消预编译后对于庞大的工程来说编译时间会增加很多,对于该问题的分析大家可参考预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)。在这里由于工程很小我就直接采用关闭预编译的方式来解决,如下图操作:


DICOM:剖析Orthanc中的Web Server, Mongoose


        修改完成后,F6启动编译又出现了新的错误,具体错误如下。

错误2:

DICOM:剖析Orthanc中的Web Server, Mongoose


        百度搜索一下,关于该问题的解决方案都是说添加_CRT_NONSTDC_NO_DEPRECATE预定义即可,因此起初尝试了在代码工程中直接添加#define _CRT_NONSTDC_NO_DEPRECATE或者#define _CRT_NONSTDC_NO_DEPRECATE 1,无论是放在#include "stdafx.h"代码之前还是之后,依然出现该错误。后来想想其实对于预处理器的定义在VS中应该是在工程属性的预处理器项目下添加,如下图尝试后,能够顺利完成MongooseEmbeed.sln工程的编译。


DICOM:剖析Orthanc中的Web Server, Mongoose


运行测试:

        

        接下来让我们启动MongooseEmbbed.sln工程,实际测试一下。在浏览器中输入:http://localhost:8080,此处的8080是我们在工程主文件中设置的Mongoose Web Server的监听端口号,具体测试结果如下:


DICOM:剖析Orthanc中的Web Server, Mongoose


        上图右侧显示的就是MongooseEmbbed工程所在目录下的文件列表,Mongoose Web Server会默认将工程所在目录作为Web Server的主目录。之前在介绍WEB PACS的系列博文中提到过Web Server有一个默认的索引文件,通常叫做index.html(当然在配置选项中也可以进行*设置)。在Mongoose源码包的examples文件夹下给我们准备了多种index.html,让我们将mongoose-5.5\mongoose-5.5\examples\restful_api\index.html拷贝到工程主目录下,再一次启动本地工程,此次我们看到Mongoose Web Server自动加载了主目录下的index.html文档,具体运行结果如下图:


DICOM:剖析Orthanc中的Web Server, Mongoose


        对于Mongoose Web Server的设置在MongooseEmbbed.sln代码中仅仅展示了设置Web服务主目录和监听端口,对于index files的设置没有介绍,但是从mongoose.c源码中可以简单的看出mongoose默认的index文件的顺序,即index.html,index.htm,index.shtml,index.cgi,index.php,其他的默认配置如下。

static const char *static_config_options[] = {
"access_control_list", NULL,
#ifndef MONGOOSE_NO_FILESYSTEM
"access_log_file", NULL,
#ifndef MONGOOSE_NO_AUTH
"auth_domain", "mydomain.com",
#endif
#ifndef MONGOOSE_NO_CGI
"cgi_interpreter", NULL,
"cgi_pattern", DEFAULT_CGI_PATTERN,
#endif
"dav_auth_file", NULL,
"document_root", NULL,
#ifndef MONGOOSE_NO_DIRECTORY_LISTING
"enable_directory_listing", "yes",
#endif
#endif
"enable_proxy", NULL,
"extra_mime_types", NULL,
#if !defined(MONGOOSE_NO_FILESYSTEM) && !defined(MONGOOSE_NO_AUTH)
"global_auth_file", NULL,
#endif
#ifndef MONGOOSE_NO_FILESYSTEM
"hide_files_patterns", NULL,
"hexdump_file", NULL,
"index_files","index.html,index.htm,index.shtml,index.cgi,index.php",
#endif
"listening_port", NULL,
#ifndef _WIN32
"run_as_user", NULL,
#endif
#ifndef MONGOOSE_NO_SSI
"ssi_pattern", "**.shtml$|**.shtm$",
#endif
"url_rewrites", NULL,
NULL
};


        至此,对于Mongoose Web Server的安装和本地嵌入的简短介绍就完成了,从上述代码可以看出Mongoose与Apache等其他Web Server类同,我们也可以按照自己意愿来配置Mongoose Web Server,对于Mongoose的源码剖析和配置后再后续博文中进行介绍,敬请期待。




作者:zssure@163.com

时间:2015-01-25