示例#1
0
static RETSIGTYPE
sighandler(int sig)
{
  mrb_state *mrb = global_mrb;
  struct RClass *mrb_mSignal = mrb_module_get(mrb, "Signal");
  mrb_value trap_list = mrb_iv_get(mrb, mrb_obj_value(mrb_mSignal), mrb_intern_lit(mrb, "trap_list"));
  mrb_value command = mrb_ary_ref(mrb, trap_list, sig);

  if (mrb_type(command) == MRB_TT_PROC) {
    mrb_funcall(mrb, command, "call", 1, mrb_fixnum_value(sig));
  } else {
    mrb_signal(mrb, sig, sighandler);

    /* default actions */
    switch (sig) {
      case SIGINT:
        mrb_exc_raise(mrb, mrb_funcall(
          mrb,
          mrb_obj_value(mrb_class_get(mrb, "Interrupt")),
          "new",
          1,
          mrb_str_new_cstr(mrb, "")
        ));
        break;
#ifdef SIGHUP
      case SIGHUP:
#endif
#ifdef SIGQUIT
      case SIGQUIT:
#endif
#ifdef SIGTERM
      case SIGTERM:
#endif
#ifdef SIGALRM
      case SIGALRM:
#endif
#ifdef SIGUSR1
      case SIGUSR1:
#endif
#ifdef SIGUSR2
      case SIGUSR2:
#endif
        mrb_exc_raise(mrb, mrb_funcall(
          mrb,
          mrb_obj_value(mrb_class_get(mrb, "SignalException")),
          "new",
          1,
          mrb_fixnum_value(sig)
        ));
        break;
      default:
        break;
    }
  }
}
示例#2
0
文件: kernel.c 项目: kishima/mruby
/*
 *  call-seq:
 *     raise
 *     raise(string)
 *     raise(exception [, string])
 *
 *  With no arguments, raises a <code>RuntimeError</code>
 *  With a single +String+ argument, raises a
 *  +RuntimeError+ with the string as a message. Otherwise,
 *  the first parameter should be the name of an +Exception+
 *  class (or an object that returns an +Exception+ object when sent
 *  an +exception+ message). The optional second parameter sets the
 *  message associated with the exception, and the third parameter is an
 *  array of callback information. Exceptions are caught by the
 *  +rescue+ clause of <code>begin...end</code> blocks.
 *
 *     raise "Failed to create socket"
 *     raise ArgumentError, "No parameters", caller
 */
