Example #1
0
func Serve(addr string) {
	DEFAULT_SERVER.Addr = cyurl.ParseHost(addr)
	ln, err := net.Listen("tcp", DEFAULT_SERVER.Addr.String())
	if err != nil {
		panic(err)
	}
	defer ln.Close()

	log.Printf("<<<Server Accepting on Port %s>>>\n", DEFAULT_SERVER.Addr.Port())
	for {
		conn, err := ln.Accept()
		if err != nil {
			ErrLog.Println(err)
		}
		go handleConnection(conn)
	}
}
Example #2
0
func handleConnection(conn net.Conn) {
	serve_time := time.Now()

	defer conn.Close()

	ctx := NewContext()
	ctx.ReqAddr = cyurl.ParseHost(conn.RemoteAddr().String())
	ctx.Req = NewRequest()
	ctx.Resp = NewResponse()

	var err error

	reader := bufio.NewReader(conn)

	// Read startline
	line, _, err := reader.ReadLine()
	if len(line) != 0 && err == nil {
		ctx.Req.ParseStartLine(line)
	}

	// Read header
	for {
		line, _, err := reader.ReadLine()
		if len(line) == 0 || err != nil {
			break
		}
		ctx.Req.ParseHeader(line)
	}

	// Read body
	if _, exists := SUPPORT_BODY_HTTP_METHOD[ctx.Req.Method]; exists {
		body := make([]byte, ctx.Req.ContentLength)
		_, err := reader.Read(body)
		if err == nil {
			ctx.Req.Body = string(body)
		} else {
			ctx.Req.Body = err.Error()
		}
	}

	if ctx.Req.Headers.Get(HTTP_HEAD_X_FORWARDED_FOR) != "" {
		ctx.ReqAddr = cyurl.ParseHost(ctx.Req.Headers.Get(HTTP_HEAD_X_FORWARDED_FOR))
	}
	ctx.Resp.Proto = ctx.Req.Proto

	// black url list
	if _, exists := BLACK_URL[ctx.Req.Url.Path]; exists {
		ctx.Resp.StatusCode = StatusOK
		ctx.Resp.Body = "F**k You!"
	} else if DEFAULT_SERVER.Routes.routes[ctx.Req.Method][ctx.Req.Url.Path] != nil {
		DEFAULT_SERVER.Routes.routes[ctx.Req.Method][ctx.Req.Url.Path].ServeHTTP(ctx)
	} else {
		if _, exists := HTTP_METHOD[ctx.Req.Method]; !exists {
			ctx.Resp.StatusCode = StatusMethodNotAllowed
		} else {
			ctx.Resp.StatusCode = StatusNotFound
		}
	}

	if ctx.Resp.StatusCode == StatusNotFound {
		ctx.Resp.Body = DEFAULT_ERROR_PAGE
	}
	ctx.Resp.Headers.Add(HTTP_HEAD_DATE, serve_time.Format(time.RFC1123))
	ctx.Resp.Headers.Add(HTTP_HEAD_CONTENTLENGTH, fmt.Sprintf("%d", len(ctx.Resp.Body)))

	writer := bufio.NewWriter(conn)
	_, err = writer.WriteString(fmt.Sprintf("%s %d %s\r\n", ctx.Resp.Proto, ctx.Resp.StatusCode, StatusText(ctx.Resp.StatusCode)))
	if err != nil {
		ErrLog.Println(err)
	} else {
		writer.Flush()
	}
	for k, v := range ctx.Resp.Headers {
		for _, vv := range v {
			_, err = writer.WriteString(fmt.Sprintf("%s: %s\r\n", k, vv))
			if err != nil {
				ErrLog.Println(err)
			} else {
				writer.Flush()
			}
		}
	}
	_, err = writer.WriteString(CRLF)
	if err != nil {
		ErrLog.Println(err)
	} else {
		writer.Flush()
	}
	_, err = writer.WriteString(ctx.Resp.Body)
	if err != nil {
		ErrLog.Println(err)
	} else {
		writer.Flush()
	}
	//	ctx.elapse = time.Now().Sub(serve_time)
	log.Println(fmt.Sprintf(LOG_CONTEXT, ctx.ReqAddr.Address(), "-", serve_time.Format(LOG_TIME_FORMAT), ctx.Req.Method, ctx.Req.Url.RawPath, ctx.Req.Proto, ctx.Resp.StatusCode, ctx.Req.ContentLength, "-", ctx.Req.UserAgent, 0))
}