Beispiel #1
0
void network_be_end ( epdata_t *epd )  // for lua function die
{
    if ( epd->process_timeout == 1 && epd->keepalive != -1 ) {
        epd->process_timeout = 0;
        free_epd ( epd );
        return;
    }

    //printf ( "network_be_end %d\n" , ((se_ptr_t*)epd->se_ptr)->fd );
    update_timeout ( epd->timeout_ptr, STEP_SEND_TIMEOUT );
    se_be_write ( epd->se_ptr, network_be_write );
    serv_status.success_counts++;
    epd->status = STEP_SEND;
    serv_status.sending_counts++;

    if ( epd->iov[0].iov_base == NULL && epd->iov[1].iov_base == NULL
         && epd->response_sendfile_fd == -1 ) {
        serv_status.sending_counts--;
        network_send_error ( epd, 417, "" );

    } else if ( epd->response_sendfile_fd == -2 ) {
        epd->response_sendfile_fd = -1;
        serv_status.sending_counts--;
        network_send_error ( epd, 404, "File Not Found!" );

    } else {
        int gzip_data = 0;

        //printf("%d %s\n", epd->response_content_length, epd->iov[1].iov_base);
        if ( epd->response_content_length > 1024 && epd->iov[1].iov_base &&
             !is_binary ( epd->iov[1].iov_base, epd->iov[1].iov_len )
           ) {
            char *p = NULL;

            if ( epd->headers ) {
                p = stristr ( epd->headers, "Accept-Encoding", epd->header_len );
            }

            if ( p ) {
                p += 16;
                int i = 0, m = strlen ( p );

                for ( ; i < 20 && i < m; i++ ) {
                    if ( p[i] == '\n' ) {
                        break;
                    }
                }

                p[i] = '\0';

                if ( strstr ( p, "deflate" ) ) {
                    gzip_data = 2;

                } else if ( strstr ( p, "gzip" ) ) {
                    gzip_data = 1;
                }

                p[i] = '\n';
            }
        }

        if ( gzip_data > 0 )
            epd->response_content_length = gzip_iov ( gzip_data,
                                           ( struct iovec * ) &epd->iov,
                                           epd->iov_buf_count,
                                           &epd->iov_buf_count );

        int len = 0;

        if ( epd->iov[0].iov_base == NULL ) {
            len = sprintf ( temp_buf,
                            "HTTP/1.1 200 OK\r\nServer: aLiLua/%s (%s)\r\nContent-Type: text/html; charset=UTF-8\r\nConnection: %s\r\n%sContent-Length: %d\r\n\r\n",
                            version, hostname, ( epd->keepalive == 1 ? "keep-alive" : "close" ),
                            ( gzip_data == 1 ? "Content-Encoding: gzip\r\n" : ( gzip_data == 2 ?
                                    "Content-Encoding: deflate\r\n" : "" ) ),
                            epd->response_content_length + ( gzip_data == 1 ? 10 : 0 ) );
            epd->response_header_length = len;

        } else {
            //( ( char * ) ( epd->iov[0].iov_base ) ) [epd->response_header_length] = '\0';
            memcpy ( temp_buf, epd->iov[0].iov_base, epd->response_header_length );
            len = epd->response_header_length + sprintf ( temp_buf + epd->response_header_length,
                    "Server: aLiLua/%s (%s)\r\nConnection: %s\r\nDate: %s\r\n%sContent-Length: %d\r\n\r\n",
                    version, hostname, ( epd->keepalive == 1 ? "keep-alive" : "close" ), now_date,
                    ( gzip_data == 1 ? "Content-Encoding: gzip\r\n" : ( gzip_data == 2 ?
                            "Content-Encoding: deflate\r\n" : "" ) ),
                    epd->response_content_length + ( gzip_data == 1 ? 10 : 0 ) );
            epd->response_header_length += len;
        }

        if ( len < 4086 && epd->response_sendfile_fd <= -1 && epd->iov[1].iov_base
             && epd->iov[1].iov_len > 0 ) {
            if ( epd->iov[0].iov_base == NULL ) {
                epd->iov[0].iov_base = malloc ( EP_D_BUF_SIZE );
            }

            if ( epd->iov[0].iov_base == NULL ) {
                epd->keepalive = 0;
                network_end_process ( epd );
                serv_status.sending_counts--;
                return;
            }

            memcpy ( epd->iov[0].iov_base, temp_buf, len );
            epd->iov[0].iov_len = len;
            epd->response_content_length += len;

            if ( gzip_data == 1 ) {
                memcpy ( epd->iov[0].iov_base + len, gzip_header, 10 );
                epd->iov[0].iov_len += 10;
                epd->response_content_length += 10;
            }

            epd->iov_buf_count += 1;

        } else {
            network_raw_send ( epd->fd, temp_buf, len );

            if ( gzip_data == 1 ) {
                network_raw_send ( epd->fd, gzip_header, 10 );
            }

            free ( epd->iov[0].iov_base );
            epd->iov[0].iov_base = NULL;
            int i = 0;

            for ( i = 0; i < epd->iov_buf_count; i++ ) {
                epd->iov[i] = epd->iov[i + 1];
                epd->iov[i + 1].iov_base = NULL;
                epd->iov[i + 1].iov_len = 0;
            }
        }

        //epd->response_header_length = 0;
        //printf("%d\n", epd->response_header_length);

        if ( epd->response_content_length == 0 ) {
            network_end_process ( epd );
            serv_status.sending_counts--;

        } else {
            epd->response_buf_sended = 0;

        }
    }
}
static int lua_co_send(lua_State *L)
{
    cosocket_t *c*k = NULL;
    {
        if(lua_gettop(L) < 2) {
            return 0;
        }

        int t = lua_type(L, 2);

        if(!lua_isuserdata(L, 1) || (t != LUA_TSTRING && t != LUA_TTABLE)) {
            lua_pushboolean(L, 0);
            lua_pushstring(L, "Error params!");
            return 2;
        }

        c*k = (cosocket_t *) lua_touserdata(L, 1);

        if(c*k->status != 2 || c*k->fd == -1 || !c*k->ptr) {
            lua_pushboolean(L, 0);
            lua_pushstring(L, "Not connected!");
            return 2;
        }

        if(c*k->inuse == 1) {
            lua_pushnil(L);
            lua_pushstring(L, "socket busy!");
            return 2;
        }

        c*k->L = L;
        c*k->send_buf_ed = 0;

        if(t == LUA_TTABLE) {
            c*k->send_buf_len = lua_calc_strlen_in_table(L, 2, 2, 1 /* strict */);

            if(c*k->send_buf_len > 0) {
                if(c*k->send_buf_len < _SENDBUF_SIZE) {
                    c*k->send_buf_need_free = NULL;
                    lua_copy_str_in_table(L, 2, c*k->_send_buf);
                    c*k->send_buf = c*k->_send_buf;

                } else {
                    c*k->send_buf_need_free = large_malloc(c*k->send_buf_len);

                    if(!c*k->send_buf_need_free) {
                        LOGF(ERR, "malloc error @%s:%d\n", __FILE__, __LINE__);
                        exit(1);
                    }

                    lua_copy_str_in_table(L, 2, c*k->send_buf_need_free);
                    c*k->send_buf = c*k->send_buf_need_free;
                }
            }

        } else {
            const char *p = lua_tolstring(L, 2, &c*k->send_buf_len);
            c*k->send_buf_need_free = NULL;

            if(c*k->send_buf_len < _SENDBUF_SIZE) {
                memcpy(c*k->_send_buf, p, c*k->send_buf_len);
                c*k->send_buf = c*k->_send_buf;

            } else {
                c*k->send_buf_need_free = large_malloc(c*k->send_buf_len);

                if(!c*k->send_buf_need_free) {
                    LOGF(ERR, "malloc error @%s:%d\n", __FILE__, __LINE__);
                    exit(1);
                }

                memcpy(c*k->send_buf_need_free, p, c*k->send_buf_len);
                c*k->send_buf = c*k->send_buf_need_free;
            }
        }

        if(c*k->send_buf_len < 1) {
            lua_pushboolean(L, 0);
            lua_pushstring(L, "content empty!");
            return 2;
        }

        c*k->inuse = 0;
        int ret = cosocket_be_write(c*k->ptr);

        if(ret > 0) {
            se_be_write(c*k->ptr, cosocket_be_write);

            c*k->timeout_ptr = add_timeout(c*k, c*k->timeout, timeout_handle);
            c*k->inuse = 1;
            return lua_yield(L, 0);

        } else {
            return 0 - ret;
        }
    }
}