MRB_API mrb_value
mrb_f_raise(mrb_state *mrb, mrb_value self)
{
  mrb_value a[2], exc;
  mrb_int argc;


  argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]);
  switch (argc) {
  case 0:
    mrb_raise(mrb, E_RUNTIME_ERROR, "");
    break;
  case 1:
    if (mrb_string_p(a[0])) {
      a[1] = a[0];
      argc = 2;
      a[0] = mrb_obj_value(E_RUNTIME_ERROR);
    }
    /* fall through */
  default:
    exc = mrb_make_exception(mrb, argc, a);
    mrb_exc_raise(mrb, exc);
    break;
  }
  return mrb_nil_value();            /* not reached */
}
示例#3
0
static mrb_value MR_JsonParse (mrb_state* mrb, mrb_value self) {
  char* errmsg;
  char* s;
  /* int res; */
  size_t l;
  TRI_json_t* json;

  /* res = */ mrb_get_args(mrb, "s", &s, &l);

  if (s == NULL) {
    return mrb_nil_value();
  }

  json = TRI_Json2String(TRI_UNKNOWN_MEM_ZONE, s, &errmsg);

  if (json == NULL) {
    mrb_value exc;

    exc = MR_ArangoError(mrb, TRI_ERROR_HTTP_CORRUPTED_JSON, errmsg);
    TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, errmsg);

    mrb_exc_raise(mrb, exc);
    assert(false);
  }

  return MR_ObjectJson(mrb, json);
}
示例#4
0
文件: error.c 项目: deweerdt/h2o
MRB_API mrb_noreturn void
mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg)
{
  mrb_value mesg;
  mesg = mrb_str_new_cstr(mrb, msg);
  mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg));
}
示例#5
0
文件: error.c 项目: arturdent/mruby
void
mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg)
{
  mrb_value mesg;
  mesg = mrb_str_new2(mrb, msg);
  mrb_exc_raise(mrb, mrb_exc_new3(mrb, c, mesg));
}
示例#6
0
static mrb_value send_chunked_method(mrb_state *mrb, mrb_value self)
{
    h2o_mruby_generator_t *generator = h2o_mruby_current_generator;
    const char *s;
    mrb_int len;

    /* parse args */
    mrb_get_args(mrb, "s", &s, &len);

    { /* precond check */
        mrb_value exc = check_precond(mrb, generator);
        if (!mrb_nil_p(exc))
            mrb_exc_raise(mrb, exc);
    }

    /* append to send buffer, and send out immediately if necessary */
    if (len != 0) {
        h2o_mruby_chunked_t *chunked = generator->chunked;
        if (chunked->bytes_left != SIZE_MAX) {
            if (len > chunked->bytes_left)
                len = chunked->bytes_left;
            chunked->bytes_left -= len;
        }
        if (len != 0) {
            h2o_buffer_reserve(&chunked->callback.receiving, len);
            memcpy(chunked->callback.receiving->bytes + chunked->callback.receiving->size, s, len);
            chunked->callback.receiving->size += len;
            if (chunked->sending.bytes_inflight == 0)
                do_send(generator, &chunked->callback.receiving, 0);
        }
    }

    return mrb_nil_value();
}
示例#7
0
/*
 *  call-seq:
 *     raise
 *     raise(string)
 *     raise(exception [, string])
 *
 *  With no arguments, raises a <code>RuntimeError</code>
 *  With a single +String+ argument, raises a
 *  +RuntimeError+ with the string as a message. Otherwise,
 *  the first parameter should be the name of an +Exception+
 *  class (or an object that returns an +Exception+ object when sent
 *  an +exception+ message). The optional second parameter sets the
 *  message associated with the exception, and the third parameter is an
 *  array of callback information. Exceptions are caught by the
 *  +rescue+ clause of <code>begin...end</code> blocks.
 *
 *     raise "Failed to create socket"
 *     raise ArgumentError, "No parameters", caller
 */
