示例#1
0
static PyObject *Server_route(Server *self, PyObject *args) {
  PyObject *req = NULL;

  if (!PyArg_ParseTuple(args,
                        "O",
                        &req)) {
    PyErr_SetString(PyExc_TypeError, "error parameter");
    return NULL;
  }

  if (!PyObject_TypeCheck(req, &RequestType)) {
    PyErr_SetString(PyExc_TypeError, "the first parameter must be the request object");
    return NULL;
  }

  guava_server_t *server = self->server;
  if (!server->routers) {
    Py_RETURN_NONE;
  }

  Py_ssize_t nrouters = PyList_Size(server->routers);
  Handler *handler = NULL;

  Router *router = (Router *)guava_router_get_best_matched_router(server->routers, req);

  do {
    if (!router) {
      break;
    }

    handler = (Handler *)PyObject_CallMethod((PyObject *)router, "route", "(O)", req);
    handler->handler->router = router->router;

    for (Py_ssize_t i = 0; i < nrouters; ++i) {
      router = (Router *)PyList_GetItem(server->routers, i);
      if (router->router->type != GUAVA_ROUTER_CUSTOM) {
        /*
         * Cause we already try to get the best matched router
         * But we still need to pass the custome router in case use defined some speciall routes
         */
        continue;
      }
      Handler *h = (Handler *)PyObject_CallMethod((PyObject *)router, "route", "(O)", req);
      if ((PyObject *)h != Py_None) {
        handler = h;
        handler->handler->router = router->router;
        break;
      }
    }

    if (!handler || !handler->handler) {
      break;
    }

    return (PyObject *)handler;
  } while (0);

  Py_RETURN_NONE;
}
示例#2
0
int guava_request_on_message_complete(http_parser *parser) {
  guava_conn_t *conn = (guava_conn_t *)parser->data;
  Request *request = (Request *)conn->request;
  guava_server_t *server = conn->server;

  Router *router = NULL;
  Handler *handler = NULL;

  guava_response_t *resp = guava_response_new();
  guava_response_set_conn(resp, conn);

  Py_ssize_t nrouters = PyList_Size(server->routers);

  do {
    router = (Router *)guava_router_get_best_matched_router((PyObject *)server->routers, (PyObject *)request);
    if (router) {
      if (router->router->type == GUAVA_ROUTER_STATIC) {
        guava_handler_static(router->router, conn, ((Request *)conn->request)->req, resp, on_write, on_sendfile);
        break;
      } else {
        handler = (Handler *)PyObject_CallMethod((PyObject *)router, "route", "(O)", request);
        handler->handler->router = router->router;
      }
    }

    for (Py_ssize_t i = 0; i < nrouters; ++i) {
      router = (Router *)PyList_GetItem(server->routers, i);
      if (router->router->type != GUAVA_ROUTER_CUSTOM) {
        /*
         * Cause we already try to get the best matched router
         * But we still need to pass the custome router in case use defined some speciall routes
         */
        continue;
      }
      Handler *h = (Handler *)PyObject_CallMethod((PyObject *)router, "route", "(O)", request);
      if ((PyObject *)h != Py_None) {
        handler = h;
        handler->handler->router = router->router;
        break;
      }
    }

    if (!guava_handler_is_valid(handler->handler) || handler->handler->flags & GUAVA_HANDLER_404) {
      guava_response_404(resp, NULL);
      guava_response_send(resp, on_write);
      break;
    }

    if (handler->handler->flags & GUAVA_HANDLER_REDIRECT) {
      PyObject *location = PyTuple_GetItem(handler->handler->args, 0);
      guava_response_302(resp, PyString_AsString(location));
      guava_response_send(resp, on_write);
      break;
    }

    if (handler->handler->router->type == GUAVA_ROUTER_STATIC) {
      guava_handler_static(handler->handler->router, conn, ((Request *)conn->request)->req, resp, on_write, on_sendfile);
      break;
    }

    PyObject *module_name = NULL;
    if (guava_string_equal_raw(handler->handler->package, ".")) {
      module_name = PyString_FromString(handler->handler->module);
    } else {
      module_name = PyString_FromFormat("%s.%s", handler->handler->package, handler->handler->module);
    }

    PyObject *module = PyImport_Import(module_name);
    Py_DECREF(module_name);

    if (!module) {
      fprintf(stderr, "no module named: %s\n", PyString_AsString(module_name));
      if (PyErr_Occurred()) {
        PyErr_Print();
      }
      guava_response_500(resp, NULL);
      guava_response_send(resp, on_write);
      break;
    }

    PyObject *cls_name = PyString_FromString(handler->handler->cls);
    PyObject *cls = PyObject_GetAttr(module, cls_name);

    Py_DECREF(module);
    Py_DECREF(cls_name);

    if (!cls) {
      fprintf(stderr, "no cls named: %s\n", PyString_AsString(cls_name));
      if (PyErr_Occurred()) {
        PyErr_Print();
      }
      guava_response_500(resp, NULL);
      guava_response_send(resp, on_write);
      break;
    }

    Controller *c = (Controller *)PyObject_CallObject(cls, NULL);

    if (!PyObject_TypeCheck(c, &ControllerType)) {
      fprintf(stderr, "You controller class must inherit from guava.controller.Controller\n");
      guava_response_500(resp, NULL);
      guava_response_send(resp, on_write);
      break;
    }

    Py_DECREF(cls);
    c->resp = resp;
    c->req = ((Request *)conn->request)->req;
    c->router = handler->handler->router;

    PyObject *r = NULL;
    if (handler->handler->args) {
      r = PyObject_CallMethod((PyObject *)c, handler->handler->action, "O", handler->handler->args);
    } else {
      r = PyObject_CallMethod((PyObject *)c, handler->handler->action, NULL);
    }

    if (!r) {
      Py_DECREF(c);
      if (PyErr_Occurred()) {
        PyErr_Print();
      }
      fprintf(stderr, "failed to execute action: %s\n", handler->handler->action);
      guava_response_500(resp, NULL);
      guava_response_send(resp, on_write);
      break;
    }

    if (handler->handler->router->session_store && c->SESSION) {
      guava_request_t *r = ((Request *)conn->request)->req;
      PyObject *sid_cookie = PyDict_GetItemString(r->COOKIES, handler->handler->router->session_store->name);
      guava_session_id_t sid = NULL;

      if (sid) {
        sid = guava_string_new(((Cookie *)sid_cookie)->data.value);
      } else {
        sid = guava_session_new_id();
      }

      guava_session_set(handler->handler->router->session_store, sid, c->SESSION);
    }

    Py_DECREF(c);

    guava_response_send(resp, on_write);
  } while(0);

  Py_XDECREF(handler);
  Py_XDECREF(conn->request);

  return 0;
}