webserver实现
最近的工作需求client和server使用https协议进行通讯,我负责client编写程序,在操作系统的-depth理解认为一旦前webserver实现,整理代码:
#include"apue.h" extern char **environ;
void clienterror(int fd,char *cause,char *errnum,char *shortmsg,char *longmsg)
{
char buf[MAXLINE],body[MAXLINE];
sprintf(body,"<html><title>Tiny Error</title>");
sprintf(body,"%s<body bgcolor=""ffffff"">\r\n",body);
sprintf(body,"%s%s:%s\r\n",body,errnum,shortmsg);
sprintf(body,"%s<p>%s:%s\r\n",body,longmsg,cause);
sprintf(body,"%s<hr><em>The tiny Web server</em?\r\n",body); sprintf(buf,"HTTP/1.0 %s %s\r\n",errnum,shortmsg);
rio_writen(fd,buf,strlen(buf));
sprintf(buf,"Content-type:text/html\r\n");
rio_writen(fd,buf,strlen(buf));
sprintf(buf,"Content-length:%d\r\n\r\n",(int)strlen(body));
rio_writen(fd,buf,strlen(buf));
rio_writen(fd,body,strlen(body));
} void read_requesthdrs(rio_t *rp)
{ char buf[MAXLINE];
rio_readlineb(rp,buf,MAXLINE);
while(strcmp(buf,"\r\n"))
{
rio_readlineb(rp,buf,MAXLINE);
printf("%s",buf);
}
return;
} int parse_uri(char *uri,char *filename,char *cgiargs)
{
char *ptr;
printf("parse_uri(uri):%s\n",uri);
if(!strstr(uri,"cgi-bin"))
{
strcpy(cgiargs,"");
strcpy(filename,".");
strcat(filename,uri);
if(uri[strlen(uri)-1]=='/')
strcat(filename,"home.html");
return 1;
} else
{
ptr=index(uri,'?');
if(ptr)
{
strcpy(cgiargs,ptr+1);
*ptr='\0';
}
else
strcpy(cgiargs,"");
strcpy(filename,".");
strcat(filename,uri);
return 0; }
} void get_filetype(char *filename,char *filetype)
{ if(strstr(filename,".html"))
strcpy(filetype,"text/html");
else if(strstr(filename,".gif"))
strcpy(filetype,"image/gif");
else if(strstr(filename,".jpg"))
strcpy(filetype,"image/jpeg");
else
strcpy(filetype,"text/plain");
} void serve_dynamic(int fd,char *filename,char *caiargs)
{
char buf[MAXLINE],*emptylist[]={NULL}; sprintf(buf,"HTTP/1.0 200 OK\r\n");
rio_writen(fd,buf,strlen(buf));
sprintf(buf,"Server:Tiny Web Server\r\n");
rio_writen(fd,buf,strlen(buf)); if(fork()==0)
{
setenv("QUERY_STRING",caiargs,1);
dup2(fd,STDOUT_FILENO);
execve(filename,emptylist,environ);
}
wait(NULL);
} void serve_static(int fd,char *filename,int filesize)
{ int srcfd;
char *srcp,filetype[MAXLINE],buf[MAXLINE]; get_filetype(filename,filetype);
sprintf(buf,"HTTP/1.0 200 OK\r\n");
sprintf(buf,"%sServer:Tiny Web Server\r\n",buf);
sprintf(buf,"%sContent-length:%d\r\n",buf,filesize);
sprintf(buf,"%sContent-type:%s\r\n\r\n",buf,filetype);
rio_writen(fd,buf,strlen(buf)); srcfd=open(filename,O_RDONLY,0);
srcp=mmap(0,filesize,PROT_READ,MAP_PRIVATE,srcfd,0);
close(srcfd);
rio_writen(fd,srcp,filesize);
munmap(srcp,filesize);
} void doit(int fd)
{
int is_static;
struct stat sbuf;
char buf[MAXLINE],method[MAXLINE],uri[MAXLINE],version[MAXLINE];
char filename[MAXLINE],cgiargs[MAXLINE];
rio_t rio; rio_readinitb(&rio,fd);
rio_readlineb(&rio,buf,MAXLINE);
sscanf(buf,"%s %s %s",method,uri,version);
if(strcasecmp(method,"GET"))
{
clienterror(fd,method,"501","Not implemented","Tiny does not implemented this method");
return;
} read_requesthdrs(&rio); is_static=parse_uri(uri,filename,cgiargs);
if(stat(filename,&sbuf)<0)
{
clienterror(fd,filename,"404","Not found","Tiny couldn't find this file");
return;
} if(is_static)
{
if(!(S_ISREG(sbuf.st_mode))||!(S_IRUSR&sbuf.st_mode))
{
clienterror(fd,filename,"403","Forbidden","Tiny could't read the file");
return;
}
serve_static(fd,filename,sbuf.st_size);
}
else
{
if(!(S_ISREG(sbuf.st_mode))|!(S_IXUSR&sbuf.st_mode))
{
clienterror(fd,filename,"403","Forbidden","Tiny could't run the CGI program");
return;
}
serve_dynamic(fd,filename,cgiargs);
} } int main(int argc,char **argv)
{
int listenfd,connfd,port,clientlen;
struct sockaddr_in clientaddr; if(argc!=2)
{
fprintf(stderr,"usage:%s <port> \n",argv[0]);
exit(0);
} port=atoi(argv[1]); listenfd=open_listenfd(port);
while(1)
{
clientlen=sizeof(clientaddr);
connfd=accept(listenfd,(SA*)&clientaddr,&clientlen);
doit(connfd);
close(connfd);
}
}
我们能够直接使用浏览器測试上面的程序。比方当前server程序的文件夹以下有一个index.html,仅仅要我们在浏览器中输入:
localhost:<port>/index.html就能够请求到index.html
server端收到的浏览器请求行例如以下:
版权声明:本文博客原创文章,博客,未经同意,不得转载。
webserver实现的更多相关文章
- WebServer+ADO+百万数据查询
很简单的demo,查询速度快,易理解,废话不说 上demo 看完就明白了 源码地址:http://files.cnblogs.com/files/SpadeA/WebDemo.zip 这是关于Web ...
- webserver[实时查询当天的天气情况]
1.webserver是什么? 日常生活中经常会使用到webserver,注册时,会收到验证码,购买东西时,会收到短信,假如,A公司网站和B公司合作,那么A公司注册对的用户可以直接推送给B网站,那怎么 ...
- Warning: file_put_contents(data.txt): failed to open stream: Permission denied in /Library/WebServer/Documents/test.php on line 22
最近在学习PHP 在保存文件的时候报Warning: file_put_contents(data.txt): failed to open stream: Permission denied in ...
- [C#] 图文解说调用WebServer实例
本文旨在实现如何在.NET环境下调用WebServer,以天气接口为例进行说明. WebServer地址:http://www.webxml.com.cn/WebServices/WeatherWeb ...
- python开启简单webserver
python开启简单webserver linux下面使用 python -m SimpleHTTPServer 8000 windows下面使用上面的命令会报错,Python.Exe: No Mod ...
- C# 如何调用WebServer函数
WebServer(ASMX)服务程序网站的编写简单总结. WebServer中遇到的问题 编写WebServer程序VS运行调试时如果出现 System.Data.OracleClient.Orac ...
- [Top-Down Approach] Assignment 1: WebServer [Python]
Today I complete Socket Programming Assignment 1 Web Server Here is the code: #!/usr/bin/python2.7 # ...
- 【监控】WebServer入库与缓存更新代码优化小计
问题描述: 通过WebServer将监控数据入库到Hbase,在入库之前需要将指标与ip的列表更新到缓存中,以便前台页面随时选择查看.前两天上了一些新用户导致负载增加,逐渐发现某些用户的监控场景出现丢 ...
- Linux WebServer WebRoot Path Identification
目录 . HTTPD(Apache) . NGINX . TENGINE . JBOSS . TOMCAT . LIGHTTPD 1. HTTPD(Apache) 0x1: 启动参数 Usage: . ...
- iOS - Apache Tomcat WebServer 服务器配置
前言 提前下载好相关软件,且安装目录最好安装在全英文路径下.如果路径有中文名,那么可能会出现一些莫名其妙的问题. 提前准备好的软件: apache-tomcat-6.0.45.tar.gz eclip ...
随机推荐
- eclipse luna 无法安装veloeclipse问题
问题: 在eclipse 4.4(luna)版本号.安装veloeclipse 2.0.8时,在即将完毕的时候出现下面错误提示: An error occurred while installing ...
- oracle查询和编写数据字典
在项目交付时假设须要编写数据字典,能够採用以下的方法.首先执行以下的sql语句 SELECT A.TABLE_NAME AS 表名, A.COLUMN_NAME AS 字段名, DECODE(A.CH ...
- Java 抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是工厂方法模式的进一步抽象,其英文原话"Provide an interface for creating families ...
- JS window.open()财产
一. Window 对象 Window 对象是 JavaScript 顶级对象层次. Window 对象表示一个浏览器窗口或帧. Window 在对象 <body> 或 <frame ...
- IOS设计模式学习(11)中介者
1 前言 面向对象的设计鼓励把行为分散到不同对象中.这种分散可能导致对象之间的相互关联.在最糟糕的情况下,所有对象都彼此了解并相互操作.但是增加的相互关联又减少了获得的益处.增加的关联似的对象很难或不 ...
- [Erlang危机](5.1.0)VM检测概述
原创文章.转载请注明出处:server非业余研究http://blog.csdn.net/erlib 作者Sunface 把执行指标储存在VM的内存中.能够指定是全局的还是app所特有的. • vms ...
- 【6】和作为连续序列s
称号:输入一个整数s,并打印出所有s整数的连续序列(含有至少2的数量). 如输入9,输出2.3.4和4.5两个序列 方案一:因为序列至少要2个数,则两个数上限值为(1+s)/2,我们能够枚举该序列的起 ...
- POJ 3422 Kaka's Matrix Travels(费用流)
POJ 3422 Kaka's Matrix Travels 题目链接 题意:一个矩阵.从左上角往右下角走k趟,每次走过数字就变成0,而且获得这个数字,要求走完之后,所获得数字之和最大 思路:有点类似 ...
- EmEditor Professional(文本编辑) 下载地址
http://www.greenxf.com/soft/2126.html 16.1.5 http://www.cr173.com/soft/3031.html 16.3.0
- partial 的好处
1.可以将一个类中的属 性, 方法分类来写 2.方法了可以写在多个类中, 这样可以对方法进行分类 由于项目上使用了代码生成工具, 自定义的一些按钮事件默认是不生成的,得自己定义,如果把定义的代码写 ...