mrb_value
mrb_f_raise(mrb_state *mrb, mrb_value self)
{
  mrb_value a[2], exc;
  int argc;


  argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]);
  switch (argc) {
  case 0:
    mrb_raise(mrb, E_RUNTIME_ERROR, "");
    break;
  case 1:
    a[1] = mrb_check_string_type(mrb, a[0]);
    if (!mrb_nil_p(a[1])) {
      argc = 2;
      a[0] = mrb_obj_value(E_RUNTIME_ERROR);
    }
    /* fall through */
  default:
    exc = mrb_make_exception(mrb, argc, a);
    mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern2(mrb, "lastpc", 6), mrb_cptr_value(mrb, mrb->c->ci->pc));
    mrb_exc_raise(mrb, exc);
    break;
  }
  return mrb_nil_value();            /* not reached */
}
示例#8
0
static struct RProc*
create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, char *file, mrb_int line)
{
  mrbc_context *cxt;
  struct mrb_parser_state *p;
  struct RProc *proc;
  struct REnv *e;

  if (!mrb_nil_p(binding)) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil.");
  }

  cxt = mrbc_context_new(mrb);
  cxt->lineno = line;
  if (file) {
    mrbc_filename(mrb, cxt, file);
  }
  cxt->capture_errors = TRUE;

  p = mrb_parse_nstring(mrb, s, len, cxt);

  /* only occur when memory ran out */
  if (!p) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state.");
  }

  if (0 < p->nerr) {
    /* parse error */
    char buf[256];
    int n;
    n = snprintf(buf, sizeof(buf), "line %d: %s\n", p->error_buffer[0].lineno, p->error_buffer[0].message);
    mrb_parser_free(p);
    mrbc_context_free(mrb, cxt);
    mrb_exc_raise(mrb, mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
  }

  proc = mrb_generate_code(mrb, p);
  if (proc == NULL) {
    /* codegen error */
    mrb_parser_free(p);
    mrbc_context_free(mrb, cxt);
    mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error");
  }
  if (mrb->c->ci[-1].proc->target_class) {
    proc->target_class = mrb->c->ci[-1].proc->target_class;
  }
  e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci[-1].proc->env);
  e->mid = mrb->c->ci[-1].mid;
  e->cioff = mrb->c->ci - mrb->c->cibase - 1;
  e->stack = mrb->c->ci->stackent;
  mrb->c->ci->env = e;
  proc->env = e;
  patch_irep(mrb, proc->body.irep, 0);

  mrb_parser_free(p);
  mrbc_context_free(mrb, cxt);

  return proc;
}
示例#9
0
文件: error.c 项目: Zyxwvu/mruby
void
mrb_raise_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list args)
{
  char buf[256];

  vsnprintf(buf, 256, fmt, args);
  mrb_exc_raise(mrb, mrb_exc_new(mrb, c, buf, strlen(buf)));
}
示例#10
0
void mrb_state::mrb_raisef(RClass *c, const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    auto mesg = mrb_vformat(this, fmt, args);
    va_end(args);
    mrb_exc_raise(this, mrb_exc_new_str(c, mesg));
}
示例#11
0
文件: error.c 项目: Zyxwvu/mruby
void
mrb_raise(mrb_state *mrb, struct RClass *c, const char *fmt, ...)
{
  va_list args;
  char buf[256];

  va_start(args, fmt);
  vsnprintf(buf, 256, fmt, args);
  va_end(args);
  mrb_exc_raise(mrb, mrb_exc_new(mrb, c, buf, strlen(buf)));
}
示例#12
0
文件: error.c 项目: deweerdt/h2o
MRB_API mrb_noreturn void
mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...)
{
  va_list args;
  mrb_value mesg;

  va_start(args, fmt);
  mesg = mrb_vformat(mrb, fmt, args);
  va_end(args);
  mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg));
}
示例#13
0
文件: error.c 项目: deweerdt/h2o
MRB_API mrb_noreturn void
mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, ...)
{
  mrb_value exc;
  va_list ap;

  va_start(ap, fmt);
  exc = mrb_funcall(mrb, mrb_obj_value(E_NOMETHOD_ERROR), "new", 3,
                    mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id), args);
  va_end(ap);
  mrb_exc_raise(mrb, exc);
}
示例#14
0
static mrb_value
eval_context_compile(mrb_state *mrb, mrb_value self)
{
  char *script;
  mrb_int script_length;
  mrbc_context* compile_ctx;
  struct mrb_parser_state *parser;
  struct RProc *proc;

  mrb_get_args(mrb, "s", &script, &script_length);

  compile_ctx = mrbc_context_new(mrb);
  if (!compile_ctx) {
    mrb_raise(mrb, E_RUNTIME_ERROR,
              "[mruby][eval][compile] failed to allocate context");
  }
  compile_ctx->capture_errors = TRUE;

  parser = mrb_parse_nstring(mrb, script, script_length, compile_ctx);
  if (!parser) {
    mrbc_context_free(mrb, compile_ctx);
    mrb_raise(mrb, E_RUNTIME_ERROR,
              "[mruby][eval][compile] failed to allocate parser");
  }
  if (parser->nerr > 0) {
    struct mrb_parser_message *error = &(parser->error_buffer[0]);
    mrb_value new_args[1];
    mrb_value exception;

    new_args[0] = mrb_format(mrb,
                             "line %S:%S: %S",
                             mrb_fixnum_value(error->lineno),
                             mrb_fixnum_value(error->column),
                             mrb_str_new_cstr(mrb, error->message));
    exception = mrb_obj_new(mrb, E_SYNTAX_ERROR, 1, new_args);
    mrb_parser_free(parser);
    mrbc_context_free(mrb, compile_ctx);

    mrb_exc_raise(mrb, exception);
  }

  proc = mrb_generate_code(mrb, parser);
  {
    mrb_code *iseq = proc->body.irep->iseq;
    while (GET_OPCODE(*iseq) != OP_STOP) {
      iseq++;
    }
    *iseq = MKOP_AB(OP_RETURN, 1, OP_R_NORMAL);
  }
  mrb_parser_free(parser);
  mrbc_context_free(mrb, compile_ctx);
  return mrb_obj_value(proc);
}
示例#15
0
void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
{
    mrb_value exc;
    mrb_value argv[2];
    va_list args;

    va_start(args, fmt);
    argv[0] = mrb_vformat(mrb, fmt, args)->wrap();
    va_end(args);
    argv[1] = mrb_symbol_value(id);
    exc = E_NAME_ERROR->new_instance(2, argv);
    mrb_exc_raise(mrb, exc);
}
示例#16
0
文件: gc.c 项目: TressaOrg/mruby
MRB_API void*
mrb_realloc(mrb_state *mrb, void *p, size_t len)
{
  void *p2;

  p2 = mrb_realloc_simple(mrb, p, len);
  if (!p2 && len) {
    if (mrb->gc.out_of_memory) {
      mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
      /* mrb_panic(mrb); */
    }
    else {
      mrb->gc.out_of_memory = TRUE;
      mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
    }
  }
  else {
    mrb->gc.out_of_memory = FALSE;
  }

  return p2;
}
示例#17
0
static void
mrb_load_fail(mrb_state *mrb, mrb_value path, const char *err)
{
  mrb_value mesg, exc;

  mesg = mrb_str_new_cstr(mrb, err);
  mrb_str_cat_lit(mrb, mesg, " -- ");
  mrb_str_cat_str(mrb, mesg, path);
  exc = mrb_funcall(mrb, mrb_obj_value(E_LOAD_ERROR), "new", 1, mesg);
  mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "path"), path);

  mrb_exc_raise(mrb, exc);
}
示例#18
0
文件: error.c 项目: deweerdt/h2o
MRB_API mrb_noreturn void
mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
{
  mrb_value exc;
  mrb_value argv[2];
  va_list args;

  va_start(args, fmt);
  argv[0] = mrb_vformat(mrb, fmt, args);
  va_end(args);

  argv[1] = mrb_symbol_value(id);
  exc = mrb_obj_new(mrb, E_NAME_ERROR, 2, argv);
  mrb_exc_raise(mrb, exc);
}
示例#19
0
文件: error.c 项目: Blorgus/mruby
void
mrb_raise(mrb_state *mrb, struct RClass *c, const char *fmt, ...)
{
  va_list args;
  char buf[256];
  int n;

  va_start(args, fmt);
  n = vsnprintf(buf, 256, fmt, args);
  va_end(args);
  if (n < 0) {
    n = 0;
  }
  mrb_exc_raise(mrb, mrb_exc_new(mrb, c, buf, n));
}
示例#20
0
文件: eval.c 项目: devnexen/h2o
static mrb_value
exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc)
{
  /* no argument passed from eval() */
  mrb->c->ci->argc = 0;
  if (mrb->c->ci->acc < 0) {
    mrb_value ret = mrb_top_run(mrb, proc, self, 0);
    if (mrb->exc) {
      mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
    }
    return ret;
  }
  /* clear block */
  mrb->c->stack[1] = mrb_nil_value();
  return mrb_exec_irep(mrb, self, proc);
}
示例#21
0
static mrb_value
mrb_kernel_load(mrb_state *mrb, mrb_value self)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;
  char *path;

  mrb_get_args(mrb, "z", &path);

  grn_mrb_load(ctx, path);
  if (mrb->exc) {
    mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
  }

  grn_mrb_ctx_check(mrb);

  return mrb_true_value();
}
示例#22
0
文件: error.c 项目: Zyxwvu/mruby
void
mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
{
  mrb_value exc, argv[2];
  va_list args;
  char buf[256];

  va_start(args, fmt);
  //argv[0] = mrb_vsprintf(fmt, args);
  vsnprintf(buf, 256, fmt, args);
  argv[0] = mrb_str_new(mrb, buf, strlen(buf));
  va_end(args);

  argv[1] = mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id));
  exc = mrb_class_new_instance(mrb, 2, argv, E_NAME_ERROR);
  mrb_exc_raise(mrb, exc);
}
示例#23
0
文件: kernel.c 项目: beeplove/mruby
/*
 *  call-seq:
 *     raise
 *     raise(string)
 *     raise(exception [, string [, array]])
 *     fail
 *     fail(string)
 *     fail(exception [, string [, array]])
 *
 *  With no arguments, raises the exception in <code>$!</code> or raises
 *  a <code>RuntimeError</code> if <code>$!</code> is +nil+.
 *  With a single +String+ argument, raises a
 *  +RuntimeError+ with the string as a message. Otherwise,
 *  the first parameter should be the name of an +Exception+
 *  class (or an object that returns an +Exception+ object when sent
 *  an +exception+ message). The optional second parameter sets the
 *  message associated with the exception, and the third parameter is an
 *  array of callback information. Exceptions are caught by the
 *  +rescue+ clause of <code>begin...end</code> blocks.
 *
 *     raise "Failed to create socket"
 *     raise ArgumentError, "No parameters", caller
 */
