You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@trafficserver.apache.org by ChangCheng <cc...@msn.com> on 2011/05/03 14:35:28 UTC

TS Error->OpenReadHead failed?

Hi:
For some reason. Every request Url have been modified before my ATS accept. eg: www.example.com -> www.example.com&xxid=1. So i have a plug-in running on my ATS to strip out this modified parameter, back to normal URL.
I did a stress test for ATS over night, i have a script to continue request modified URL. i got this error message from my traffic.out log file.
[May  3 13:12:41.267] Server {1085303664} NOTE: OpenReadHead failed for cachekey C0EE02F9 : vector inconsistency with 2736
[May  3 13:12:43.635] Server {1086356336} NOTE: OpenReadHead failed for cachekey B23FE0E6 : vector inconsistency with 3864
[May  3 13:12:46.764] Server {1084250992} NOTE: OpenReadHead failed for cachekey 23299E8B : vector inconsistency with 2872
[May  3 13:12:48.697] Server {1084250992} NOTE: OpenReadHead failed for cachekey 487830EF : vector inconsistency with 2840
[May  3 13:13:03.815] Server {1086356336} NOTE: OpenReadHead failed for cachekey 74893488 : vector inconsistency with 2888
[May  3 13:13:11.034] Server {1086356336} NOTE: OpenReadHead failed for cachekey AD80A11B : vector inconsistency with 2768
[May  3 13:14:42.328] Server {1085303664} NOTE: OpenReadHead failed for cachekey 33AABFC5 : vector inconsistency with 2840

I don't know what's reason caused this error. This is core part of my plug-in  down below:

const char *RGWIDName = "xxid";
static void handle_read_request(TSHttpTxn txnp, TSCont contp) {
    TSMBuffer bufp;
    TSMLoc hdr_loc;
    int tmp_len;
    int tmp_len1;
    char *modified;
    char *modifiedURL;
    char *query;
    const char *methodGet;
    if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
        TSError("couldn't retrieve client request header\n");
        goto done;
    }
    /**strip out only work on get and head method*/
    methodGet = TSHttpHdrMethodGet(bufp, hdr_loc, &tmp_len1);
    if (methodGet == TS_HTTP_METHOD_GET || methodGet == TS_HTTP_METHOD_HEAD) {
        modifiedURL = TSHttpTxnEffectiveUrlStringGet(txnp, &tmp_len);
        modified = strstr(modifiedURL, RGWIDName);
        if (modified != NULL) {

                if (allLog)
                    TSTextLogObjectWrite(
                            allLog,
                            (char*) "[handle_read_request] Modified url  RGWValue is %s",
                            modified);
                else
                    TSError("[handle_read_request] Error write into log");
           /**set orginal url into header*/
            int orginalURLLength = strlen(modifiedURL) - strlen(modified) - 1;
            char orginalURL[orginalURLLength];
            strncpy(orginalURL, modifiedURL, orginalURLLength);
            char *start = orginalURL, *end = orginalURL + orginalURLLength;
            TSMBuffer urlBuf = TSMBufferCreate();
            TSMLoc urlLoc;
            TSUrlCreate(urlBuf, &urlLoc);
            if (TSUrlParse(urlBuf, urlLoc, (const char **) &start, end)
                    != TS_PARSE_DONE) {
                TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
                TSUrlDestroy(urlBuf, urlLoc);
                TSHandleMLocRelease(urlBuf, NULL, urlLoc);
                TSError("[all-plugin<handle_read_request>] Can't not parse URL");
                goto done;
            }

            if (TSHttpHdrUrlSet(bufp, hdr_loc, urlLoc) == TS_ERROR) {
                TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
                TSUrlDestroy(urlBuf, urlLoc);
                TSHandleMLocRelease(urlBuf, TS_NULL_MLOC, urlLoc);
                TSError("[all-plugin<handle_read_request>] Can't not set URL");
                goto done;
            }
            TSUrlDestroy(urlBuf, urlLoc);
            TSHandleMLocRelease(urlBuf, TS_NULL_MLOC, urlLoc);
            TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
            goto done;
        } else {
            if (allLog)
                TSTextLogObjectWrite(allLog,
                        (char*) "[handle_read_request] Normal url");
            else
                TSError("[handle_read_request] Error write into log");
        }
        TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);

        goto done;
    }
    TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
    done: TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
}

I would like to know it's my plug-in problem or TS bug cuased this error?
Any Suggestion?
Thanks

PS: My ATS version is 2.1.7
 		 	   		  

Re: TS Error->OpenReadHead failed?

Posted by Leif Hedstrom <zw...@apache.org>.
One thing to test is to completely clear the cache. E.g traffic_server -Cclear .

-- leif

Re: TS Error->OpenReadHead failed?

Posted by Leif Hedstrom <zw...@apache.org>.
On 05/03/2011 06:35 AM, ChangCheng wrote:
>
> I don't know what's reason caused this error. This is core part of my plug-in  down below:

Nothing rings any bells, but let me give some input on the plugin code.

> const char *RGWIDName = "xxid";
> static void handle_read_request(TSHttpTxn txnp, TSCont contp) {
>     TSMBuffer bufp;
>     TSMLoc hdr_loc;
>     int tmp_len;
>     int tmp_len1;
>     char *modified;
>     char *modifiedURL;
>     char *query;
>     const char *methodGet;
>     if (TSHttpTxnClientReqGet(txnp, &bufp, &hdr_loc) != TS_SUCCESS) {
>         TSError("couldn't retrieve client request header\n");
>         goto done;
>     }
>     /**strip out only work on get and head method*/
>     methodGet = TSHttpHdrMethodGet(bufp, hdr_loc, &tmp_len1);
>     if (methodGet == TS_HTTP_METHOD_GET || methodGet == TS_HTTP_METHOD_HEAD) {
>         modifiedURL = TSHttpTxnEffectiveUrlStringGet(txnp, &tmp_len);

This modifiedURL must be TSfree()'d before the plugin is done.
>         modified = strstr(modifiedURL, RGWIDName);
>         if (modified != NULL) {

Assuming the GWIDName can only occur in the query parameters, why are
you not just getting the query parms, using TSUrlHttpQueryGet() ? That
has the advantage too that you don't need to worry about freeing, and it
will also be *much* faster, since it works directly on the marshal buffers.

>             TSUrlCreate(urlBuf, &urlLoc);
>             if (TSUrlParse(urlBuf, urlLoc, (const char **) &start, end)
>                     != TS_PARSE_DONE) {
>                 TSHandleMLocRelease(bufp, TS_NULL_MLOC, hdr_loc);
>                 TSUrlDestroy(urlBuf, urlLoc);
>                 TSHandleMLocRelease(urlBuf, NULL, urlLoc);
>                 TSError("[all-plugin<handle_read_request>] Can't not parse URL");
>                 goto done;
>             }
>
>             if (TSHttpHdrUrlSet(bufp, hdr_loc, urlLoc) == TS_ERROR) {

Same here, why not just use TSUrlHttpQuerySet() ? That avoids all this
URL creation, parsing, and URL copying. If the stuff is not in the query
arguments, but in e.g. the URI path, there are similar APIs to Get() and
Set() that component. In almost all cases, it's easier and much faster
to work on the various components, instead of creating that URL string
copy, and then work on that.

-- Leif