Gazelle

 view release on metacpan or  search on metacpan

lib/Plack/Handler/Gazelle.xs  view on Meta::CPAN

    (void)hv_stores(e,"psgi.run_once",        newSV(0));
    (void)hv_stores(e,"psgi.multithread",     newSV(0));
    (void)hv_stores(e,"psgi.multiprocess",    newSViv(1));
    (void)hv_stores(e,"psgi.streaming",       newSViv(1));
    (void)hv_stores(e,"psgi.nonblocking",     newSV(0));
    (void)hv_stores(e,"psgix.input.buffered", newSViv(1));
    (void)hv_stores(e,"psgix.harakiri",       newSViv(1));

    /* stolenn from Feersum */
    /* placeholders that get defined for every request */
    (void)hv_stores(e, "SERVER_PROTOCOL", &PL_sv_undef);
    (void)hv_stores(e, "SERVER_NAME",     &PL_sv_undef);
    (void)hv_stores(e, "SERVER_PORT",     &PL_sv_undef);
    (void)hv_stores(e, "REQUEST_URI",     &PL_sv_undef);
    (void)hv_stores(e, "REQUEST_METHOD",  &PL_sv_undef);
    (void)hv_stores(e, "PATH_INFO",       &PL_sv_undef);
    (void)hv_stores(e, "REMOTE_ADDR",     &PL_sv_placeholder);
    (void)hv_stores(e, "REMOTE_PORT",     &PL_sv_placeholder);

    /* defaults that get changed for some requests */
    (void)hv_stores(e, "psgi.input",      &PL_sv_placeholder);
    (void)hv_stores(e, "CONTENT_LENGTH",  &PL_sv_placeholder);
    (void)hv_stores(e, "QUERY_STRING",    &PL_sv_placeholder);

    /* anticipated headers */
    (void)hv_stores(e, "CONTENT_TYPE",           &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_HOST",              &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_USER_AGENT",        &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_ACCEPT",            &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_ACCEPT_LANGUAGE",   &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_ACCEPT_CHARSET",    &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_REFERER",           &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_COOKIE",            &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_IF_MODIFIED_SINCE", &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_IF_NONE_MATCH",     &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_IF_MODIFIED_SINCE", &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_IF_NONE_MATCH",     &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_CACHE_CONTROL",     &PL_sv_placeholder);
    (void)hv_stores(e, "HTTP_X_FORWARDED_FOR",   &PL_sv_placeholder);

    env_template = e;
}

SV *
accept_psgi(fileno, timeout, tcp, host, port)
    int fileno
    double timeout
    int tcp
    SV * host
    SV * port
PREINIT:
    int fd;
    struct sockaddr_in cliaddr;
    unsigned int len;
    char read_buf[MAX_HEADER_SIZE];
    HV * env;
    int flag = 1;
    ssize_t rv = 0;
    ssize_t buf_len;
    ssize_t reqlen;
PPCODE:
{
    /* if ( my ($conn, $buf, $env) = accept_buffer(fileno($server),timeout,tcp,host,port) */

    len = sizeof(cliaddr);
    fd = _accept(fileno, (struct sockaddr *)&cliaddr, len);
    /* endif */
    if (fd < 0) {
      goto badexit;
    }

    rv = _read_timeout(fd, timeout, &read_buf[0], MAX_HEADER_SIZE);
    // printf("fd:%d rv:%ld %f %d\n",fd,rv,timeout);
    if ( rv <= 0 ) {
      close(fd);
      goto badexit;
    }

    env = newHVhv(env_template);

    if ( tcp == 1 ) {
      setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
      (void)hv_stores(env,"REMOTE_ADDR",newSVpv(inet_ntoa(cliaddr.sin_addr),0));
      (void)hv_stores(env,"REMOTE_PORT",newSViv(ntohs(cliaddr.sin_port)));
    }
    else {
      (void)hv_stores(env,"REMOTE_ADDR",newSV(0));
      (void)hv_stores(env,"REMOTE_PORT",newSViv(0));
    }
    (void)hv_stores(env,"SERVER_PORT",SvREFCNT_inc(port));
    (void)hv_stores(env,"SERVER_NAME",SvREFCNT_inc(host));

    buf_len = rv;
    while (1) {
      reqlen = _parse_http_request(aTHX_ &read_buf[0],buf_len,env);
      if ( reqlen >= 0 ) {
        break;
      }
      else if ( reqlen == -1 ) {
        /* error */
        close(fd);
        goto badexit_clear;
      }
      if ( MAX_HEADER_SIZE - buf_len == 0 ) {
        /* too large header  */
       char* badreq;
       badreq = BAD_REQUEST;
       rv = _write_timeout(fd, timeout, badreq, sizeof(BAD_REQUEST) - 1);
       close(fd);
       goto badexit_clear;
      }
      /* request is incomplete */
      rv = _read_timeout(fd, timeout, &read_buf[buf_len], MAX_HEADER_SIZE - buf_len);
      if ( rv <= 0 ) {
        close(fd);
        goto badexit_clear;
      }
      buf_len += rv;
    }

    /* expect */



( run in 0.430 second using v1.01-cache-2.11-cpan-5511b514fd6 )