Nginx如何处理一个请求

基于名字的虚拟主机

Nginx首先选定由哪一个虚拟主机来处理请求。让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听)开始:

server {
    listen      80;
    server_name xtgxiso.cn www.xtgxiso.cn;
    ...
}

server {
    listen      80;
    server_name xtgxiso.net www.xtgxiso.net;
    ...
}

server {
    listen      80;
    server_name xtgxiso.com www.xtgxiso.com;
    ...
}

在这个配置中,nginx仅仅检查请求的“Host”头以决定该请求应由哪个虚拟主机来处理。如果Host头没有匹配任意一个虚拟主机,或者请求中根本没
有包含Host头,那nginx会将请求分发到定义在此端口上的默认虚拟主机。在以上配置中,第一个被列出的虚拟主机即nginx的默认虚拟主机——这是
nginx的默认行为。而且,可以显式地设置某个主机为默认虚拟主机,即在”listen”指令中设置”default_server”参数

server {
    listen      80 default_server;
    server_name xtgxiso.net www.xtgxiso.net;
    ...
}

“default_server”参数从0.8.21版开始可用。在之前的版本中,应该使用”default”参数代替。

如何防止处理未定义主机名的请求

如果不允许请求中缺少“Host”头,可以定义如下主机,丢弃这些请求:

server {
    listen       80;
    server_name  "";
    return       444;
}

在这里,我们设置主机名为空字符串以匹配未定义“Host”头的请求,而且返回了一个nginx特有的,非http标准的返回码444,它可以用来关闭连接。

从0.8.48版本开始,这已成为主机名的默认设置,所以可以省略server_name “”。而之前的版本使用机器的hostname作为主机名的默认值。

基于域名和IP混合的虚拟主机

下面让我们来看一个复杂点的配置,在这个配置里,有几个虚拟主机在不同的地址上监听

server {
    listen      192.168.1.1:80;
    server_name xtgxiso.cn www.xtgxiso.cn;
    ...
}

server {
    listen      192.168.1.1:80;
    server_name xtgxiso.net www.xtgxiso.net;
    ...
}

server {
    listen      192.168.1.2:80;
    server_name xtgxiso.com www.xtgxiso.com;
    ...
}

这个配置中,nginx首先测试请求的IP地址和端口是否匹配某个server配置块中的listen指令配置。接着nginx继续测试请求的Host头是否匹配这个server块中的某个server_name的值。如果主机名没有找到,nginx将把这个请求交给默认虚拟主机处理。例如,一个从192.168.1.1:80端口收到的访问www.xtgxiso.com的请求将被监听192.168.1.1:80端口的默认虚拟主机处理,本例中就是第一个服务器,因为这个端口上没有定义名为www.xtgxiso.com的虚拟主机。

默认服务器是监听端口的属性,所以不同的监听端口可以设置不同的默认服务器

server {
    listen      192.168.1.1:80;
    server_name xtgxiso.cn www.xtgxiso.cn;
    ...
}

server {
    listen      192.168.1.1:80 default_server;
    server_name xtgxiso.net www.xtgxiso.net;
    ...
}

server {
    listen      192.168.1.2:80 default_server;
    server_name xtgxiso.com www.xtgxiso.com;
    ...
}

一个简单PHP站点配置

现在我们来看在一个典型的,简单的PHP站点中,nginx怎样为一个请求选择location来处理