mrb_value
mrb_f_raise(mrb_state *mrb, mrb_value self)
{
  mrb_value err;
  mrb_value *argv;
  int argc;

  mrb_get_args(mrb, "*", &argv, &argc);
  if (argc == 0) {
    err = get_errinfo(mrb);
    if (!mrb_nil_p(err)) {
        argc = 1;
        argv[0] = err;
      }
  }
  mrb_exc_raise(mrb, mrb_make_exception(mrb, argc, argv));
  return mrb_nil_value();            /* not reached */
}
示例#24
0
文件: gc.c 项目: Everysick/mruby
static void
gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p)
{
#ifdef MRB_GC_FIXED_ARENA
  if (gc->arena_idx >= MRB_GC_ARENA_SIZE) {
    /* arena overflow error */
    gc->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */
    mrb_exc_raise(mrb, mrb_obj_value(mrb->arena_err));
  }
#else
  if (gc->arena_idx >= gc->arena_capa) {
    /* extend arena */
    gc->arena_capa = (int)(gc->arena_capa * 1.5);
    gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa);
  }
#endif
  gc->arena[gc->arena_idx++] = p;
}
示例#25
0
static mrb_value
mrb_wslay_event_send(mrb_state *mrb, mrb_value self)
{
  mrb_wslay_user_data *data = (mrb_wslay_user_data *) DATA_PTR(self);
  mrb_assert(data);

  int err = wslay_event_send(data->ctx);
  if (err == WSLAY_ERR_NOMEM) {
    mrb_sys_fail(mrb, "wslay_event_send");
  }
  else if (err == WSLAY_ERR_CALLBACK_FAILURE) {
    mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
  }
  else if (err != 0) {
    return MRB_WSLAY_ERROR(mrb_fixnum_value(err));
  }

  return self;
}
示例#26
0
文件: error.c 项目: Blorgus/mruby
void
mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
{
  mrb_value exc, argv[2];
  va_list args;
  char buf[256];
  int n;

  va_start(args, fmt);
  n = vsnprintf(buf, 256, fmt, args);
  va_end(args);
  if (n < 0) {
    n = 0;
  }
  argv[0] = mrb_str_new(mrb, buf, n);
  argv[1] = mrb_symbol_value(id); /* ignore now */
  exc = mrb_class_new_instance(mrb, 1, argv, E_NAME_ERROR);
  mrb_exc_raise(mrb, exc);
}
示例#27
0
文件: eval.c 项目: pbosetti/mruby
static mrb_value
f_eval(mrb_state *mrb, mrb_value self)
{
  char *s;
  mrb_int len;
  mrb_value binding = mrb_nil_value();
  char *file = NULL;
  mrb_int line = 1;
  mrb_value ret;
  struct RProc *proc;

  mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line);

  proc = create_proc_from_string(mrb, s, len, binding, file, line);
  ret = mrb_top_run(mrb, proc, mrb->c->stack[0], 0);
  if (mrb->exc) {
    mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
  }

  return ret;
}
示例#28
0
文件: kernel.c 项目: kimhmadsen/mruby
/*
 *  call-seq:
 *     raise
 *     raise(string)
 *     raise(exception [, string])
 *
 *  With no arguments, raises a <code>RuntimeError</code>
 *  With a single +String+ argument, raises a
 *  +RuntimeError+ with the string as a message. Otherwise,
 *  the first parameter should be the name of an +Exception+
 *  class (or an object that returns an +Exception+ object when sent
 *  an +exception+ message). The optional second parameter sets the
 *  message associated with the exception, and the third parameter is an
 *  array of callback information. Exceptions are caught by the
 *  +rescue+ clause of <code>begin...end</code> blocks.
 *
 *     raise "Failed to create socket"
 *     raise ArgumentError, "No parameters", caller
 */
