user1225207
user1225207

Reputation: 13

libcurl how to change encoding url behavior

Problem: When I make a request which contains redirects, the last of the redirects returns 404 because a URL from the Location header contains a '#' character. libcurl encodes it to %23 and the request returns 404 (server's rules?) while some other requests with redirects to a URL containing a '#' work fine. For example the Opera browser also gets 404 with %23 and 200 with '#'. Does anyone knows how can I change such behavior and make libcurl not to encode the URL? So at this time I don't want to go to redirection URLs manually... This behavior is noted with and without a proxy.

Additional info
-------------------------------------
libcurl 7.27.0
Ubuntu 12.04
CURLOPT_FOLLOWLOCATION = true
CURLOPT_MAXREDIRS = -1
HTTP 1.1
CURLOPT_POSTREDIR = default

Upvotes: 0

Views: 977

Answers (1)

amaurea
amaurea

Reputation: 5067

I do not know if you can control this directly in libcurl. But even if you cannot, not all hope is lost. Your code can hijack curl_easy_escape to get the behavior you want. This is a hack, but you could use it as a last resort, I guess.

The here is a simple example that highjacks the double sin(double) function from the math library. First the main file which uses sin:

sin_test.c:

#include <math.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char ** argv)
{
    double x = atof(argv[1]);
    printf("sin(%f) = %f\n", x, sin(x));
    return 0;
}

Compile this file: gcc -o sin_test sin_test.c -lm, and check that it works

./sin_test 1
sin(1.000000) = 0.841471

We will now take this as given, and try to override its behavior without changing its source code. To do this, we define a shared library sin_override.so as follows. Create the file sin_override.c with the contents:

#include <math.h>
#include <stdlib.h>
#define __USE_GNU
#include <dlfcn.h>

double sin(double x)
{
    double (*real_sin)(double) = NULL;
    if(!real_sin) real_sin = dlsym(RTLD_NEXT,"sin");
    return real_sin(x)/10;
}

And compile it with `gcc -fPIC -shared -o sin_override.so sin_override.c -ldl. Now tell the system to load this shared library before the program itself:

LD_PRELOAD=/full/path/to/sin_override.so ./sin_test 1
sin(1.000000) = 0.084147

The answer is now 10 times smaller than before, confirming that we have overridden the default sin.

In your case, you would be overriding curl_easy_escape instead, by first calling the real curl_easy_escape, and then running through the resulting string, replacing %23 with #, and then returning the modified string. I haven't tested this for libcurl, but something like this should work, though it is a bit cumbersome.

Upvotes: 1

Related Questions