diff options
Diffstat (limited to 'src/httpd.c')
-rw-r--r-- | src/httpd.c | 74 |
1 files changed, 60 insertions, 14 deletions
diff --git a/src/httpd.c b/src/httpd.c index 0171a11..c200fc6 100644 --- a/src/httpd.c +++ b/src/httpd.c @@ -3,7 +3,7 @@ char * sc_https2http (char * i) { memmove(i+4, i+5, strlen(i)-3); return i; } -char * sc_queryhtml (const struct sc_query * q, const char * add_form, size_t l) { /* remember to free returned string in the caller */ /* caller takes care of freeing */ +char * sc_queryhtml (const struct sc_query * q, const char * add_form, size_t l, const char * r) { /* remember to free returned string in the caller */ /* caller takes care of freeing */ size_t resultshtml_written = 0; size_t resultshtml_sizeof = SC_ALLOC_CHUNK; char * resultshtml = malloc(resultshtml_sizeof); @@ -39,16 +39,48 @@ char * sc_queryhtml (const struct sc_query * q, const char * add_form, size_t l) free(safebody); free(safeurl); } -#define SC_HRS SC_I18N_NUMBER_OF_RESULTS ": %zu | " SC_I18N_QUERY_TIME ": %s" char formatted_time[128]; struct tm tm; localtime_r(&q->lookup_time, &tm); strftime(formatted_time, 128, SC_I18N_DATETIME_FORMAT, &tm); - char queryinfo[256]; - snprintf(queryinfo, 256, SC_HRS, q->results_length, formatted_time); + char * safesuggested = NULL; + if (q->suggested && strlen(q->suggested) < 4096) { + safesuggested = alloca(strlen(q->suggested)*3+256); + strcpy(safesuggested, "?q="); + urlencode(safesuggested+3, q->suggested); + } + if (!q->suggested && r && strlen(r) < 4096) { + safesuggested = alloca(strlen(r)*3+256); + strcpy(safesuggested, "?q="); + urlencode(safesuggested+3, r); + } + char * htmlsuggested = htmlspecialchars(q->suggested); + if (!htmlsuggested) + htmlsuggested = htmlspecialchars(r); + if (safesuggested) { + if (strstr(add_form, "name=h")) + strcat(safesuggested, "&h=h"); + if (strstr(add_form, "name=l")) + sprintf(safesuggested+strlen(safesuggested), "&l=%d", atoi(strstr(add_form, "name=l")+8)); + if (strstr(add_form, "name=h")) + strcat(safesuggested, "&h=h"); + if (strstr(add_form, "name=e") || r) + strcat(safesuggested, "&e=e"); + } + char * suggested = NULL; + if (htmlsuggested && safesuggested) + suggested = malloc(1+strlen(SC_I18N_DID_YOU_REALLY_MEAN)+strlen(SC_I18N_DID_YOU_MEAN)+strlen(safesuggested)+strlen(htmlsuggested)); + if (suggested) + sprintf(suggested, "%s <a href='%s'>%s</a>", q->suggested ? SC_I18N_DID_YOU_MEAN : SC_I18N_DID_YOU_REALLY_MEAN, safesuggested, htmlsuggested); + char * queryinfo = malloc(256+strlen(suggested ? suggested : "")); + snprintf(queryinfo, 256, "%s%s" SC_I18N_NUMBER_OF_RESULTS ": %zu | " SC_I18N_QUERY_TIME ": %s" +, suggested ? suggested : "", suggested ? " | " : "", q->results_length, formatted_time); char * safequery = htmlspecialchars(q->string); char * response = malloc(strlen((char *) sc_hp)+2*strlen(safequery)+strlen(queryinfo)+strlen(resultshtml)+strlen(add_form)); sprintf(response, (char *) sc_hp, safequery, safequery, add_form, queryinfo, resultshtml); + free(queryinfo); + free(suggested); + free(htmlsuggested); free(safequery); free(resultshtml); return response; @@ -130,6 +162,8 @@ enum MHD_Result sc_httpd (void * cls, const char * l = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "l"); const char * h = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "h"); const char * f = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "f"); + const char * e = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "e"); + const char * r = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "r"); snprintf(add_form, 128, "%s%s%d%s", h ? "<input type=hidden name=h value=h />" : "", l ? "<input type=hidden name=l value=" : "<!-- Odgovor na dokončno vprašanje o Življenju, Vesolju in sploh Vsem je ", l ? atoi(l) : 42, @@ -212,11 +246,29 @@ retry: sc_https2http(LOCHORSE); location = out; } else - response = sc_queryhtml(q, add_form, atoi(l ? l : "0")); /* MHD_create_response_from_buffer will free response (; */ + response = sc_queryhtml(q, add_form, atoi(l ? l : "0"), r); /* MHD_create_response_from_buffer will free response (; */ SC_CUE(c, c->queries_lock); } else { SC_CUE(c, c->queries_lock); - enum sc_return r = sc_query_google(query, c, NULL, opt); + char * redirect = NULL; + enum sc_return r = sc_query_google(query, c, NULL, e ? NULL : &redirect, opt); + if (redirect && strlen(query) < 4096 && strlen(redirect) < 4096) { + status_code = 307; + location = alloca(256+strlen(query)*3+strlen(redirect)*3); + sprintf(location, "?l=%d%s%s%s%s&q=", atoi(l ? l : ""), (opt & SC_OPT_IMAGE) ? "&i=i" : "", h ? "&h=h" : "", f ? "&f=f" : "", e ? "&e=e" : ""); + urlencode(location+strlen(location), redirect); + free(redirect); + redirect = NULL; + strcat(location, "&r="); + urlencode(location+strlen(location), query); + content_type = "text/plain"; + char * safeurl = htmlspecialchars(location); + free(response); + response = malloc(strlen(safeurl)*3+512); + sprintf(response, "<meta http-equiv=refresh content='0;URL=%s'><a id=a href='%s'>%s</a><script>a.click();</script>", safeurl, safeurl, safeurl); + free(safeurl); + goto sendresp; + } if (already_retried++ || r == SC_CAPTCHA) { status_code = 570+ABS(r); if (r == SC_CAPTCHA && strlen(query) < 4096) { @@ -224,15 +276,8 @@ retry: status_code = 307; location = alloca(strlen(getenv("SC_FALLBACK")) + 256 + strlen(query)*3); - sprintf(location, "%sl=%d&q=", getenv("SC_FALLBACK"), - atoi(l ? l : "")); + sprintf(location, "%sl=%d%s%s%s%s&q=", getenv("SC_FALLBACK"), atoi(l ? l : ""), (opt & SC_OPT_IMAGE) ? "&i=i" : "", h ? "&h=h" : "", f ? "&f=f" : "", e ? "&e=e" : ""); urlencode(location+strlen(location), query); - if (opt & SC_OPT_IMAGE) - strcat(location, "&i=i"); - if (h) - strcat(location, "&h=h"); - if (f) - strcat(location, "&f=f"); } char * safequery = htmlspecialchars(query); response = malloc(strlen((char*) sc_hp) @@ -258,6 +303,7 @@ retry: } else goto retry; } } + sendresp: httpd_response = MHD_create_response_from_buffer (response_len ? response_len : strlen(response), (void *) response, mhdrmm); MHD_add_response_header(httpd_response, "Content-Type", content_type); if (status_code >= 300 && status_code <= 399) |