mrb_value
mrb_f_raise(mrb_state *mrb, mrb_value self)
{
  mrb_value a[2];
  int argc;

  argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]);
  switch (argc) {
  case 0:
    mrb_raise(mrb, E_RUNTIME_ERROR, "");
    break;
  case 1:
    a[1] = mrb_check_string_type(mrb, a[0]);
    if (!mrb_nil_p(a[1])) {
      argc = 2;
      a[0] = mrb_obj_value(E_RUNTIME_ERROR);
    }
    /* fall through */
  default:
    mrb_exc_raise(mrb, mrb_make_exception(mrb, argc, a));
  }
  return mrb_nil_value();            /* not reached */
}
示例#29
0
static mrb_value http_request_method(mrb_state *mrb, mrb_value self)
{
    h2o_mruby_generator_t *generator;
    struct st_h2o_mruby_http_request_context_t *ctx;
    const char *arg_url;
    mrb_int arg_url_len;
    mrb_value arg_hash;
    h2o_iovec_t method;
    h2o_url_t url;

    /* parse args */
    arg_hash = mrb_nil_value();
    mrb_get_args(mrb, "s|H", &arg_url, &arg_url_len, &arg_hash);

    /* precond check */
    if ((generator = h2o_mruby_current_generator) == NULL || generator->req == NULL)
        mrb_exc_raise(mrb, create_downstream_closed_exception(mrb));

    /* allocate context and initialize */
    ctx = h2o_mem_alloc_shared(&generator->req->pool, sizeof(*ctx), on_dispose);
    memset(ctx, 0, sizeof(*ctx));
    ctx->generator = generator;
    ctx->receiver = mrb_nil_value();
    h2o_buffer_init(&ctx->req.buf, &h2o_socket_buffer_prototype);
    h2o_buffer_init(&ctx->resp.after_closed, &h2o_socket_buffer_prototype);
    ctx->refs.request = mrb_nil_value();
    ctx->refs.input_stream = mrb_nil_value();

    /* uri */
    if (h2o_url_parse(arg_url, arg_url_len, &url) != 0)
        mrb_raise(mrb, E_ARGUMENT_ERROR, "invaild URL");

    /* method */
    method = h2o_iovec_init(H2O_STRLIT("GET"));
    if (mrb_hash_p(arg_hash)) {
        mrb_value t = mrb_hash_get(mrb, arg_hash, mrb_symbol_value(generator->ctx->symbols.sym_method));
        if (!mrb_nil_p(t)) {
            t = mrb_str_to_str(mrb, t);
            method = h2o_iovec_init(RSTRING_PTR(t), RSTRING_LEN(t));
        }
    }

    /* start building the request */
    h2o_buffer_reserve(&ctx->req.buf, method.len + 1);
    append_to_buffer(&ctx->req.buf, method.base, method.len);
    append_to_buffer(&ctx->req.buf, H2O_STRLIT(" "));
    h2o_buffer_reserve(&ctx->req.buf,
                       url.path.len + url.authority.len + sizeof(" HTTP/1.1\r\nConnection: close\r\nHost: \r\n") - 1);
    append_to_buffer(&ctx->req.buf, url.path.base, url.path.len);
    append_to_buffer(&ctx->req.buf, H2O_STRLIT(" HTTP/1.1\r\nConnection: close\r\nHost: "));
    append_to_buffer(&ctx->req.buf, url.authority.base, url.authority.len);
    append_to_buffer(&ctx->req.buf, H2O_STRLIT("\r\n"));

    /* headers */
    if (mrb_hash_p(arg_hash)) {
        mrb_value headers = mrb_hash_get(mrb, arg_hash, mrb_symbol_value(generator->ctx->symbols.sym_headers));
        if (!mrb_nil_p(headers)) {
            if (h2o_mruby_iterate_headers(generator->ctx, headers, flatten_request_header, ctx) != 0) {
                mrb_value exc = mrb_obj_value(mrb->exc);
                mrb->exc = NULL;
                mrb_exc_raise(mrb, exc);
            }
        }
    }
    /* body */
    if (mrb_hash_p(arg_hash)) {
        mrb_value body = mrb_hash_get(mrb, arg_hash, mrb_symbol_value(generator->ctx->symbols.sym_body));
        if (!mrb_nil_p(body)) {
            if (mrb_obj_eq(mrb, body, generator->rack_input)) {
                /* fast path */
                mrb_int pos;
                mrb_input_stream_get_data(mrb, body, NULL, NULL, &pos, NULL, NULL);
                ctx->req.body = generator->req->entity;
                ctx->req.body.base += pos;
                ctx->req.body.len -= pos;
            } else {
                if (!mrb_string_p(body)) {
                    body = mrb_funcall(mrb, body, "read", 0);
                    if (!mrb_string_p(body))
                        mrb_raise(mrb, E_ARGUMENT_ERROR, "body.read did not return string");
                }
                ctx->req.body = h2o_strdup(&ctx->generator->req->pool, RSTRING_PTR(body), RSTRING_LEN(body));
            }
            if (!ctx->req.has_transfer_encoding) {
                char buf[64];
                size_t l = (size_t)sprintf(buf, "content-length: %zu\r\n", ctx->req.body.len);
                h2o_buffer_reserve(&ctx->req.buf, l);
                append_to_buffer(&ctx->req.buf, buf, l);
            }
        }
    }

    h2o_buffer_reserve(&ctx->req.buf, 2);
    append_to_buffer(&ctx->req.buf, H2O_STRLIT("\r\n"));

    /* build request and connect */
    h2o_http1client_connect(&ctx->client, ctx, &generator->req->conn->ctx->proxy.client_ctx, url.host, h2o_url_get_port(&url),
                            on_connect);

    ctx->refs.request = h2o_mruby_create_data_instance(mrb, mrb_ary_entry(generator->ctx->constants, H2O_MRUBY_HTTP_REQUEST_CLASS),
                                                       ctx, &request_type);
    return ctx->refs.request;
}
示例#30
0
static int
mrb_actor_pipe_reader(zloop_t* reactor, zsock_t* pipe, void* args)
{
    errno = 0;
    self_t* self = (self_t*)args;
    int rc = 0;
    zmsg_t* msg = zmsg_recv(pipe);
    if (!msg)
        return -1;

    char* command = zmsg_popstr(msg);
    zsys_debug("command: %s", command);
    if (streq(command, "$TERM")) {
        rc = -1;
    }
    else if (streq(command, "BIND ROUTER")) {
        char* endpoint = zmsg_popstr(msg);
        if (zsock_bind(self->router, "%s", endpoint) >= 0) {
            const char* boundendpoint = zsock_endpoint(self->router);
            zyre_set_header(self->discovery, "mrb-actor-v1-router", "%s", boundendpoint);
            zsock_signal(pipe, 0);
            zsock_send(pipe, "s", boundendpoint);
        } else {
            zsock_signal(pipe, 1);
            zsock_send(pipe, "i", errno);
        }
        zstr_free(&endpoint);
    }
    else if (streq(command, "BIND PULL")) {
        char* endpoint = zmsg_popstr(msg);
        if (zsock_bind(self->pull, "%s", endpoint) >= 0) {
            const char* boundendpoint = zsock_endpoint(self->pull);
            zyre_set_header(self->discovery, "mrb-actor-v1-pull", "%s", boundendpoint);
            zsock_signal(pipe, 0);
            zsock_send(pipe, "s", boundendpoint);
        } else {
            zsock_signal(pipe, 1);
            zsock_send(pipe, "i", errno);
        }
        zstr_free(&endpoint);
    }
    else if (streq(command, "ZYRE SET ENDPOINT")) {
        char* endpoint = zmsg_popstr(msg);
        if (zyre_set_endpoint(self->discovery, "%s", endpoint) == -1) {
            zsock_signal(pipe, 1);
        } else {
            zsock_signal(pipe, 0);
        }
        zstr_free(&endpoint);
    }
    else if (streq(command, "ZYRE GOSSIP BIND")) {
        char* endpoint = zmsg_popstr(msg);
        zyre_gossip_bind(self->discovery, "%s", endpoint);
        zstr_free(&endpoint);
    }
    else if (streq(command, "ZYRE GOSSIP CONNECT")) {
        char* endpoint = zmsg_popstr(msg);
        zyre_gossip_connect(self->discovery, "%s", endpoint);
        zstr_free(&endpoint);
    }
    else if (streq(command, "ZYRE START")) {
        if (zyre_start(self->discovery) == -1) {
            zsock_signal(pipe, 1);
        } else {
            zyre_join(self->discovery, "mrb-actor-v1");
            zsock_signal(pipe, 0);
        }
    }
    else if (streq(command, "LOAD IREP FILE")) {
        char* mrb_file = zmsg_popstr(msg);
        mrb_state* mrb = self->mrb;
        int ai = mrb_gc_arena_save(mrb);
        struct mrb_jmpbuf* prev_jmp = mrb->jmp;
        struct mrb_jmpbuf c_jmp;

        MRB_TRY(&c_jmp)
        {
            mrb->jmp = &c_jmp;
            FILE* fp = fopen(mrb_file, "rb");
            if (!fp) {
                mrb_sys_fail(mrb, "fopen");
            }
            mrb_load_irep_file(mrb, fp);
            fclose(fp);
            if (mrb->exc) {
                mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
            }
            zsock_signal(pipe, 0);
            mrb->jmp = prev_jmp;
        }
        MRB_CATCH(&c_jmp)
        {
            mrb->jmp = prev_jmp;
            mrb_print_error(mrb);
            zsock_signal(pipe, 1);
            mrb->exc = NULL;
        }
        MRB_END_EXC(&c_jmp);
        mrb_gc_arena_restore(mrb, ai);

        zstr_free(&mrb_file);
    }