Пример #1
0
func process(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("X-Powered-By", "Cocaine")
	defer r.Body.Close()
	var (
		service = r.Header.Get("X-Cocaine-Service")
		event   = r.Header.Get("X-Cocaine-Event")
	)

	if len(service) == 0 || len(event) == 0 {
		var (
			j = 1
		)
		npos := strings.IndexByte(r.URL.Path[j:], '/')
		if npos < 0 {
			w.WriteHeader(http.StatusBadRequest)
			return
		}
		service = r.URL.Path[j : npos+j]
		j += npos + 1

		npos = strings.IndexByte(r.URL.Path[j:], '/')
		switch npos {
		case -1:
			event = r.URL.Path[j:]
			r.URL.Path = "/"
		case 0:
			// EmptyEvent
			w.WriteHeader(http.StatusBadRequest)
			return
		default:
			event = r.URL.Path[j : npos+j]
			r.URL.Path = r.URL.Path[j+npos:]
		}

		if len(service) == 0 || len(event) == 0 {
			w.WriteHeader(http.StatusBadRequest)
			return
		}
	}

	ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
	defer cancel()
	app, err := cocaine.NewService(ctx, service, nil)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	defer app.Close()

	task, err := packRequest(r)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	channel, err := app.Call(ctx, "enqueue", event)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	if err := channel.Call(ctx, "write", task); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	var (
		body      []byte
		startLine struct {
			Code    int
			Headers [][2]string
		}
	)

	packedHeaders, err := channel.Get(ctx)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprint(w, err)
		return
	}
	if err := packedHeaders.ExtractTuple(&body); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprint(w, err)
		return
	}

	if err := codec.NewDecoderBytes(body, hAsocket).Decode(&startLine); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprint(w, err)
		return
	}
	body = body[:]

	log.Println(startLine)
	for _, header := range startLine.Headers {
		w.Header().Add(header[0], header[1])
	}
	w.WriteHeader(startLine.Code)

BODY:
	for {
		res, err := channel.Get(ctx)
		switch {
		case err != nil:
			break BODY
		case res.Err() != nil:
			break BODY
		case channel.Closed():
			break BODY
		default:
			res.ExtractTuple(&body)
			w.Write(body)
			body = body[:]
		}
	}
}
Пример #2
0
func (st *cocaineCodeStorage) createStorage(ctx context.Context) (service *cocaine.Service, err error) {
	defer apexctx.GetLogger(ctx).Trace("connect to 'storage' service").Stop(&err)
	return cocaine.NewService(ctx, "storage", st.locator)
}