server {
    listen      80;
    server_name xtgxiso.cn www.xtgxiso.cn;
    root        /data/www;

    location / {
        index   index.html index.php;
    }

    location ~* \.(gif|jpg|png)$ {
        expires 30d;
    }

    location ~ \.php$ {
        fastcgi_pass  localhost:9000;
        fastcgi_param SCRIPT_FILENAME
                      $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}

首先,nginx使用前缀匹配找出最准确的location,这一步nginx会忽略location在配置文件出现的顺序。上面的配置中,唯一的前缀匹配location是”/”,
而且因为它可以匹配任意的请求,所以被作为最后一个选择。接着,nginx继续按照配置中的顺序依次匹配正则表达式的location,匹配到第一个正则
表达式后停止搜索。匹配到的location将被使用。如果没有匹配到正则表达式的location,则使用刚刚找到的最准确的前缀匹配的
location。

请注意所有location匹配测试只使用请求的URI部分,而不使用参数部分。这是因为写参数的方法很多,比如:

/index.php?user=john&page=1
/index.php?page=1&user=john

除此以外,任何人在请求串中都可以随意添加字符串:

/index.php?page=1&something+else&user=john

现在让我们来看使用上面的配置,请求是怎样被处理的:

  • 请求”/logo.gif”首先匹配上location “/”,然后匹配上正则表达式”\.(gif|jpg|png)$”。因此,它将被后者处理。根据”root /data/www”指令,nginx将请求映射到文件/data/www/logo.gif”,并发送这个文件到客户端。
  • 请求”/index.php”首先也匹配上location “/”,然后匹配上正则表达式”\.(php)$”。 因此,它将被后者处理,进而被发送到监听在localhost:9000的FastCGI服务器。fastcgi_param指令将FastCGI的参数SCRIPT_FILENAME的值设置为”/data/www/index.php”,接着FastCGI服务器执行这个文件。变量$document_root等于root指令设置的值,变量$fastcgi_script_name的值是请求的uri,”/index.php”。
  • 请求”/about.html”仅能匹配上location “/”,因此,它将使用此location进行处理。根据”root /data/www”指令,nginx将请求映射到文件”/data/www/about.html”,并发送这个文件到客户端。
  • 请求”/”的处理更为复杂。它仅能匹配上location “/”,因此,它将使用此location进行处理。然后,index指令使用它的参数和”root /data/www”指令所组成的文件路径来检测对应的文件是否存在。如果文件/data/www/index.html不存在,而/data/www/index.php存在,此指令将执行一次内部重定向到”/index.php”,接着nginx将重新寻找匹配”/index.php”的location,就好像这次请求是从客户端发过来一样。正如我们之前看到的那样,这个重定向的请求最终交给FastCGI服务器来处理。

but DH wants to wait until January at least
gay porn A moment of silence occurred six times in remembrance of the 9

who should be the top 10 couturiers for now
how to lose weight fastHow to Make Old Fashion Potato Casseroles for Side Dishes
free hd porn
发表在 网站架构 | 标签为 | 一条评论

常用签名生成算法

  1. 在请求参数列表中,除去sign,appid,imgupload三个参数外,其他需要使用到的参数皆是要签名的参数
  2. 对参数里的每一个值从a到z的顺序排序。排序完成之后,再把所有数组值以“&”字符连接起来
  3. 在MD5 签名时,需要把appkey连接起来再做md5签名.

 PHP签名代码算法如下:
 <?php
         function verification($arr,$appkey){
            //过虑生成新的数组
	    $para_filter = array();
	    foreach ($arr as $key => $val ) {
		if( in_array($key,array('sign','appid','imgupload')) || $val == "")continue;
		else	$para_filter[$key] = $arr[$key];
	    }
	   //排序数组
	   ksort($para_filter);
	   reset($para_filter);
 
	   //再把所有数组值以“&”字符连接起来
	   $arg  = "";
	   foreach ($para_filter as $key => $val ) {
	       $arg.=$key."=".urlencode($val)."&";
	   }
 
	   //去掉最后一个&字符
	   $arg = substr($arg,0,count($arg)-2);
 
           //如果存在转义字符,那么去掉转义
	   if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
	   $prestr = $arg . $appkey;
 
           return md5($prestr);		
 
	}

简单说明,哈哈!

within the net attire great retailers sell reasonable flip styles
miranda lambert weight loss Leighton Meester Is a Big Fan of Fashion Eyeglasses with Black Frames

red and white the colors of the Mexican flag
christina aguilera weight lossWho Is Your Fashion Icon
free porn sites
发表在 网站开发 | 一条评论

数据库作业

全部sql以access2007为标准.均测试通过

1:查询全部入库产品的编号和数量
select 产品编号,sum(入库数量) as 入库总数量 from 入库数据 group by 产品编号

2:查询全部产品的入库信息
select * from 入库数据

3:查询全部出库产品的出库总价,要求查询结果为两列,为 “产品编号”“出库总价”
select 产品编号,sum(出库单价*出库数量) as 出库总价 from 出库数据 group by 产品编号

4:查询入库的产品编号(即结果要求不重复)
select distinct(产品编号) from 入库数据

5:查询入库单价大宇20 元的产品编号和入库日期
select 产品编号,入库日期  from 入库数据 where 入库单价 > 20

6:查询入库单价在10 元到100 元之间的产品编号
select 产品编号  from 入库数据 where 入库单价 > 10 and 入库单价 < 100

7:查询产品编号为三个字的产品入库信息
select * from 入库数据 where 产品编号 in (select 产品编号 from 产品信息 where len(产品名称)=3)

8:查询龙井茶的入库信息
select * from 入库数据 where 产品编号 in (select 产品编号 from 产品信息 where 产品名称=’龙井茶’)

9:查询缺少产品说明的产品信息
select * from 产品信息 where 产品说明 is null

10:查询入库单价为5 元且入库数量为10 的产品编号
select 产品编号 from 入库数据 where 入库单价=5 and 入库数量=10

11:查询入库数量超过20的产品入库信息,查询结果按照入库单价进行降序排列
select * from 入库数据 where 入库数量 > 20 order by 入库单价 desc

12:查询出库产品类别总数
select count(*) as 类别数量 from (select distinct 产品信息.类别id from 出库数据,产品信息 where 出库数据.产品编号=产品信息.产品编号)

13:查询最大出库单价的产品出库信息
select top 1 * from 出库数据     order by 出库单价 desc
 
14:查询入库数量超过100 的产品编号和入库单价
select 产品编号,入库单价  from 入库数据 where 入库数量 > 100

15:查询个人护理产品的出库信息
select *  from 出库数据 where 产品编号 in (select 产品编号 from 产品信息 where 类别id in (select 类别id from 产品类型 where 产品类别=’个人护理’) )

16:查询出库单价超过10 元的个人护理产品的出库单价和产品说明
select 出库单价,产品说明 from 出库数据,产品信息 where 出库数据.产品编号=产品信息.产品编号 and 出库单价 > 10 and 类别id in (select 类别id from 产品类型 where 产品类别=’个人护理’)

17:嵌套查询家居系列产品的入库信息
select *  from 入库数据 where 产品编号 in (select 产品编号 from 产品信息 where 类别id in (select 类别id from 产品类型 where 产品类别=’家居系列’) )

 
18:查询入库单价比某一 “个人护理”产品入库单价更高的产品入库信息
select *  from 入库数据 where 入库单价 > ( select min(入库单价)from 入库数据 where 产品编号 in (select 产品编号 from 产品信息 where 类别id in (select 类别id from 产品类型 where 产品类别=’个人护理’) )  )
 
19:查询入库单价比任一 “个人护理”产品入库单价更高的产品入库信息
select *  from 入库数据 where 入库单价 > ( select max(入库单价)from 入库数据 where 产品编号 in (select 产品编号 from 产品信息 where 类别id in (select 类别id from 产品类型 where 产品类别=’个人护理’) )  )

20:用集合查询方式查询个人护理产品以及入库单价超过20 元的入库产品信息
select * from 入库数据 where 产品编号 in (select 产品编号 from 产品信息 where 类别id in (select 类别id from 产品类型 where 产品类别=’个人护理’) )
union
select * from 入库数据 where 入库单价 > 20

21:用集合查询方式查询个人护理产品且入库单价超过10 元的入库产品信息
select * from 入库数据 where 产品编号 in (select 产品编号 from 产品信息 where 类别id in (select 类别id from 产品类型 where 产品类别=’个人护理’) )
intersect
select * from 入库数据 where 入库单价 > 10
这个intersect数据库access不支持,所以写成
select * from 入库数据 where  入库单价 > 10 and 产品编号 in (select 产品编号 from 产品信息 where 类别id in (select 类别id from 产品类型 where 产品类别=’个人护理’) )

There was a little armpit tightness when I first got it
gay porn Widely Accepted Study Model Round The Globe

is actually harry fashion forgetting one way
cartoon porn10 Tips to Spotting Counterfeit Abercrombie Fitch
gay porn
发表在 北京大学 | 标签为 | 3 条评论

2012级<计算机网络>期中考试—对答案

They are embarrassed by everything and hold nothing back
cartoon porn a Trend That’s Good For the Planet

registered Democrats and older voters that is
pornoFashion fake goyard bags from www
xvideos
发表在 北京大学 | 标签为 | 2 条评论

GO—-处理文件上传

GO 代码:

package main

import (
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
)

func saygo(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		t, _ := template.ParseFiles("form.html")
		t.Execute(w, nil)

	} else {
		w.Header().Set("Content-Type", "text/html;charset=utf-8")
		r.ParseMultipartForm(1024 * 1024)
		file, handler, err := r.FormFile("uploadfile")
		if err != nil {
			fmt.Println(err)
			return
		}
		defer file.Close()
		fmt.Fprintf(w, "%v", handler.Header)
		f, err := os.OpenFile("./"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil {
			fmt.Println(err)
			return
		}
		defer f.Close()
		io.Copy(f, file)

		fmt.Fprintf(w, "<br/>")
		t, _ := template.ParseFiles("form.html")
		t.Execute(w, nil)
	}
}

func main() {
	http.HandleFunc("/", saygo)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

模板文件:

<html>
<head>
<title>上传文件</title>
</head>
<body>
<form enctype="multipart/form-data" action="" method="post">
    文件:<input type="file" name="uploadfile"><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>

说明:仅是功能说明,不做于生产使用!

now in order to make your own individual
gay porn Allen Walker Cosplay Costume Makes Your Indicate Far more Interesting

Andriod phone or tablet
miranda lambert weight lossSuit by Suzanne Williams caters to the fashion conscience romantic
youjizz
发表在 网站开发 | 标签为 | 2 条评论

GO—-防止多次提交表单

不知道你是否曾经看到过一个论坛或者博客,在一个帖子或者文章后面出现多条重复的记录,这些大多数是因为用户重复递交了留言的表单引起的。由于种种原因,用户经常会重复递交表单。通常这只是鼠标的误操作,如双击了递交按钮,也可能是为了编辑或者再次核对填写过的信息,点击了浏览器的后退按钮,然后又再次点击了递交按钮而不是浏览器的前进按钮。当然,也可能是故意的——比如,在某项在线调查或者博彩活动中重复投票。那我们如何有效的防止用户多次递交相同的表单呢?

解决方案是在表单中添加一个带有唯一值的隐藏字段。在验证表单时,先检查带有该惟一值的表单是否已经递交过了。如果是,拒绝再次递交;如果不是,则处理表单进行逻辑处理。另外,如果是采用了Ajax模式递交表单的话,当表单递交后,通过javascript来禁用表单的递交按钮。

GO代码

package main

import (
	"fmt"
	"html/template"
	"log"
	"math/rand"
	"net/http"
	"time"
)

func saygo(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		time := time.Now().Unix()
		num := rand.Int63n(900000)
		token := time + num
		t, _ := template.ParseFiles("form.html")
		t.Execute(w, token)

	} else {
		w.Header().Set("Content-Type", "text/html;charset=utf-8")
		r.ParseForm()
		token := r.Form.Get("token")
		if token != "" {
			//验证token的合法性 比如:token是否已处理过,可以通过memcached,file,db来检查
		} else {
			fmt.Fprintf(w, "token为空<br/>")
		}
		fmt.Fprintf(w, "<br/>")
		t, _ := template.ParseFiles("form.html")
		t.Execute(w, nil)
	}
}

func main() {
	http.HandleFunc("/", saygo)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

模板

<html>
<head>
<title>重复提交</title>
</head>
<body>
<form action="" method="post">
    唯一值:<input type="text" size="40" value="{{.}}" name="token"><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>

我们看到token已经有输出值,你可以不断的刷新,可以看到这个值在不断的变化。这样就保证了每次显示form表单的时候都是唯一的,用户递交的表单保持了唯一性。
我们的解决方案可以防止非恶意的攻击,并能使恶意用户暂时不知所措,然后,它却不能排除所有的欺骗性的动机,对此类情况还需要更复杂的工作

We suggest the guillotine
quick weight loss How to Get the Grunge Fashion Look

Having experienced the gothic scene and fashion from its early stages
how to lose weight fastShopping List on the Bag of 8 Classic
how to lose weight fast
发表在 网站开发 | 标签为 | 2 条评论

GO—-预防跨站脚本

现在的网站包含大量的动态内容以提高用户体验,比过去要复杂得多。攻击者通常会在有漏洞的程序中插入JavaScript以欺骗用户。一旦得手,他们可以盗取用户帐户信息,修改用户设置,盗取/污染cookie和植入恶意广告等。
对XSS最佳的防护应该结合以下两种方法:一是验证所有输入数据,有效检测攻击(这个我们前面小节已经有过介绍);另一个是对所有输出数据进行适当的处理,以防止任何已成功注入的脚本在浏览器端运行。

那么Go里面是怎么做这个有效防护的呢?Go的html/template里面带有下面几个函数可以帮你转义

  • func HTMLEscape(w io.Writer, b []byte) //把b进行转义之后写到w
  • func HTMLEscapeString(s string) string //转义s之后返回结果字符串
  • func HTMLEscaper(args …interface{}) string //支持多个参数一起转义,返回结果字符串

GO代码

package main

import (
	"fmt"
	"html/template"
	"log"
	"net/http"
)

func saygo(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		t, _ := template.ParseFiles("form.html")
		t.Execute(w, nil)
	} else {
		w.Header().Set("Content-Type", "text/html;charset=utf-8")
		r.ParseForm()

		//username := r.Form.Get("username")
		username := template.HTMLEscapeString(r.Form.Get("username"))
		fmt.Fprintf(w, username)

		fmt.Fprintf(w, "<br/>")
		t, _ := template.ParseFiles("form.html")
		t.Execute(w, nil)
	}
}

func main() {
	http.HandleFunc("/", saygo)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

模板文件:

<html>
<head>
<title>预防跨站脚本</title>
</head>
<body>
<form action="" method="post">
    输入:<input type="text" value="<script>alert('攻击')</script>" name="username"><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>

通过示例,你就可以明白GO是怎么处理转义安全的.

I have some cellulite and no shortage of scars
gay porn Natalie Getz Looks Hot in ICE

monster box collection 1
miranda lambert weight lossEntertainer tops herself again at Grammy Awards Show photo Show
cartoon porn
发表在 网站开发 | 标签为 | 2 条评论

GO—-验证表单的输入

上一节,咱们简单说了如何获取表单的信息,现在简单说一下验证表单的输入.

GO文件

package main

import (
	"fmt"
	"html/template"
	"log"
	"net/http"
	"regexp"
	"strconv"
	"strings"
)

func saygo(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		t, _ := template.ParseFiles("form.html")
		t.Execute(w, nil)
	} else {
		w.Header().Set("Content-Type", "text/html;charset=utf-8")
		r.ParseForm()

		//必填判断
		fmt.Fprintf(w, r.Form["uid"][0]+"<br/>")
		if len(r.Form["uid"][0]) == 0 {
			fmt.Fprintf(w, "必填不能为空"+"<br/>")
		}

		//数字判断
		fmt.Fprintf(w, r.Form.Get("age")+"<br/>")
		getint, err := strconv.Atoi(r.Form.Get("age"))
		if err != nil {
			fmt.Fprintf(w, "不是数字"+"<br/>")
		} else if getint > 100 {
			fmt.Fprintf(w, "数字不能大于100"+"<br/>")
		}

		//电子邮件
		fmt.Fprintf(w, r.Form.Get("email")+"<br/>")
		if m, _ := regexp.MatchString(`^([\w\.\_]{2,10})@(\w{1,}).([a-z]{2,4})$`, r.Form.Get("email")); !m {
			fmt.Fprintf(w, "不是合法的邮件"+"<br/>")
		}

		//下拉菜单
		fmt.Fprintf(w, r.Form.Get("area")+"<br/>")
		slice := []string{"1111", "2222", "333"}
		is_slice := false
		for _, v := range slice {
			if v == r.Form.Get("area") {
				is_slice = true
			}
		}
		if is_slice != true {
			fmt.Fprintf(w, "不是合法的下拉菜单"+"<br/>")
		}

		//单选按钮
		fmt.Fprintf(w, r.Form.Get("gender")+"<br/>")
		slice2 := []int{1, 2}
		is_slice2 := false
		for _, v := range slice2 {
			if strconv.Itoa(v) == r.Form.Get("gender") {
				is_slice2 = true
			}
		}
		if is_slice2 != true {
			fmt.Fprintf(w, "不是合法的单选"+"<br/>")
		}

		//复选框
		slice3 := r.Form["interest"]
		fmt.Fprintf(w, strings.Join(slice3, ",")+"<br/>")
		m := make(map[string]int)
		m["football"] = 1
		m["basketball"] = 1
		m["tennis"] = 1
		is_slice3 := true
		for _, v := range slice3 {
			if int(m[v]) <= 0 {
				is_slice3 = false
			}
		}
		if is_slice3 != true {
			fmt.Fprintf(w, "不是合法的复选"+"<br/>")
		}

		fmt.Fprintf(w, "<br/>")
		t, _ := template.ParseFiles("form.html")
		t.Execute(w, nil)
	}
}

func main() {
	http.HandleFunc("/", saygo)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

模板文件:

<html>
<head>
<title>form示例</title>
</head>
<body>
<form action="" method="post">
    必填:<input type="text" name="uid"><br/>
    数字:<input type="text" name="age"><br/>
	电子邮件:<input type="text" name="email"><br/>
	下拉菜单:<select name="area">
			<option value="0000">0000</option>
			<option value="1111">1111</option>
			<option value="2222">2222</option>
			<option value="3333">3333</option>
			</select><br/>
	单选按钮:<input type="radio" name="gender" value="1">男
			<input type="radio" name="gender" value="2">女<br/>
	复选框:<input type="checkbox" name="interest" value="football">足球
			<input type="checkbox" name="interest" value="basketball">篮球
			<input type="checkbox" name="interest" value="tennis">网球
			<input type="checkbox" name="interest" value="0000">不合法
    <input type="submit" value="提交">
</form>
</body>
</html>

这里只是简单说明,哈哈!

Those people shouldn’t be allowed to do that
gay porn Oscars 2010 Red Carpet Best and Worst Dressed photos

I will not stop wearing the high end tie dye clothing
how to lose weight fastJoico K Pack Reconstructor Conditioner best High End for dry
black porn
发表在 网站开发 | 标签为 | 2 条评论

GO—-处理表单的输入

先来看一个表单递交的例子,我们有如下的表单内容,命名成文件login.html(放入当前新建项目的目录里面)

<html>
<head>
<title></title>
</head>
<body>
<form action="/login/" method="post">
    用户名:<input type="text" name="username">
    密码:<input type="password" name="password">
    <input type="submit" value="登陆">
</form>
</body>
</html>


上面递交表单到服务器的/login,当用户输入信息点击登陆之后,会跳转到服务器的路由login里面,我们首先要判断这个是什么方式传递过来,POST还是GET呢?http包里面有一个很简单的方式就可以获取form信息

package main

import (
	"fmt"
	"html/template"
	"log"
	"net/http"
	"strings"
)

func saygo(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello World!\n")
}

func login(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		t, _ := template.ParseFiles("login.html")
		t.Execute(w, nil)
	} else {
		w.Header().Set("Content-Type", "text/html")
		r.ParseForm()
		username := strings.Join(r.Form["username"], "")
		fmt.Fprintf(w, username+"<br/>")
		password := strings.Join(r.Form["password"], "")
		fmt.Fprintf(w, password+"<br/>")
	}
}

func main() {
	http.HandleFunc("/", saygo)
	http.HandleFunc("/login/", login)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

通过以上简单的代码,我们就可以处理表单的基本信息.

hole of the celebrities vol
weight loss tips Top Places to Shop for Casual Petites

Apply for a visa
how to lose weight fastHigh collars a fashion recycle
hd porn
发表在 网站开发 | 标签为 | 3 条评论

php–循环展开

在北大体系结构中,听到一项循环展开的技术,带着问题用自己熟悉的语言测试一下,果然如老师所说的一样。

代码如下:

<?PHP
error_reporting(0);
ini_set("display_error",0);
ini_set("memory_limit","999M");

function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

function test1(){
	$list = array();
	$time_start = microtime_float();
	for($i=1;$i<=100000;$i++){
		$list[$i]=$i;
	}
	$time_end = microtime_float();
	$time = $time_end - $time_start;
	echo "test1 in $time seconds<br/>";
}

function test2(){
	$list = array();
	$time_start = microtime_float();
	for($i=1;$i<=100000;$i++){
		$list[$i]=$list[$i]+$list[$i-1];
	}
	$time_end = microtime_float();
	$time = $time_end - $time_start;
	echo "test2 in $time seconds<br/>";
}

function test3(){
	$list = array();
	$time_start = microtime_float();
	for($i=1;$i<=100000;$i++){
		$list[$i]=$list[$i]+100000;
	}
	$time_end = microtime_float();
	$time = $time_end - $time_start;
	echo "test3 in $time seconds<br/>";
}
test1();
test2();
test3();




多次运行结果如下:

test1 in 0.015625 seconds
test2 in 0.25 seconds
test3 in 0.140625 seconds


test1 in 0.03125 seconds
test2 in 0.140625 seconds
test3 in 0.140625 seconds


test1 in 0.03125 seconds
test2 in 0.1875 seconds
test3 in 0.140625 seconds


test1 in 0.03125 seconds
test2 in 0.15625 seconds
test3 in 0.140625 seconds

基本可以看出,test1用的时间最短,其次是test3,最长是test2.

这就是知道编译器原理之后,写代码注意的细节问题。详细原理有时间给大家具体讲解。!

If you are going for the movie look
christina aguilera weight loss DIRK PITT novels finally coming to big screen

spandex blend 32 inseam
snooki weight lossTwink Solid G String Underwear Available Now for Free at DealbyEthan
youjizz
发表在 网站开发 | 标签为 | 2 条评论