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 )