view src/os/win32/ngx_wsarecv_chain.c @ 505:ee66921ecd47 release-0.1.27

nginx-0.1.27-RELEASE import *) Feature: the "blocked" parameter of the "valid_referers" directive. *) Change: the errors while handling the request header now logged at "info" level. The server name and the "Host" and "Referer" header lines also logged. *) Change: the "Host" header line is also logged in error log. *) Feature: the proxy_pass_unparsed_uri directive. The special handling of the "://" symbols in URI, appeared in 0.1.11 version, now is canceled. *) Bugfix: nginx could not be built on FreeBSD and Linux, if the --without-ngx_http_auth_basic_module configuration parameter was used.
author Igor Sysoev <igor@sysoev.ru>
date Mon, 28 Mar 2005 14:43:02 +0000
parents d4ea69372b94
children 4d9ea73a627a
line wrap: on
line source


/*
 * Copyright (C) Igor Sysoev
 */


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>


#define NGX_WSABUFS  8 


ssize_t
ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain)
{
    int           rc;
    u_char       *prev;
    u_long        bytes, flags;
    size_t        size;
    ngx_err_t     err;
    ngx_array_t   vec;
    ngx_event_t  *rev;
    LPWSABUF      wsabuf;
    WSABUF        wsabufs[NGX_WSABUFS];

    prev = NULL;
    wsabuf = NULL;
    flags = 0;
    size = 0;
    bytes = 0;

    vec.elts = wsabufs;
    vec.nelts = 0;
    vec.size = sizeof(WSABUF);
    vec.nalloc = NGX_WSABUFS; 
    vec.pool = c->pool;

    /* coalesce the neighbouring bufs */

    while (chain) {
        if (prev == chain->buf->last) {
            wsabuf->len += chain->buf->end - chain->buf->last;

        } else {
            wsabuf = ngx_array_push(&vec);
            if (wsabuf == NULL) {
                return NGX_ERROR;
            }

            wsabuf->buf = (char *) chain->buf->last;
            wsabuf->len = chain->buf->end - chain->buf->last;
        }

        size += chain->buf->end - chain->buf->last;
        prev = chain->buf->end;
        chain = chain->next;
    }

    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
                   "WSARecv: %d:%d", vec.nelts, wsabuf->len);


    rc = WSARecv(c->fd, vec.elts, vec.nelts, &bytes, &flags, NULL, NULL);

    rev = c->read;

    if (rc == -1) {
        rev->ready = 0;
        err = ngx_socket_errno;

        if (err == WSAEWOULDBLOCK) {
            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
                           "WSARecv() not ready");
            return NGX_AGAIN;
        }

        rev->error = 1;
        ngx_connection_error(c, err, "WSARecv() failed");
        return NGX_ERROR;
    }

    if (bytes < size) {
        rev->ready = 0;
    }

    if (bytes == 0) {
        rev->eof = 1;
    }

    return bytes;
}