October 13th Tuesday

  Yesterday I was always finding out a way to slove the problem about base64 decoding in the nginx.  After some testing, I found the engine is inable to get the finger printer data or the templet data from the url request.  I tried several methods to get the correct data.  That is not easy because there are not the english documents on it.  The author of nginx is a Muscovite.  It is said that his english is not good.  So, now there is not a authentic english documents on the nginx.

 

  It is a main drawback during developing the module of nginx.  Another is that I can not use the functions in the standard C library.  I have to rewrite some functions which is depended by my modules.

 

  OK.  Let's return the base64 problem.  I download a base64 decoding function from the official site.  The algorithm can run correctly.  However, the decoding algorithm in the nginx can not.  The algorithm in the nginx checks wether each datum is right, firstly; and check whether the length of encoding data is divided by four, at once no remainder.  The standard algorithm just check the length of encoding data.

 

  I removed the data check from the decoding algorithm of the nginx, and tested it.  The result from decoding is discrepancy from the standard algorithm.  Although there are just several bytes's value vary.  The discrepance bewteen tow decoding algorithms is so important and dangerous.

 

/* the decoding algorithm in the nginx */

ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
{
    size_t          len;
    u_char         *d, *s;
    static u_char   basis64[] = {
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
        77,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 77, 77, 77, 77, 77,
        77, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 77, 77, 77, 77, 77,

        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
        77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77
    };

    for (len = 0; len < src->len; len++) {
        if (src->data[len] == '=') {
            break;
        }

        if (basis64[src->data[len]] == 77) {
            return NGX_ERROR;
        }
    }

    if (len % 4 == 1) {
        return NGX_ERROR;
    }

    s = src->data;
    d = dst->data;

    while (len > 3) {
        *d++ = (u_char) (basis64[s[0]] << 2 | basis64[s[1]] >> 4);
        *d++ = (u_char) (basis64[s[1]] << 4 | basis64[s[2]] >> 2);
        *d++ = (u_char) (basis64[s[2]] << 6 | basis64[s[3]]);

        s += 4;
        len -= 4;
    }

    if (len > 1) {
        *d++ = (u_char) (basis64[s[0]] << 2 | basis64[s[1]] >> 4);
    }

    if (len > 2) {
        *d++ = (u_char) (basis64[s[1]] << 4 | basis64[s[2]] >> 2);
    }

    dst->len = d - dst->data;

    return NGX_OK;
}

 

 

/* the decoding algorithm is implemented by me according to the standard decoding algorithm */

 

/*
** Translation Table to decode (created by author)
*/
static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[//]^_`abcdefghijklmnopq";

 

/*
** decodeblock
**
** decode 4 '6-bit' characters into 3 8-bit binary bytes
*/
static void decodeblock( u_char in[4], u_char out[3] )
{  
    out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
    out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2);
    out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
}

static ngx_int_t std_decode_base64(ngx_str_t *dst, ngx_str_t *src)
{
    u_char in[4], out[3], v;
    ngx_int_t i, len;
    u_char *cp = src->data;
    u_char *end = src->data + src->len;
    u_char *rs = dst->data;

    /*if (src->len %4 != 0) return NGX_ERROR;*/

    while ( !(cp > end) ) {
        for ( len = 0, i = 0; i < 4 && !(cp > end); i++ ) {
            v = 0;
            while ( !(cp > end) && v == 0 ) {
                v = (u_char) (*cp);
                cp++;
                v = (u_char) ((v < 43 || v > 122) ? 0 : cd64[v - 43]);
                if (v) {
                    v = (u_char) ((v == '$') ? 0 : v - 61);
                }
            }

            if ( !(cp > end) ) {
                len++;
                if (v) {
                    in[i] = (u_char) (v - 1);
                }
            }
            else {
                in[i] = 0;
            }
        }

        if (len) {
            decodeblock(in, out);
            for (i = 0; i < len - 1; i++) {
                *rs = out[i];
                rs++;
            }
        }
    }

    *rs = '/0';
    dst->len = rs - dst->data;

    return NGX_OK;
}

 

 

你可能感兴趣的:(Algorithm,nginx,download,encoding,methods,translation)