func (this *Server) serviceRequest(request Request) { defer func() { err := recover() if err != nil { buf := make([]byte, 1<<16) n := runtime.Stack(buf, false) s := string(buf[0:n]) logging.Severep("", logging.Pair{"panic", err}, logging.Pair{"stack", s}) os.Stderr.WriteString(s) os.Stderr.Sync() } }() request.Servicing() namespace := request.Namespace() if namespace == "" { namespace = this.namespace } prepared, err := this.getPrepared(request, namespace) if err != nil { request.Fail(err) } if (this.readonly || value.ToBool(request.Readonly())) && (prepared != nil && !prepared.Readonly()) { request.Fail(errors.NewServiceErrorReadonly("The server or request is read-only" + " and cannot accept this write statement.")) } var operator execution.Operator if request.State() != FATAL { var err error operator, err = execution.Build(prepared) if err != nil { request.Fail(errors.NewError(err, "")) } } if request.State() == FATAL { // Fail the request - Write out response - and return request.Failed(this) return } // Apply server execution timeout if this.timeout > 0 { timer := time.AfterFunc(this.timeout, func() { request.Expire() }) defer timer.Stop() } go request.Execute(this, prepared.Signature(), operator.StopChannel()) context := execution.NewContext(this.datastore, this.systemstore, namespace, this.readonly, request.NamedArgs(), request.PositionalArgs(), request.Credentials(), request.ScanConsistency(), request.ScanVector(), request.Output()) operator.RunOnce(context, nil) }
func newHttpRequest(resp http.ResponseWriter, req *http.Request, bp BufferPool) *httpRequest { var httpArgs httpRequestArgs var err errors.Error e := req.ParseForm() if e != nil { err = errors.NewServiceErrorBadValue(e, "request form") } if err != nil && req.Method != "GET" && req.Method != "POST" { err = errors.NewServiceErrorHTTPMethod(req.Method) } if err == nil { httpArgs, err = getRequestParams(req) } var statement string if err == nil { statement, err = httpArgs.getStatement() } var prepared *plan.Prepared if err == nil { prepared, err = getPrepared(httpArgs) } if err == nil && statement == "" && prepared == nil { err = errors.NewServiceErrorMissingValue("statement or prepared") } var namedArgs map[string]value.Value if err == nil { namedArgs, err = httpArgs.getNamedArgs() } var positionalArgs value.Values if err == nil { positionalArgs, err = httpArgs.getPositionalArgs() } var namespace string if err == nil { namespace, err = httpArgs.getString(NAMESPACE, "") } var timeout time.Duration if err == nil { timeout, err = httpArgs.getDuration(TIMEOUT) } var readonly value.Tristate if err == nil { readonly, err = httpArgs.getTristate(READONLY) } if err == nil && readonly == value.FALSE && req.Method == "GET" { err = errors.NewServiceErrorReadonly( fmt.Sprintf("%s=false cannot be used with HTTP GET method.", READONLY)) } var metrics value.Tristate if err == nil { metrics, err = httpArgs.getTristate(METRICS) } var format Format if err == nil { format, err = getFormat(httpArgs) } if err == nil && format != JSON { err = errors.NewServiceErrorNotImplemented("format", format.String()) } var signature value.Tristate if err == nil { signature, err = httpArgs.getTristate(SIGNATURE) } var compression Compression if err == nil { compression, err = getCompression(httpArgs) } if err == nil && compression != NONE { err = errors.NewServiceErrorNotImplemented("compression", compression.String()) } var encoding Encoding if err == nil { encoding, err = getEncoding(httpArgs) } if err == nil && encoding != UTF8 { err = errors.NewServiceErrorNotImplemented("encoding", encoding.String()) } var pretty value.Tristate if err == nil { pretty, err = httpArgs.getTristate(PRETTY) } if err == nil && pretty == value.FALSE { err = errors.NewServiceErrorNotImplemented("pretty", "false") } var consistency *scanConfigImpl if err == nil { consistency, err = getScanConfiguration(httpArgs) } var creds datastore.Credentials if err == nil { creds, err = getCredentials(httpArgs, req.URL.User, req.Header["Authorization"]) } client_id := "" if err == nil { client_id, err = httpArgs.getString(CLIENT_CONTEXT_ID, "") } base := server.NewBaseRequest(statement, prepared, namedArgs, positionalArgs, namespace, readonly, metrics, signature, consistency, client_id, creds) rv := &httpRequest{ BaseRequest: *base, resp: resp, req: req, } rv.SetTimeout(rv, timeout) rv.writer = NewBufferedWriter(rv, bp) // Limit body size in case of denial-of-service attack req.Body = http.MaxBytesReader(resp, req.Body, MAX_REQUEST_BYTES) // Abort if client closes connection closeNotify := resp.(http.CloseNotifier).CloseNotify() go func() { <-closeNotify rv.Stop(server.TIMEOUT) }() if err != nil { rv.Fail(err) } return rv }