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 ...
随机推荐
- swift-辞典NSDictionary定义,变化的关键,删/加入关键
// Playground - noun: a place where people can play import UIKit //--------------------------------- ...
- jQuery来源学习笔记:扩展的实用功能
// 扩展的实用功能 jQuery.extend({ // http://www.w3school.com.cn/jquery/core_noconflict.asp // 释放$的 jQuery 控 ...
- Qt计算器开发(二):信号槽实现数学表达式合法性检查
表达式的合法性 由于我们的计算器不是单步计算的,所以我们能够一次性输入一个长表达式.然而假设用户输入的长表达式不合法的话,那么就会引发灾难.所以有必要对于用户的输入做一个限制. 一些限制举例: 比方, ...
- poj 2288 Islands and Bridges
题意: 给你一个双向连通图,求 获得权值最大 的 哈密顿通路的 权值 和 这个权值对应的数目: 其中权值计算方法是 列如 ABCD 权值是a+b+c+d+ab+bc+cd 如果 A,B,C 和B ...
- Java SE学习之数组——匿名数组和不规则数组
本文是学习网络上的文章时的总结以及自己的一点实践.感谢大家无私的分享. 近期偶然遇到了数组的问题,学习了匿名数组和不规则数组. 匿名数组适用于仅仅使用一次的情况:不规则数组适用是每行数据总数不确定的情 ...
- 微软研究院的分布式云计算框架orleans
orleans Orleans 客户端请求的消息流转以及消息在Silo中再路由机制 Witte 2015-04-29 21:58 阅读:196 评论:0 一种基于Orleans的分布式Id ...
- 解决IIS7中出现An error occurred on the server when processing the URL错误提示的方法
在IIS7上配置一个asp程序,出现了一个错如提示: An error occurred on the server when processing the URL. Please contact t ...
- 编程基础——C/C++,Java,ObjC讨论回调模式
什么是回调? 因为它是从C开始进入编程世界.术语改只是口.叫习惯了.java里通常叫listener(监听器).C/C++里通常叫callback(回调),ObjC里面叫delegate(托付) 回调 ...
- php 二维数组传递给 js 问题解决记录
需求: php从数据库中读取到二维数组.传递到js中 实现步骤: php:json_encode → json → js:eval 即在php中使用json_encode()将php的二维数 ...
- Machine Learning—Linear Regression
Evernote的同步分享:Machine Learning-Linear Regression 版权声明:本文博客原创文章.博客,未经同意,不得转载.