예제 #1
0
func (c *child) serveRequest(req *request, body io.ReadCloser) {
	r := newResponse(c, req)
	httpReq, err := cgi.RequestFromMap(req.params) // 根据参数构建http请求
	if err != nil {
		// there was an error reading the request
		r.WriteHeader(http.StatusInternalServerError)
		c.conn.writeRecord(typeStderr, req.reqId, []byte(err.Error()))
	} else {
		httpReq.Body = body
		c.handler.ServeHTTP(r, httpReq)
	}
	r.Close()
	c.mu.Lock()
	delete(c.requests, req.reqId)
	c.mu.Unlock()
	c.conn.writeEndRequest(req.reqId, 0, statusRequestComplete)

	// Consume the entire body, so the host isn't still writing to
	// us when we close the socket below in the !keepConn case,
	// otherwise we'd send a RST. (golang.org/issue/4183)
	// TODO(bradfitz): also bound this copy in time. Or send
	// some sort of abort request to the host, so the host
	// can properly cut off the client sending all the data.
	// For now just bound it a little and
	io.CopyN(ioutil.Discard, body, 100<<20)
	body.Close()

	if !req.keepConn {
		c.conn.Close()
	}
}
예제 #2
0
파일: uwsgi.go 프로젝트: spisneha25/uwsgi
func RequestHandler(env *map[string]string, wsgi_req *interface{}) {
	httpReq, err := cgi.RequestFromMap(*env)
	if err == nil {
		httpReq.Body = &BodyReader{wsgi_req}
		w := ResponseWriter{httpReq, wsgi_req, http.Header{}, false}
		http.DefaultServeMux.ServeHTTP(&w, httpReq)
	}
}
예제 #3
0
파일: uwsgi.go 프로젝트: ahua/c
//export uwsgi_go_helper_request
func uwsgi_go_helper_request(env *map[string]string, wsgi_req *C.struct_wsgi_request) {
	httpReq, err := cgi.RequestFromMap(*env)
	if err != nil {
	} else {
		httpReq.Body = &BodyReader{wsgi_req}
		w := ResponseWriter{httpReq, wsgi_req, http.Header{}, false}
		if uwsgi_default_request_handler != nil {
			uwsgi_default_request_handler(&w, httpReq)
		} else if uwsgi_default_handler != nil {
			uwsgi_default_handler.ServeHTTP(&w, httpReq)
		} else {
			http.DefaultServeMux.ServeHTTP(&w, httpReq)
		}
	}
}
예제 #4
0
파일: scgi.go 프로젝트: hoisie/web
func (s *Server) readScgiRequest(fd io.ReadWriteCloser) (*http.Request, error) {
	reader := bufio.NewReader(fd)
	line, err := reader.ReadString(':')
	if err != nil {
		return nil, err
	}
	length, err := strconv.Atoi(line[0 : len(line)-1])
	if err != nil {
		return nil, err
	}
	if length > 16384 {
		return nil, errors.New("Max header size is 16k")
	}
	headerData := make([]byte, length)
	_, err = reader.Read(headerData)
	if err != nil {
		return nil, err
	}
	b, err := reader.ReadByte()
	if err != nil {
		return nil, err
	}
	// discard the trailing comma
	if b != ',' {
		return nil, errors.New("SCGI protocol error: missing comma")
	}
	headerList := bytes.Split(headerData, []byte{0})
	headers := map[string]string{}
	for i := 0; i < len(headerList)-1; i += 2 {
		headers[string(headerList[i])] = string(headerList[i+1])
	}
	httpReq, err := cgi.RequestFromMap(headers)
	if err != nil {
		return nil, err
	}
	if httpReq.ContentLength > 0 {
		httpReq.Body = &scgiBody{
			reader: io.LimitReader(reader, httpReq.ContentLength),
			conn:   fd,
		}
	} else {
		httpReq.Body = &scgiBody{reader: reader, conn: fd}
	}
	return httpReq, nil
}
예제 #5
0
파일: scgi.go 프로젝트: Chownie/web
func readScgiRequest(buf *bytes.Buffer) (*http.Request, error) {
	headers := map[string]string{}

	data := buf.Bytes()
	var clen int

	colon := bytes.IndexByte(data, ':')
	data = data[colon+1:]
	var err error
	//find the CONTENT_LENGTH

	clfields := bytes.SplitN(data, []byte{0}, 3)
	if len(clfields) != 3 {
		return nil, errors.New("Invalid SCGI Request -- no fields")
	}

	clfields = clfields[0:2]
	if string(clfields[0]) != "CONTENT_LENGTH" {
		return nil, errors.New("Invalid SCGI Request -- expecting CONTENT_LENGTH")
	}

	if clen, err = strconv.Atoi(string(clfields[1])); err != nil {
		return nil, errors.New("Invalid SCGI Request -- invalid CONTENT_LENGTH field")
	}

	content := data[len(data)-clen:]

	fields := bytes.Split(data[0:len(data)-clen], []byte{0})

	for i := 0; i < len(fields)-1; i += 2 {
		key := string(fields[i])
		value := string(fields[i+1])
		headers[key] = value
	}

	body := bytes.NewBuffer(content)

	req, _ := cgi.RequestFromMap(headers)
	req.Body = ioutil.NopCloser(body)

	return req, nil
}
예제 #6
0
func (c *child) serveRequest(req *request, body io.ReadCloser) {
	r := newResponse(c, req)
	httpReq, err := cgi.RequestFromMap(req.params)
	if err != nil {
		// there was an error reading the request
		r.WriteHeader(http.StatusInternalServerError)
		c.conn.writeRecord(typeStderr, req.reqId, []byte(err.Error()))
	} else {
		httpReq.Body = body
		c.handler.ServeHTTP(r, httpReq)
	}
	if body != nil {
		body.Close()
	}
	r.Close()
	c.conn.writeEndRequest(req.reqId, 0, statusRequestComplete)
	if !req.keepConn {
		c.conn.Close()
	}
}
예제 #7
0
파일: fcgi.go 프로젝트: ungerik/web.go
func (s *Server) handleFcgiConnection(fd io.ReadWriteCloser) {
	br := bufio.NewReader(fd)
	var req *http.Request
	var fc *fcgiConn
	var body bytes.Buffer
	headers := map[string]string{}

	for {
		var h fcgiHeader
		err := binary.Read(br, binary.BigEndian, &h)
		if err == io.EOF {
			break
		}
		if err != nil {
			s.Logger.Println("FCGI Error", err.Error())
			break
		}
		content := make([]byte, h.ContentLength)
		_, err = io.ReadFull(br, content)
		if err != nil {
			s.Logger.Println("FCGI Error", err.Error())
			break
		}

		//read padding
		if h.PaddingLength > 0 {
			padding := make([]byte, h.PaddingLength)
			_, err = io.ReadFull(br, padding)
			if err != nil {
				s.Logger.Println("FCGI Error", err.Error())
				break
			}
		}

		switch h.Type {
		case fcgiBeginRequest:
			fc = &fcgiConn{h.RequestId, req, fd, make(map[string][]string), false}

		case fcgiParams:
			if h.ContentLength > 0 {
				readFcgiParams(content, headers)
			}
		case fcgiStdin:
			if h.ContentLength > 0 {
				body.Write(content)
			} else if h.ContentLength == 0 {

				req, _ = cgi.RequestFromMap(headers)
				req.Body = ioutil.NopCloser(&body)
				fc.req = req
				s.routeHandler(req, fc)
				//we close the connection after processing
				//TODO: is there a way to keep it open for future requests?
				fc.complete()
				return
			}
		case fcgiData:
			if h.ContentLength > 0 {
				body.Write(content)
			}
		case fcgiAbortRequest:
		}
	}
}