bool NetworkClient::doPost(const NString& data)
{
	private_initTransfer();
	if(!private_apply_method())
   curl_easy_setopt(curl_handle, CURLOPT_POST, 1L);
	std::string postData;
	std::vector<QueryParam>::iterator it, end = m_QueryParams.end();

		for(it=m_QueryParams.begin(); it!=end; it++)
		{
			if(!it->isFile)
			{
				postData+= urlEncode(it->name)+"="+urlEncode(it->value)+"&";
			}
		}

	if(data.empty()) {
		curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postData.c_str());
	}
	else {
		curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data.c_str());
	}

	m_currentActionType = atPost;	
	curl_result = curl_easy_perform(curl_handle);
	return private_on_finish_request();
}
Example #2
0
static STSStatus compose_url_encoded_post_data(char* buffer, uint32_t bufferSize,
                                        char* queryParams, const uint32_t queryLen,
                                        const char* signature)
{
    char* pParams = queryParams;
    char* pBuffer = buffer;
    int len = 0;
    int index = 0;
    
    while (index < queryLen) {
        char* begin = pParams;
        char* middle = strchr(begin, '=');
        char* end = strchr(begin, '&');
        
        size_t size = 0;
        if (NULL != end) {
            size = end - begin + 1;
        }
        else {
            size = strlen(begin) + 1;
        }
        index += size;
        
        size_t keyLen = middle - begin;
        char* key = begin;
        size_t valueLen = size - keyLen - 2;
        char* value = middle + 1;
        
        char* encodedKey = calloc(keyLen*3, 1);
        char* encodedValue = calloc(valueLen*3, 1);
        
        urlEncode(encodedKey, key, keyLen);
        urlEncode(encodedValue, value, valueLen);
        
        snprintf(pBuffer, strlen(encodedKey)+2, "%s=", encodedKey);
        len += strlen(encodedKey) + 1;
        pBuffer = buffer + len;
        
        snprintf(pBuffer, strlen(encodedValue)+2, "%s&", encodedValue);
        len += strlen(encodedValue) + 1;
        pBuffer = buffer + len;
        
        pParams = end + 1;
        free(encodedKey);
        free(encodedValue);
    }
    
    char* signatureKey = "Signature=";
    size_t len2 = strlen(signatureKey);
    snprintf(pBuffer, strlen(signature)+len2+1, "Signature=%s", signature);
    
    return STSStatusOK;
}
void CeIdObject::AddData(std::string name, std::string value)
{
	urlEncode(name);
	urlEncode(value);
	if(m_data.find(name + "=" + value) == std::string::npos){
		if(strcmp("", m_data.c_str()) != 0){
			m_data = m_data.append("&");
		}
		m_data = m_data.append(name);
		m_data = m_data.append("=");
		m_data = m_data.append(value);
	}
}
Example #4
0
inline std::string paramsToUrl(CURL* curl, const ADHttp::Params& params)
{
    std::stringstream res;
    const ADHttp::Params::SVec& keys = params.getKeysString();
    const ADHttp::Params::SVec& values = params.getValuesString();

    for(size_t i = 0; i<keys.size(); ++i)
    {
        if(i)
            res << "&";

        res << urlEncode(curl, keys[i]) << "=" << urlEncode(curl, values[i]);
    }
    return res.str();
}
String IoesptAzure::createEventHubSas(char *key, String url) {
	// START: Create SAS  
	// https://azure.microsoft.com/en-us/documentation/articles/service-bus-sas-overview/
	// Where to get seconds since the epoch: local service, SNTP, RTC

	String stringToSign = url + "\n" + cloud.sasExpiryDate;

	// START: Create signature
	Sha256.initHmac((const uint8_t*)key, 44);
	Sha256.print(stringToSign);

	char* sign = (char*)Sha256.resultHmac();
	int signLen = 32;
	// END: Create signature

	// START: Get base64 of signature
	int encodedSignLen = base64_enc_len(signLen);
	char encodedSign[encodedSignLen];
	base64_encode(encodedSign, sign, signLen);
	// END: Get base64 of signature

	// SharedAccessSignature
	return "sr=" + url + "&sig=" + urlEncode(encodedSign) + "&se=" + cloud.sasExpiryDate + "&skn=" + cloud.id;
	// END: create SAS
}
String IoesptAzure::createIotHubSas(char *key, String url) {
	String stringToSign = url + "\n" + cloud.sasExpiryDate;

	// START: Create signature
	// https://raw.githubusercontent.com/adamvr/arduino-base64/master/examples/base64/base64.ino

	int keyLength = strlen(key);

	int decodedKeyLength = base64_dec_len(key, keyLength);
	char decodedKey[decodedKeyLength];  //allocate char array big enough for the base64 decoded key

	base64_decode(decodedKey, key, keyLength);  //decode key

	Sha256.initHmac((const uint8_t*)decodedKey, decodedKeyLength);
	Sha256.print(stringToSign);
	char* sign = (char*)Sha256.resultHmac();
	// END: Create signature

	// START: Get base64 of signature
	int encodedSignLen = base64_enc_len(HASH_LENGTH);
	char encodedSign[encodedSignLen];
	base64_encode(encodedSign, sign, HASH_LENGTH);

	// SharedAccessSignature
	return "sr=" + url + "&sig=" + urlEncode(encodedSign) + "&se=" + cloud.sasExpiryDate;
	// END: create SAS  
}
/**
 * Encode URL with keys and values, each are passed in separated array
 * @param keys    Array of key which are left untouched
 * @param values  Array of value which will be urlencoded
 * @param output  Result in format
 *                key1=encoded(value1)&key2=encoded(value2)&.....
 * @param bufsize Buffer size of output
 *
 * @note If either a key or value is NULL, that pair will be skipped in the encoding result as if
 * it is not existed.
 * @return number of bytes in output string, 0 if failed (possibly not enough memory in output)
 */
uint16_t AdafruitHTTP::urlEncode(const char* keys[], const char* values[], uint16_t count, char* output, uint16_t bufsize)
{
  uint16_t total_bytes = 0;

  for(uint16_t i=0; i<count && total_bytes < bufsize-1; i++)
  {
    // skip NULL key or value
    if ( keys[i] && values[i] )
    {
      if (i != 0) output[total_bytes++] = '&';

      uint16_t keylen = strlen(keys[i]);
      strncpy(output+total_bytes, keys[i], bufsize-total_bytes);
      total_bytes += keylen;

      output[total_bytes++] = '=';

      uint16_t n = urlEncode(values[i], output+total_bytes, bufsize-total_bytes);
      if (n == 0) return 0; // failed to encode

      total_bytes += n;
    }
  }

  output[total_bytes] = 0;

  return total_bytes;
}
END_TEST

START_TEST(urlEncode_test) {
  char *s;
  s = urlEncode(request, "A b", " A");
  fail_unless(strcmp(s, "%41%20b") == 0);

}
Example #9
0
static std::string urlEncodeParams(map_type const &params)
{
	std::string result;

	typename map_type::const_iterator it;
	for(it=params.begin(); it!=params.end(); it++) {
		if( result.size() ) {
			result += "&";
		}
		urlEncode(it->first.c_str(),result);
		if( !it->second.empty() ) {
			result += "=";
			urlEncode(it->second.c_str(),result);
		}
	}

	return result;
}
const char* NetworkOperation::parameterString()
{
    string paramString="";
    
    map<string, string>::iterator it;
    for(it = _params.begin(); it != _params.end(); it++)
    {
        paramString+= it->first + "=" + urlEncode(it->second)+ "&";
    }
    return paramString.c_str();
}
void TextToken::toString(wchar_t **str, int *sizeAlloced) {
    wchar_t *eText = NULL, *eLink = NULL;
    switch (type) {
        case TEXT:
            eText = urlEncode(wtext);
            Utils::appendText(str, sizeAlloced, L"%s", eText);
            break;
        case WWWLINK:
            eText = urlEncode(wtext);
            eLink = urlEncode(wlink);
            Utils::appendText(str, sizeAlloced, L"<a class=\"link\" target=\"_self\" href=\"http://%s\">%s</a>", eLink, eText);
            break;
        case LINK:
            eText = urlEncode(wtext);
            eLink = urlEncode(wlink);
            Utils::appendText(str, sizeAlloced, L"<a class=\"link\" target=\"_self\" href=\"%s\">%s</a>", eLink, eText);
            break;
        case SMILEY:
            eText = urlEncode(wtext);
            if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_FLASH) && (wcsstr(wlink, L".swf")!=NULL)) {
                Utils::appendText(str, sizeAlloced,
		L"<span title=\"%s\" class=\"img\"><object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" \
		codebase=\"http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0\" >\
		<param NAME=\"movie\" VALUE=\"%s\"><param NAME=\"quality\" VALUE=\"high\"><PARAM NAME=\"loop\" VALUE=\"true\"></object></span><span style=\"position:absolute; visibility:hidden;\">%s</span>",
            	wlink, eText);
			} else if ((Options::getGeneralFlags()&Options::GENERAL_ENABLE_PNGHACK) && (wcsstr(wlink, L".png")!=NULL)) {
Example #12
0
void ProviderDB::loadProviderInfo() {
  delete cfg;

  QString loc = *page2->list->at(page2->lb->currentItem());
  QString provider = page3->lb->text(page3->lb->currentItem());
  urlEncode(provider);
  QString prov = "Provider/" + loc;
  prov += "/" + provider;
  QString fname = locate("appdata", prov);
  kdDebug(5002) << "Providerfile=" << fname << endl;

  cfg = new KSimpleConfig(fname, true);
}
Example #13
0
static const char *getURL(const char *secret, const char *label,
                          char **encoderURL, const int use_totp) {
  const char *encodedLabel = urlEncode(label);
  char *url = malloc(strlen(encodedLabel) + strlen(secret) + 80);
  char totp = 'h';
  if (use_totp) {
    totp = 't';
  }
  sprintf(url, "otpauth://%cotp/%s?secret=%s", totp, encodedLabel, secret);
  if (encoderURL) {
    const char *encoder = "https://www.google.com/chart?chs=200x200&"
                          "chld=M|0&cht=qr&chl=";
    const char *encodedURL = urlEncode(url);
    
    *encoderURL = strcat(strcpy(malloc(strlen(encoder) +
                                       strlen(encodedURL) + 1),
                                encoder), encodedURL);
    free((void *)encodedURL);
  }
  free((void *)encodedLabel);
  return url;
}
Example #14
0
static STSStatus compute_signature(char* buffer, uint32_t bufferSize,
                            char* paramsArray[], const uint32_t paramsCount,
                            const char* accessKeySecret)
{
    
    //////////////////////////////////////////////////////////////////////////
    // sign
    uint32_t canonLen = 0;

    char canonicalizedQueryString[2048 * 3];
    compose_canonicalized_query_string(canonicalizedQueryString, 2048 * 3, &canonLen,
                                       paramsArray, paramsCount);
    
    string_buffer(strToSign, 2048 * 3);
    string_buffer_initialize(strToSign);
    int fit;
    string_buffer_append(strToSign, "POST&%2F&", 9, fit);
    if (!fit) {
        return STSStatusUriTooLong;
    }
    
    string_buffer(percentTwice, 2048 * 3);
    string_buffer_initialize(percentTwice);
    percentEncode(percentTwice, canonicalizedQueryString, canonLen);
    string_buffer_append(strToSign, percentTwice, strlen(percentTwice), fit);

    //fprintf(stdout, "strToSign(%lu): %s\n", strlen(strToSign), strToSign); 
    
    // Generate an HMAC-SHA-1 of the strToSign
    size_t akSecretLen = strlen(accessKeySecret);
    char newAccessKeySecret[akSecretLen + 1];
    snprintf(newAccessKeySecret, akSecretLen+2, "%s&", accessKeySecret);
    
    unsigned char hmac[20];
    STS_HMAC_SHA1(hmac, (unsigned char *) newAccessKeySecret, strlen(newAccessKeySecret),
              (unsigned char *) strToSign, strlen(strToSign));
    
    // Now base-64 encode the results
    char b64[((20 + 1) * 4) / 3];
    int b64Len = base64Encode(hmac, 20, b64);

    char b64Encoded[256];
    if (!urlEncode(b64Encoded, b64, b64Len)) {
        return STSStatusUriTooLong;
    }
    
    snprintf(buffer, strlen(b64Encoded)+1, "%s", b64Encoded);
    
    return STSStatusOK;
    
}
void UltimateLyricsProvider::doUrlReplace(const QString &tag, const QString &value, QString &u) const
{
    if (!u.contains(tag)) {
        return;
    }

    // Apply URL character replacement
    QString valueCopy(value);
    for (const UltimateLyricsProvider::UrlFormat& format: urlFormats) {
        QRegExp re("[" + QRegExp::escape(format.first) + "]");
        valueCopy.replace(re, format.second);
    }
    u.replace(tag, urlEncode(valueCopy), Qt::CaseInsensitive);
}
std::string ChannelController::createLogoUrl(const cChannel* channel, const std::string& baseUrl) {
    if(baseUrl.empty()) {
        return "";
    }

    std::string filename = createServiceReference(channel);

    if(baseUrl.size() > 4 && baseUrl.substr(0, 4) == "http") {
        filename = urlEncode(filename);
    }

    cString piconurl = AddDirectory(baseUrl.c_str(), filename.c_str());
    return (const char*)cString::sprintf("%s.png", (const char*)piconurl);
}
static const char *getURL(const char *secret, const char *label,
                          char **encoderURL, const int use_totp, const char *issuer) {
  const char *encodedLabel = urlEncode(label);
  char *url;
  char totp = use_totp ? 't' : 'h';
  if (asprintf(&url, "otpauth://%cotp/%s?secret=%s", totp, encodedLabel, secret) < 0) {
    fprintf(stderr, "String allocation failed, probably running out of memory.\n");
    _exit(1);
  }

  if (issuer != NULL && strlen(issuer) > 0) {
    // Append to URL &issuer=<issuer>
    const char *encodedIssuer = urlEncode(issuer);
    char *newUrl;
    if (asprintf(&newUrl, "%s&issuer=%s", url, encodedIssuer) < 0) {
      fprintf(stderr, "String allocation failed, probably running out of memory.\n");
      _exit(1);
    }
    free((void *)encodedIssuer);
    free(url);
    url = newUrl;
  }

  if (encoderURL) {
    // Show a QR code.
    const char *encoder = "https://www.google.com/chart?chs=200x200&"
                          "chld=M|0&cht=qr&chl=";
    const char *encodedURL = urlEncode(url);

    *encoderURL = strcat(strcpy(malloc(strlen(encoder) +
                                       strlen(encodedURL) + 1),
                                encoder), encodedURL);
    free((void *)encodedURL);
  }
  free((void *)encodedLabel);
  return url;
}
Example #18
0
void Client::logCmd(const QString &line)
{
  QCryptographicHash	md5sum(QCryptographicHash::Md5);
  QSettings		settings;

  if (line != NS_CMD_END)
    {
      _lastCmd = NO_CMD;
      return;
    }
  settings.beginGroup("account");
  md5sum.addData(_hash.toAscii());
  md5sum.addData("-");
  md5sum.addData(_host.toAscii());
  md5sum.addData("/");
  md5sum.addData(_port.toAscii() + settings.value("password").toString().toAscii());
  sendMessage(QString(NS_USR_LOG)
	      + ' ' + settings.value("username").toString()
	      + ' ' + md5sum.result().toHex()
	      + ' ' + urlEncode(settings.value("location").toString())
	      + ' ' + urlEncode(settings.value("comment").toString()));
  _lastCmd = NB_USR_LOG;
  settings.endGroup();
}
Example #19
0
void translate(char *s) {

	CURL *handle=curl_easy_init();
	char url[2000]={'\0'};
	urlEncode(s);
	sprintf(url,"%s%s","http://rednaks.alwaysdata.net/translate/?text=",s);
	if (handle){

		curl_easy_setopt(handle,CURLOPT_URL,url);
		curl_easy_perform(handle);
		curl_easy_cleanup(handle);

	}
	//printf("le texte est :%s ",s);
	else 
		printf("erreur lors de l'initialisation de la fonction curl_easy_init()\n");
		
}
Example #20
0
void Http::findHtmlName(std::string& table, std::string& request) {
	const char* ptable = table.c_str(); 
	std::string value;
	std::string encodeValue;

	const char* begin = NULL;
	const char* end = NULL;
	const char* res = NULL;
	while (true) {
		if (begin = strstr(ptable, "<")) {
			if (end = strstr(begin, ">")) {
				std::string str(begin, end);
				if ((str.size() < 10)) {
					ptable = end;
					continue;
				}
				res = findHtmlValue(str.c_str(), "name=\"", request);
				if (res == NULL) {
					ptable = end;
					continue;
				}
				request += "=";
				value.clear();
				encodeValue.clear();
				if (str.find("textarea") == std::string::npos) {
					findHtmlValue(res, "value=\"", value);
				}
				else {
					value = "写的真好";
				}
				urlEncode(value, encodeValue);
				request += encodeValue;
				request += "&";
			}
			else {
				break;
			}
		}
		else {
			break;
		}
		ptable = end;
	}
}
Example #21
0
void
HTGAvatarView::postTweet()
{
	std::string replyMsg( "" );
	std::string replyId( "" );
	std::string postMsg = urlEncode(fMessage->Text());
	if( twitObj->statusUpdate(postMsg, replyId) )  {
		printf( "Status update: OK\n" );
		twitObj->getLastWebResponse(replyMsg);
		int errorStart = replyMsg.find("<error>");
		int errorEnd = replyMsg.find("<\error>");
		if(errorStart-errorEnd > 0)
			HTGErrorHandling::displayError(replyMsg.substr(errorStart, errorEnd-errorStart).c_str());
		else { // Send "status updated" to parent, so we can refresh timelines
			BMessage* statusUpdated = new BMessage(STATUS_UPDATED);
			statusUpdated->AddString("content", fMessage->Text());
			fParent->MessageReceived(statusUpdated);
		}
	}
Example #22
0
 char *buildHeader(char *Xhost, char *Xpath,char *Xscript, char *exeCmd)
 {
  char Header[5196];

  sprintf( Header,
  	   "GET %s/%s?configdir=%s HTTP/1.1\r\n"
	   "Accept: text/xml,application/xml,application/xhtml+xml,"
	   "text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,"
	   "image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1\r\n"
	   "Accept-Language: en-us\r\n"
	   "Accept-Encoding: deflate, gzip\r\n"
	   "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; FunWebProducts)\r\n"
	   "Host: %s\r\n"
	   "Connection: Keep-Alive\r\n"
	   "Cache-Control: no-cache\r\n"
	   "\r\n"
	   , Xpath, Xscript, urlEncode(exeCmd), Xhost );
  return Header;
 }
/**
 *
 * @param host
 * @param url
 * @param keyvalues
 * @param data_count
 * @param url_encode  Perfom URL Encode on Data before POST
 * @note
 *      POST Data is in form key1=value1&key2=value2
 *      where value[] could be url_encoded or not
 * @return
 */
bool AdafruitHTTP::post_internal(char const * host, char const *url, const char* keyvalues[][2], uint16_t count, bool url_encode)
{
  printf(HTTP_METHOD_POST " %s " HTTP_VERSION, url); println();
  printf("Host: %s", host); println();

  // Determine the total data length
  uint16_t total_len = 0;
  for(uint16_t i = 0; i<count; i++)
  {
    total_len += (strlen(keyvalues[i][0]) + 1) + (url_encode ? urlEncodeLength(keyvalues[i][1]) : strlen(keyvalues[i][1]));
  }
  total_len += count-1; // number of "&" between each key=value

  // Send all headers
  sendHeaders( total_len );

  // send data
  for(uint16_t i = 0; i<count; i++)
  {
    if (i != 0) print("&");

    char const* key   = keyvalues[i][0];
    char const* value = keyvalues[i][1];

    print(key); print("=");

    if (url_encode)
    {
      uint16_t bufsize = urlEncodeLength(value)+1;
      char* encoded_value = (char*) malloc(bufsize);
      urlEncode(value, encoded_value, bufsize);
      print(encoded_value);
      free(encoded_value);
    }else
    {
      print(value);
    }
  }

  println();
  flush();
}
/**
 * Encode URL with keys and values, both are passed in an 2-dimension array
 * @param keys_values  2-dimension Array of key (index 0) & value (index 1)
 * @param output  Result in format
 *                key1=encoded(value1)&key2=encoded(value2)&.....
 * @param bufsize Buffer size of output
 *
 * @note If either a key or value is NULL, that pair will be skipped in the encoding result as if
 * it is not existed.
 * @return number of bytes in output string, 0 if failed (possibly not enough memory in output)
 */
uint16_t AdafruitHTTP::urlEncode(const char* keys_values[][2], uint16_t count, char* output, uint16_t bufsize)
{
  uint16_t total_bytes = 0;

  for(uint16_t i=0; i<count && total_bytes < bufsize-1; i++)
  {
    char const * key   = keys_values[i][0];
    char const * value = keys_values[i][1];

    // skip NULL key or value
    if ( key && value )
    {
      if (i != 0) output[total_bytes++] = '&';
      uint16_t n = urlEncode(&key, &value, 1, output+total_bytes, bufsize-total_bytes);
      if (n == 0) return 0; // failed to encode

      total_bytes += n;
    }
  }

  output[total_bytes] = 0;

  return total_bytes;
}
Example #25
0
// URL encodes the params->key value into params->urlEncodedKey
static S3Status encode_key(const RequestParams *params,
                           RequestComputedValues *values)
{
    return (urlEncode(values->urlEncodedKey, params->key, S3_MAX_KEY_SIZE) ?
            S3StatusOK : S3StatusUriTooLong);
}
Example #26
0
S3Status S3_generate_authenticated_query_string
    (char *buffer, const S3BucketContext *bucketContext,
     const char *key, int64_t expires, const char *resource)
{
#define MAX_EXPIRES (((int64_t) 1 << 31) - 1)
    // S3 seems to only accept expiration dates up to the number of seconds
    // representably by a signed 32-bit integer
    if (expires < 0) {
        expires = MAX_EXPIRES;
    }
    else if (expires > MAX_EXPIRES) {
        expires = MAX_EXPIRES;
    }

    // xxx todo: rework this so that it can be incorporated into shared code
    // with request_perform().  It's really unfortunate that this code is not
    // shared with request_perform().

    // URL encode the key
    char urlEncodedKey[S3_MAX_KEY_SIZE * 3];
    if (key) {
        urlEncode(urlEncodedKey, key, strlen(key));
    }
    else {
        urlEncodedKey[0] = 0;
    }

    // Compute canonicalized resource
    char canonicalizedResource[MAX_CANONICALIZED_RESOURCE_SIZE];
    canonicalize_resource(bucketContext->bucketName, resource, urlEncodedKey,
                          canonicalizedResource);
                          
    // We allow for:
    // 17 bytes for HTTP-Verb + \n
    // 1 byte for empty Content-MD5 + \n
    // 1 byte for empty Content-Type + \n
    // 20 bytes for Expires + \n
    // 0 bytes for CanonicalizedAmzHeaders
    // CanonicalizedResource
    char signbuf[17 + 1 + 1 + 1 + 20 + sizeof(canonicalizedResource) + 1];
    int len = 0;

#define signbuf_append(format, ...)                             \
    len += snprintf(&(signbuf[len]), sizeof(signbuf) - len,     \
                    format, __VA_ARGS__)

    signbuf_append("%s\n", "GET"); // HTTP-Verb
    signbuf_append("%s\n", ""); // Content-MD5
    signbuf_append("%s\n", ""); // Content-Type
    signbuf_append("%llu\n", (unsigned long long) expires);
    signbuf_append("%s", canonicalizedResource);

    // Generate an HMAC-SHA-1 of the signbuf
    unsigned char hmac[20];

    HMAC_SHA1(hmac, (unsigned char *) bucketContext->secretAccessKey,
              strlen(bucketContext->secretAccessKey),
              (unsigned char *) signbuf, len);

    // Now base-64 encode the results
    char b64[((20 + 1) * 4) / 3];
    int b64Len = base64Encode(hmac, 20, b64);

    // Now urlEncode that
    char signature[sizeof(b64) * 3];
    urlEncode(signature, b64, b64Len);

    // Finally, compose the uri, with params:
    // ?AWSAccessKeyId=xxx[&Expires=]&Signature=xxx
    char queryParams[sizeof("AWSAccessKeyId=") + 20 + 
                     sizeof("&Expires=") + 20 + 
                     sizeof("&Signature=") + sizeof(signature) + 1];

    sprintf(queryParams, "AWSAccessKeyId=%s&Expires=%ld&Signature=%s",
            bucketContext->accessKeyId, (long) expires, signature);

    return compose_uri(buffer, S3_MAX_AUTHENTICATED_QUERY_STRING_SIZE,
                       bucketContext, urlEncodedKey, resource, queryParams);
}
// . sets m_qbuf1[] and m_qbuf2[]
// . m_qbuf1[] is the advanced query
// . m_qbuf2[] is the query to be used for spell checking
// . returns false and set g_errno on error
bool SearchInput::setQueryBuffers ( HttpRequest *hr ) {

	m_sbuf1.reset();
	m_sbuf2.reset();
	m_sbuf3.reset();

	short qcs = csUTF8;
	if (m_queryCharset && m_queryCharsetLen){
		// we need to convert the query string to utf-8
		qcs = get_iana_charset(m_queryCharset, m_queryCharsetLen);
		if (qcs == csUnknown) {
			//g_errno = EBADCHARSET;
			//g_msg = "(error: unknown query charset)";
			//return false;
			qcs = csUTF8;
		}
	}
	// prepend sites terms
	long numSites = 0;
	char *csStr = NULL;
	numSites = 0;
	csStr = get_charset_str(qcs);

	/*
	if ( m_sites && m_sites[0] ) {
		char *s = m_sites;
		char *t;
		long  len;
		m_sbuf1.pushChar('(');// *p++ = '(';
	loop:
		// skip white space
		while ( *s && ! is_alnum_a(*s) ) s++;
		// bail if done
		if ( ! *s ) goto done;
		// get length of it
		t = s;
		while ( *t && ! is_wspace_a(*t) ) t++;
		len = t - s;
		// add site: term
		//if ( p + 12 + len >= pend ) goto toobig;
		if ( numSites > 0 ) m_sbuf1.safeStrcpy ( " UOR " );
		m_sbuf1.safeStrcpy ( "site:" );
		//p += ucToUtf8(p, pend-p,s, len, csStr, 0,0);
		m_sbuf1.safeMemcpy ( s , len );
		//memcpy ( p , s , len     ); p += len;
		// *p++ = ' ';
		m_sbuf1.pushChar(' ');
		s = t;
		numSites++;
		goto loop;
	done:
		m_sbuf1.safePrintf(") | ");
		// inc totalLen
		m_sitesQueryLen = m_sitesLen + (numSites * 10);
	}
	*/

	// prepend
	char *qp = hr->getString("prepend",NULL,NULL);
	if( qp && qp[0] ) {
		//if( p > pstart ) *p++ =  ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		//p += sprintf( p, "+gblang:%li |", m_gblang );
		m_sbuf1.safePrintf( "%s", qp );
	}

	// append site: term
	if ( m_siteLen > 0 ) {
		//if ( p > pstart ) *p++ = ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		//memcpy ( p , "+site:" , 6 ); p += 6;
		m_sbuf1.safePrintf("+site:");
		//memcpy ( p , m_site , m_siteLen ); p += m_siteLen;
		m_sbuf1.safeMemcpy(m_site,m_siteLen);
	}

	if ( m_familyFilter ) {
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		m_sbuf1.safePrintf("gbisadult:0 | ");
	}

	// append gblang: term
	if( m_gblang > 0 ) {
		//if( p > pstart ) *p++ =  ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		//p += sprintf( p, "+gblang:%li |", m_gblang );
		m_sbuf1.safePrintf( "+gblang:%li |", m_gblang );
	}
	// bookmark here so we can copy into st->m_displayQuery below
	//long displayQueryOffset = m_sbuf1.length();
	// append url: term
	if ( m_urlLen > 0 ) {
		//if ( p > pstart ) *p++ = ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		//memcpy ( p , "+url:" , 5 ); p += 5;
		m_sbuf1.safeStrcpy ( "+url:");
		//memcpy ( p , m_url , m_urlLen ); p += m_urlLen;
		m_sbuf1.safeMemcpy ( m_url , m_urlLen );
	}
	// append url: term
	if ( m_linkLen > 0 ) {
		//if ( p > pstart ) *p++ = ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		//memcpy ( p , "+link:" , 6 ); p += 6;
		m_sbuf1.safeStrcpy ( "+link:");
		//memcpy ( p , m_link , m_linkLen ); p += m_linkLen;
		m_sbuf1.safeMemcpy ( m_link , m_linkLen );
	}
	// append the natural query
	if ( m_queryLen > 0 ) {
		//if ( p  > pstart  ) *p++  = ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		//p += ucToUtf8(p, pend-p, m_query, m_queryLen, csStr, 0,0);
		m_sbuf1.safeMemcpy ( m_query , m_queryLen );
		//memcpy ( p  , m_query , m_queryLen ); p  += m_queryLen;
		// add to spell checked buf, too		
		//if ( p2 > pstart2 ) *p2++ = ' ';
		if ( m_sbuf2.length() ) m_sbuf2.pushChar(' ');
		//p2 +=ucToUtf8(p2, pend2-p2, m_query, m_queryLen, csStr, 0,0);
		m_sbuf2.safeMemcpy ( m_query , m_queryLen );
		//memcpy ( p2 , m_query , m_queryLen ); p2 += m_queryLen;
	}
	if ( m_query2Len > 0 ) {
		//if ( p3 > pstart3 ) *p3++ = ' ';
		if ( m_sbuf3.length() ) m_sbuf3.pushChar(' ');
		//p3+=ucToUtf8(p3, pend3-p3, m_query2, m_query2Len, csStr,0,0);
		m_sbuf3.safeMemcpy ( m_query2 , m_query2Len );
	}
	//if (g_errno == EILSEQ){ // illegal character seq
	//	log("query: bad char set");
	//	g_errno = 0;
	//	if (qcs == csUTF8) {qcs = csISOLatin1;goto doOver;}
	//	if (qcs != csISOLatin1) {qcs = csUTF8;goto doOver;}
	//}
	// append quoted phrases to query
	if ( m_quoteLen1 > 0 ) {
		//if ( p  > pstart  ) *p++  = ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		//*p++ = '+';
		//*p++ = '\"';
		m_sbuf1.safeStrcpy("+\"");
		//p += ucToUtf8(p, pend-p, m_quote1, m_quoteLen1, csStr, 0,0);
		m_sbuf1.safeMemcpy ( m_quote1 , m_quoteLen1 );
		//memcpy ( p , m_quote1 , m_quoteLen1 ); p += m_quoteLen1 ;
		//*p++ = '\"';
		m_sbuf1.safeStrcpy("\"");
		// add to spell checked buf, too
		//if ( p2 > pstart2 ) *p2++ = ' ';
		if ( m_sbuf2.length() ) m_sbuf2.pushChar(' ');
		//*p2++ = '+';
		//*p2++ = '\"';
		m_sbuf2.safeStrcpy("+\"");
		//p2+=ucToUtf8(p2, pend2-p2, m_quote1, m_quoteLen1, csStr,0,0);
		m_sbuf2.safeMemcpy ( m_quote1 , m_quoteLen1 );
		//memcpy ( p2 , m_quote1 , m_quoteLen1 ); p2 += m_quoteLen1 ;
		//*p2++ = '\"';
		m_sbuf2.safeStrcpy("\"");
	}
	//if (g_errno == EILSEQ){ // illegal character seq
	//	g_errno = 0;
	//	if (qcs == csUTF8) {qcs = csISOLatin1;goto doOver;}
	//	if (qcs != csISOLatin1) {qcs = csUTF8;goto doOver;}
	//}
	if ( m_quoteLen2 > 0 ) {
		//if ( p  > pstart  ) *p++  = ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		//*p++ = '+';
		//*p++ = '\"';
		m_sbuf1.safeStrcpy("+\"");
		//p += ucToUtf8(p, pend-p, m_quote2, m_quoteLen2, csStr, 0,0);
		m_sbuf1.safeMemcpy ( m_quote2 , m_quoteLen2 );
		//memcpy ( p , m_quote2 , m_quoteLen2 ); p += m_quoteLen2 ;
		//*p++ = '\"';
		m_sbuf1.safeStrcpy("\"");
		// add to spell checked buf, too
		//if ( p2 > pstart2 ) *p2++ = ' ';
		if ( m_sbuf2.length() ) m_sbuf2.pushChar(' ');
		//*p2++ = '+';
		//*p2++ = '\"';
		m_sbuf2.safeStrcpy("+\"");
		//p2+=ucToUtf8(p2, pend2-p2, m_quote2, m_quoteLen2, csStr,0,0);
		m_sbuf2.safeMemcpy ( m_quote2 , m_quoteLen2 );
		//memcpy ( p2 , m_quote2 , m_quoteLen2 ); p2 += m_quoteLen2 ;
		//*p2++ = '\"';
		m_sbuf2.safeStrcpy("\"");
	}
	//if (g_errno == EILSEQ){ // illegal character seq
	//	g_errno = 0;
	//	if (qcs == csUTF8) {qcs = csISOLatin1;goto doOver;}
	//	if (qcs != csISOLatin1) {qcs = csUTF8;goto doOver;}
	//}

	// append plus terms
	if ( m_plusLen > 0 ) {
		char *s = m_plus;
		char *send = m_plus + m_plusLen;
		//if ( p > pstart && p < pend ) *p++  = ' ';
		//if ( p2 > pstart2 && p2 < pend2) *p2++ = ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		if ( m_sbuf2.length() ) m_sbuf2.pushChar(' ');
		while (s < send) {
			while (isspace(*s) && s < send) s++;
			char *s2 = s+1;
			if (*s == '\"') {
				// if there's no closing quote just treat
				// the end of the line as such
				while (*s2 != '\"' && s2 < send) s2++;
				if (s2 < send) s2++;
			} else {
				while (!isspace(*s2) && s2 < send) s2++;
			}
			if (s2 < send) break;
			//if (p < pend) *p++ = '+';
			//if (p2 < pend2) *p2++ = '+';
			m_sbuf1.pushChar('+');
			m_sbuf2.pushChar('+');
			//p += ucToUtf8(p, pend-p, s, s2-s, csStr, 0,0);
			//p2 += ucToUtf8(p2, pend2-p2, s, s2-s, csStr, 0,0);
			m_sbuf1.safeMemcpy ( s , s2 - s );
			m_sbuf2.safeMemcpy ( s , s2 - s );
			/*
			if (g_errno == EILSEQ) { // illegal character seq
				g_errno = 0;
				if (qcs == csUTF8) {
					qcs = csISOLatin1;
					goto doOver;
				}
				if (qcs != csISOLatin1) {
					qcs = csUTF8;
					goto doOver;
				}
			}
			*/
			s = s2 + 1;
			if (s < send) {
				//if (p < pend) *p++ = ' ';
				//if (p2 < pend2) *p2++ = ' ';
				if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
				if ( m_sbuf2.length() ) m_sbuf2.pushChar(' ');
			}
		}

	}  
	// append minus terms
	if ( m_minusLen > 0 ) {
		char *s = m_minus;
		char *send = m_minus + m_minusLen;
		//if ( p > pstart && p < pend ) *p++  = ' ';
		//if ( p2 > pstart2 && p2 < pend2) *p2++ = ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		if ( m_sbuf2.length() ) m_sbuf2.pushChar(' ');
		while (s < send) {
			while (isspace(*s) && s < send) s++;
			char *s2 = s+1;
			if (*s == '\"') {
				// if there's no closing quote just treat
				// the end of the line as such
				while (*s2 != '\"' && s2 < send) s2++;
				if (s2 < send) s2++;
			} else {
				while (!isspace(*s2) && s2 < send) s2++;
			}
			if (s2 < send) break;
			//if (p < pend) *p++ = '-';
			//if (p2 < pend2) *p2++ = '-';
			m_sbuf1.pushChar('-');
			m_sbuf2.pushChar('-');
			//p += ucToUtf8(p, pend-p, s, s2-s, csStr, 0,0);
			//p2 += ucToUtf8(p2, pend2-p2, s, s2-s, csStr, 0,0);
			m_sbuf1.safeMemcpy ( s , s2 - s );
			m_sbuf2.safeMemcpy ( s , s2 - s );
			/*
			if (g_errno == EILSEQ) { // illegal character seq
				g_errno = 0;
				if (qcs == csUTF8) {
					qcs = csISOLatin1;
					goto doOver;
				}
				if (qcs != csISOLatin1) {
					qcs = csUTF8;
					goto doOver;
				}
			}
			*/
			s = s2 + 1;
			if (s < send) {
				//if (p < pend) *p++ = ' ';
				//if (p2 < pend2) *p2++ = ' ';
				if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
				if ( m_sbuf2.length() ) m_sbuf2.pushChar(' ');
			}
		}
	}
	// append gbkeyword:numinlinks if they have &mininlinks=X, X>0
	long minInlinks = m_hr->getLong("mininlinks",0);
	if ( minInlinks > 0 ) {
		//if ( p > pstart ) *p++ = ' ';
		if ( m_sbuf1.length() ) m_sbuf1.pushChar(' ');
		//char *str = "gbkeyword:numinlinks";
		//long  len = gbstrlen(str);
		//memcpy ( p , str , len );
		//p += len;
		m_sbuf1.safePrintf ( "gbkeyword:numinlinks");
	}

	// null terms
	if ( ! m_sbuf1.pushChar('\0') ) return false;
	if ( ! m_sbuf2.pushChar('\0') ) return false;
	if ( ! m_sbuf3.pushChar('\0') ) return false;

	// the natural query
	m_displayQuery = m_sbuf2.getBufStart();// + displayQueryOffset;

	if ( ! m_displayQuery ) m_displayQuery = "";

	while ( *m_displayQuery == ' ' ) m_displayQuery++;

	m_displayQueryLen = gbstrlen(m_displayQuery);//p-m_displayQuery


	//log("query: got query %s",m_sbuf1.getBufStart());
	//log("query: got display query %s",m_displayQuery);

	// urlencoded display query
	urlEncode(m_qe,
		  MAX_QUERY_LEN*2,
		  m_displayQuery,
		  m_displayQueryLen);
	



	//////////
	//
	// show DMOZ BREADCRUMB if doing a 
	// "gbpcatid:<catid> |" (Search restricted to category)
	// "gbcatid:<catid>"    (DMOZ urls in that topic, c=dmoz3)
	//
	//////////
	long pcatId = -1;
	long dcatId  = -1;
	// get the final query
	char *q =m_sbuf1.getBufStart();

	if ( q ) sscanf(q,"gbpcatid:%li",&pcatId);
	if ( q ) sscanf(q,"gbcatid:%li",&dcatId);
	// pick the one that is valid
	long catId = -1;
	if ( pcatId >= 0 ) catId = pcatId;
	if ( dcatId >= 0 ) catId = dcatId;
	
	//////
	//
	// save catid into the state
	m_catId = catId;
	//
	///////

	// are we a right to left language like hebrew?
	if ( catId > 0 && g_categories->isIdRTL(catId) )
		m_isRTL = true;
	else
		m_isRTL = false;

	return true;
}
int getAuthenticationParams(const char *const SP_URL,
	std::string &strIdpAddress,
	std::string &strSessionIdentifier,
	std::string &strPathSecurityParameters)
{

	std::string  strResult = "";
	EIDCLIENT_CONNECTION_HANDLE connection = 0x00;
	EID_CLIENT_CONNECTION_ERROR connection_status;
	char sz[READ_BUFFER];
	size_t sz_len = sizeof sz;

	connection_status = eIDClientConnectionStartHttp(&connection, SP_URL, NULL, NULL, DontGetHttpHeader, DontFollowHttpRedirect);

	if (connection_status != EID_CLIENT_CONNECTION_ERROR_SUCCESS) {
		printf("%s:%d Error\n", __FILE__, __LINE__);
		return connection_status;
	}
	memset(sz, 0x00, READ_BUFFER);
	connection_status = eIDClientConnectionTransceive(connection, NULL, 0, sz, &sz_len);

	if(connection_status != EID_CLIENT_CONNECTION_ERROR_SUCCESS)
	{
		printf("%s:%d Error\n", __FILE__, __LINE__);
		eIDClientConnectionEnd(connection);
		connection = 0x00;
		return connection_status;
	}

	strResult += std::string(sz, sz_len);
	std::string strTmp = strResult;
	std::transform(strTmp.begin(), strTmp.end(), strTmp.begin(), static_cast<int ( *)(int)>(tolower));
	size_t found = strTmp.find("<html");
	if (found == std::string::npos) {
				printf("%s:%d Error\n", __FILE__, __LINE__);
		return -1;
	}
	strResult = strResult.substr(found);

	eIDClientConnectionEnd(connection);
	connection = 0x00;


	CeIdObject      eIdObject;
	eIdObject.GetParams(strResult);
	std::string strData = "SAMLRequest=";
	//OL-Server wants url-encoded POST-Data..
	urlEncode(eIdObject.m_strSAMLRequest);
	strData += eIdObject.m_strSAMLRequest;
	if(!eIdObject.m_strSigAlg.empty()) {
		strData += "&SigAlg=";
		strData += eIdObject.m_strSigAlg;
	}
	if(!eIdObject.m_strSignature.empty()) {
		strData += "&Signature=";
		strData += eIdObject.m_strSignature;
	}

	if (eIdObject.m_strRelayState.size() > 1) {
		strData += "&RelayState=";
		strData += eIdObject.m_strRelayState;
	}

	strResult = "";
	connection_status = eIDClientConnectionStartHttp(&connection, eIdObject.m_strAction.c_str(), NULL, NULL, DontGetHttpHeader, DontFollowHttpRedirect);

	if (connection_status != EID_CLIENT_CONNECTION_ERROR_SUCCESS) {
		printf("%s:%d Error\n", __FILE__, __LINE__);
		return connection_status;
	}

	memset(sz, 0x00, READ_BUFFER);
	sz_len = sizeof sz;

	connection_status = eIDClientConnectionTransceive(connection, strData.c_str(), strData.size(), sz, &sz_len);

	if(connection_status != EID_CLIENT_CONNECTION_ERROR_SUCCESS)
	{
		printf("%s:%d Error\n", __FILE__, __LINE__);
		return connection_status;
	}

	strResult += std::string(sz, sz_len);

	strTmp = strResult;
	std::transform(strTmp.begin(), strTmp.end(), strTmp.begin(), static_cast<int ( *)(int)>(tolower));
	found = strTmp.find("<html");

	if (found != std::string::npos) {
		strResult = strResult.substr(found);
	} else {
		printf("%s:%d Error\n", __FILE__, __LINE__);
		return -2;
	}

	eIDClientConnectionEnd(connection);
	connection = 0x00;

	std::string response2 = strResult;
	response2 = str_replace("<PSK>", "", response2);
	response2 = str_replace("</PSK>", "", response2);
	response2 = str_replace("&uuml;", "ü", response2);
	response2 = str_replace("&ouml;", "ö", response2);
	eIdObject.GetParams(response2);
	strIdpAddress = eIdObject.m_strServerAddress;
	strSessionIdentifier = eIdObject.m_strSessionID;
	strPathSecurityParameters = eIdObject.m_strPSK;
	strRefresh = eIdObject.m_strRefreshAddress;
	//printf("IdpAddress\t" + strIdpAddress << std::endl;
	//printf("SessionID\t" + strSessionIdentifier << std::endl;
	//printf("PSK\t\t" + strPathSecurityParameters << std::endl;
	//printf("RefreshAddress\t" + strRefresh << std::endl;
	return 0;
}
// returns false if blocked, true otherwise
bool processLoop ( void *state ) {
	// get it
	State2 *st = (State2 *)state;
	// get the tcp socket from the state
	TcpSocket *s = st->m_socket;
	// get it
	XmlDoc *xd = &st->m_xd;

	if ( ! xd->m_loaded ) {
		// setting just the docid. niceness is 0.
		//xd->set3 ( st->m_docId , st->m_coll , 0 );
		// callback
		xd->setCallback ( state , processLoop );
		// . and tell it to load from the old title rec
		// . this sets xd->m_oldTitleRec/m_oldTitleRecSize
		// . this sets xd->ptr_* and all other member vars from
		//   the old title rec if found in titledb.
		if ( ! xd->loadFromOldTitleRec ( ) ) return false;
	}

	if ( g_errno ) return sendErrorReply ( st , g_errno );
	// now force it to load old title rec
	//char **tr = xd->getTitleRec();
	SafeBuf *tr = xd->getTitleRecBuf();
	// blocked? return false if so. it will call processLoop() when it rets
	if ( tr == (void *)-1 ) return false;
	// we did not block. check for error? this will free "st" too.
	if ( ! tr ) return sendErrorReply ( st , g_errno );
	// if title rec was empty, that is a problem
	if ( xd->m_titleRecBuf.length() == 0 ) 
		return sendErrorReply ( st , ENOTFOUND);

	// set callback
	char *na = xd->getIsNoArchive();
	// wait if blocked
	if ( na == (void *)-1 ) return false;
	// error?
	if ( ! na ) return sendErrorReply ( st , g_errno );
	// forbidden? allow turkeys through though...
	if ( ! st->m_isAdmin && *na )
		return sendErrorReply ( st , ENOCACHE );

	SafeBuf *sb = &st->m_sb;


	// &page=4 will print rainbow sections
	if ( ! st->m_printed && st->m_r.getLong("page",0) ) {
		// do not repeat this call
		st->m_printed = true;
		// this will call us again since we called
		// xd->setCallback() above to us
		if ( ! xd->printDocForProCog ( sb , &st->m_r ) )
			return false;
	}

	char *contentType = "text/html";
	char format = st->m_format;
	if ( format == FORMAT_XML ) contentType = "text/xml";
	if ( format == FORMAT_JSON ) contentType = "application/json";

	// if we printed a special page (like rainbow sections) then return now
	if ( st->m_printed ) {
		bool status = g_httpServer.sendDynamicPage (s,
							    //buf,bufLen,
							    sb->getBufStart(),
							    sb->getLength(),
							    -1,false,
							    //"text/html",
							    contentType,
							    -1, NULL, "utf8" );
		// nuke state2
		mdelete ( st , sizeof(State2) , "PageGet1" );
		delete (st);
		return status;
	}

	/*
	  // this was calling XmlDoc and setting sections, etc. to
	  // get the SpiderReply junk... no no no
	// is it banned or filtered? this ignores the TagRec in the titleRec
	// and uses msg8a to get it fresh instead
	char *vi = xd->getIsFiltered();//Visible( );
	// wait if blocked
	if ( vi == (void *)-1 ) return false;
	// error?
	if ( ! vi ) return sendErrorReply ( st , g_errno );
	// banned?
	if ( ! st->m_isAdmin && ! *vi ) return sendErrorReply (st,EDOCBANNED);
	*/

	// get the utf8 content
	char **utf8 = xd->getUtf8Content();
	//long   len  = xd->size_utf8Content - 1;
	// wait if blocked???
	if ( utf8 == (void *)-1 ) return false;
	// strange
	if ( xd->size_utf8Content<=0) {
		log("pageget: utf8 content <= 0");
		return sendErrorReply(st,EBADENGINEER );
	}
	// alloc error?
	if ( ! utf8 ) return sendErrorReply ( st , g_errno );

	// get this host
	Host *h = g_hostdb.getHost ( g_hostdb.m_hostId );
	if ( ! h ) {
		log("pageget: hostid %li is bad",g_hostdb.m_hostId);
		return sendErrorReply(st,EBADENGINEER );
	}


	char *content    = xd->ptr_utf8Content;
	long  contentLen = xd->size_utf8Content - 1;

	// shortcut
	char strip = st->m_strip;

	// alloc buffer now
	//char *buf = NULL;
	//long  bufMaxSize = 0;
	//bufMaxSize = len + ( 32 * 1024 ) ;
	//bufMaxSize = contentLen + ( 32 * 1024 ) ;
	//buf        = (char *)mmalloc ( bufMaxSize , "PageGet2" );
	//char *p          = buf;
	//char *bufEnd     = buf + bufMaxSize;
	//if ( ! buf ) {
	//	return sendErrorReply ( st , g_errno );
	//}

	// for undoing the header
	//char *start1 = p;
	long startLen1 = sb->length();

	// we are always utfu
	if ( strip != 2 )
		sb->safePrintf( "<meta http-equiv=\"Content-Type\" "
			     "content=\"text/html;charset=utf8\">\n");

	// base href
	//Url *base = &xd->m_firstUrl;
	//if ( xd->ptr_redirUrl.m_url[0] )
	//	base = &xd->m_redirUrl;
	char *base = xd->ptr_firstUrl;
	if ( xd->ptr_redirUrl ) base = xd->ptr_redirUrl;
	//Url *redir = *xd->getRedirUrl();
	if ( strip != 2 ) {
		sb->safePrintf ( "<BASE HREF=\"%s\">" , base );
		//p += gbstrlen ( p );
	}

	// default colors in case css files missing
	if ( strip != 2 ) {
		sb->safePrintf( "\n<style type=\"text/css\">\n"
			  "body{background-color:white;color:black;}\n"
			  "</style>\n");
		//p += gbstrlen ( p );
	}

	//char format = st->m_format;
	if ( format == FORMAT_XML ) sb->reset();
	if ( format == FORMAT_JSON ) sb->reset();

	// for undoing the stuff below
	long startLen2 = sb->length();//p;

	// query should be NULL terminated
	char *q    = st->m_q;
	long  qlen = st->m_qlen;

	char styleTitle[128] =  "font-size:14px;font-weight:600;"
				"color:#000000;";
	char styleText[128]  =  "font-size:14px;font-weight:400;"
				"color:#000000;";
	char styleLink[128] =  "font-size:14px;font-weight:400;"
				"color:#0000ff;";
	char styleTell[128] =  "font-size:14px;font-weight:600;"
				"color:#cc0000;";

	// get the url of the title rec
	Url *f = xd->getFirstUrl();

	bool printDisclaimer = st->m_printDisclaimer;

	if ( xd->m_contentType == CT_JSON )
		printDisclaimer = false;

	if ( format == FORMAT_XML ) printDisclaimer = false;
	if ( format == FORMAT_JSON ) printDisclaimer = false;

	char tbuf[100];
	tbuf[0] = 0;
	time_t lastSpiderDate = xd->m_spideredTime;

	if ( printDisclaimer ||
	     format == FORMAT_XML ||
	     format == FORMAT_JSON ) {
		struct tm *timeStruct = gmtime ( &lastSpiderDate );
		strftime ( tbuf, 100,"%b %d, %Y UTC", timeStruct);
	}

	// We should always be displaying this disclaimer.
	// - May eventually want to display this at a different location
	//   on the page, or on the click 'n' scroll browser page itself
	//   when this page is not being viewed solo.
	// CNS: if ( ! st->m_clickNScroll ) {
	if ( printDisclaimer ) {

		sb->safePrintf(//sprintf ( p , 
			  //"<BASE HREF=\"%s\">"
			  //"<table border=1 width=100%%>"
			  //"<tr><td>"
			  "<table border=\"1\" bgcolor=\"#"
			  BGCOLOR
			  "\" cellpadding=\"10\" "
			  //"id=\"gbcnsdisctable\" class=\"gbcnsdisctable_v\""
			  "cellspacing=\"0\" width=\"100%%\" color=\"#ffffff\">"
			  "<tr"
			  //" id=\"gbcnsdisctr\" class=\"gbcnsdisctr_v\""
			  "><td>"
			  //"<font face=times,sans-serif color=black size=-1>"
			  "<span style=\"%s\">"
			  "This is Gigablast's cached page of </span>"
			  "<a href=\"%s\" style=\"%s\">%s</a>"
			  "" , styleTitle, f->getUrl(), styleLink,
			  f->getUrl() );
		//p += gbstrlen ( p );
		// then the rest
		//sprintf(p , 
		sb->safePrintf(
			"<span style=\"%s\">. "
			"Gigablast is not responsible for the content of "
			"this page.</span>", styleTitle );
		//p += gbstrlen ( p );

		sb->safePrintf ( "<br/><span style=\"%s\">"
			  "Cached: </span>"
			  "<span style=\"%s\">",
			  styleTitle, styleText );
		//p += gbstrlen ( p );

		// then the spider date in GMT
		// time_t lastSpiderDate = xd->m_spideredTime;
		// struct tm *timeStruct = gmtime ( &lastSpiderDate );
		// char tbuf[100];
		// strftime ( tbuf, 100,"%b %d, %Y UTC", timeStruct);
		//p += gbstrlen ( p );
		sb->safeStrcpy(tbuf);

		// Moved over from PageResults.cpp
		sb->safePrintf( "</span> - <a href=\""
			      "/get?"
			      "q=%s&amp;c=%s&amp;rtq=%li&amp;"
			      "d=%lli&amp;strip=1\""
			      " style=\"%s\">"
			      "[stripped]</a>", 
			      q , st->m_coll , 
			      (long)st->m_rtq,
			      st->m_docId, styleLink ); 

		// a link to alexa
		if ( f->getUrlLen() > 5 ) {
			sb->safePrintf( " - <a href=\"http:"
					 "//web.archive.org/web/*/%s\""
					 " style=\"%s\">"
					 "[older copies]</a>" ,
					 f->getUrl(), styleLink );
		}

		if (st->m_noArchive){
			sb->safePrintf( " - <span style=\"%s\"><b>"
				     "[NOARCHIVE]</b></span>",
				     styleTell );
		}
		if (st->m_isBanned){
			sb->safePrintf(" - <span style=\"%s\"><b>"
				     "[BANNED]</b></span>",
				     styleTell );
		}

		// only print this if we got a query
		if ( qlen > 0 ) {
			sb->safePrintf("<br/><br/><span style=\"%s\"> "
				   "These search terms have been "
				   "highlighted:  ",
				   styleText );
			//p += gbstrlen ( p );
		}
		
	}

	// how much space left in p?
	//long avail = bufEnd - p;
	// . make the url that we're outputting for (like in PageResults.cpp)
	// . "thisUrl" is the baseUrl for click & scroll
	char thisUrl[MAX_URL_LEN];
	char *thisUrlEnd = thisUrl + MAX_URL_LEN;
	char *x = thisUrl;
	// . use the external ip of our gateway
	// . construct the NAT mapped port
	// . you should have used iptables to map port to the correct
	//   internal ip:port
	//unsigned long  ip   =g_conf.m_mainExternalIp  ; // h->m_externalIp;
	//unsigned short port=g_conf.m_mainExternalPort;//h->m_externalHttpPort
	// local check
	//if ( st->m_isLocal ) {
	unsigned long  ip   = h->m_ip;
	unsigned short port = h->m_httpPort;
	//}
	//sprintf ( x , "http://%s:%li/get?q=" , iptoa ( ip ) , port );
	// . we no longer put the port in here
	// . but still need http:// since we use <base href=>
	if (port == 80) sprintf(x,"http://%s/get?q=",iptoa(ip));
	else            sprintf(x,"http://%s:%hu/get?q=",iptoa(ip),port);
	x += gbstrlen ( x );
	// the query url encoded
	long elen = urlEncode ( x , thisUrlEnd - x , q , qlen );
	x += elen;
	// separate cgi vars with a &
	//sprintf ( x, "&seq=%li&rtq=%lid=%lli",
	//	  (long)st->m_seq,(long)st->m_rtq,st->m_msg22.getDocId());
	sprintf ( x, "&d=%lli",st->m_docId );
	x += gbstrlen(x);		
	// set our query for highlighting
	Query qq;
	qq.set2 ( q, st->m_langId , true );

	// print the query terms into our highlight buffer
	Highlight hi;
	// make words so we can set the scores to ignore fielded terms
	Words qw;
	qw.set ( q            ,  // content being highlighted, utf8
		 qlen         ,  // content being highlighted, utf8
		 TITLEREC_CURRENT_VERSION,
		 true         ,  // computeIds
		 false        ); // hasHtmlEntities?
	// . assign scores of 0 to query words that should be ignored
	// . TRICKY: loop over words in qq.m_qwords, but they should be 1-1
	//   with words in qw.
	// . sanity check
	//if ( qw.getNumWords() != qq.m_numWords ) { char *xx = NULL; *xx = 0;}
	// declare up here
	Matches m;
	// do the loop
	//Scores ss;
	//ss.set ( &qw , NULL );
	//for ( long i = 0 ; i < qq.m_numWords ; i++ )
	//	if ( ! m.matchWord ( &qq.m_qwords[i],i ) ) ss.m_scores[i] = 0;
	// now set m.m_matches[] to those words in qw that match a query word
	// or phrase in qq.
	m.setQuery ( &qq );
	//m.addMatches ( &qw , &ss , true );
	m.addMatches ( &qw );
	long hilen = 0;

	// CNS: if ( ! st->m_clickNScroll ) {
	// and highlight the matches
	if ( printDisclaimer ) {
		hilen = hi.set ( //p       ,
				 //avail   ,
				sb ,
				 &qw     , // words to highlight
				 &m      , // matches relative to qw
				 false   , // doSteming
				 false   , // st->m_clickAndScroll , 
				 (char *)thisUrl );// base url for ClcknScrll
		//p += hilen;
		// now an hr
		//memcpy ( p , "</span></table></table>\n" , 24 );   p += 24;
		sb->safeStrcpy("</span></table></table>\n");
	}


	bool includeHeader = st->m_includeHeader;

	// do not show header for json object display
	if ( xd->m_contentType == CT_JSON )
		includeHeader = false;

	if ( format == FORMAT_XML ) includeHeader = false;
	if ( format == FORMAT_JSON ) includeHeader = false;

	//mfree(uq, uqCapacity, "PageGet");
	// undo the header writes if we should
	if ( ! includeHeader ) {
		// including base href is off by default when not including
		// the header, so the caller must explicitly turn it back on
		if ( st->m_includeBaseHref ) sb->m_length=startLen2;//p=start2;
		else                         sb->m_length=startLen1;//p=start1;
	}

	//sb->safeStrcpy(tbuf);



	if ( format == FORMAT_XML ) {
		sb->safePrintf("<response>\n");
		sb->safePrintf("<statusCode>0</statusCode>\n");
		sb->safePrintf("<statusMsg>Success</statusMsg>\n");
		sb->safePrintf("<url><![CDATA[");
		sb->cdataEncode(xd->m_firstUrl.m_url);
		sb->safePrintf("]]></url>\n");
		sb->safePrintf("<docId>%llu</docId>\n",xd->m_docId);
		sb->safePrintf("\t<cachedTimeUTC>%lu</cachedTimeUTC>\n",
			      lastSpiderDate);
		sb->safePrintf("\t<cachedTimeStr>%s</cachedTimeStr>\n",tbuf);
	}

	if ( format == FORMAT_JSON ) {
		sb->safePrintf("{\"response\":{\n");
		sb->safePrintf("\t\"statusCode\":0,\n");
		sb->safePrintf("\t\"statusMsg\":\"Success\",\n");
		sb->safePrintf("\t\"url\":\"");
		sb->jsonEncode(xd->m_firstUrl.m_url);
		sb->safePrintf("\",\n");
		sb->safePrintf("\t\"docId\":%llu,\n",xd->m_docId);
		sb->safePrintf("\t\"cachedTimeUTC\":%lu,\n",lastSpiderDate);
		sb->safePrintf("\t\"cachedTimeStr\":\"%s\",\n",tbuf);
	}

	// identify start of <title> tag we wrote out
	char *sbstart = sb->getBufStart();
	char *sbend   = sb->getBufEnd();
	char *titleStart = NULL;
	char *titleEnd   = NULL;
	for ( char *t = sbstart ; t < sbend ; t++ ) {
		// title tag?
		if ( t[0]!='<' ) continue;
		if ( to_lower_a(t[1])!='t' ) continue;
		if ( to_lower_a(t[2])!='i' ) continue;
		if ( to_lower_a(t[3])!='t' ) continue;
		if ( to_lower_a(t[4])!='l' ) continue;
		if ( to_lower_a(t[5])!='e' ) continue;
		// point to it
		char *x = t + 5;
		// max - to keep things fast
		char *max = x + 500;
		for ( ; *x && *x != '>' && x < max ; x++ );
		x++;
		// find end
		char *e = x;
		for ( ; *e && e < max ; e++ ) {
			if ( e[0]=='<' &&
			     to_lower_a(e[1])=='/' &&
			     to_lower_a(e[2])=='t' &&
			     to_lower_a(e[3])=='i' &&
			     to_lower_a(e[4])=='t' &&
			     to_lower_a(e[5])=='l' &&
			     to_lower_a(e[6])=='e' )
				break;
		}
		if ( e < max ) {
			titleStart = x;
			titleEnd   = e;
		}
		break;
	}

	// . print title at top!
	// . consider moving
	if ( titleStart ) {

		char *ebuf = st->m_r.getString("eb");
		if ( ! ebuf ) ebuf = "";

		//p += sprintf ( p , 
		sb->safePrintf(
			       "<table border=1 "
			       "cellpadding=10 "
			       "cellspacing=0 "
			       "width=100%% "
			       "color=#ffffff>" );

		long printLinks = st->m_r.getLong("links",0);

		if ( ! printDisclaimer && printLinks )
			sb->safePrintf(//p += sprintf ( p , 
				       // first put cached and live link
				       "<tr>"
				       "<td bgcolor=lightyellow>"
				       // print cached link
				       //"<center>"
				       "&nbsp; "
				       "<b>"
				       "<a "
				       "style=\"font-size:18px;font-weight:600;"
				       "color:#000000;\" "
				       "href=\""
				       "/get?"
				       "c=%s&d=%lli&qh=0&cnsp=1&eb=%s\">"
				       "cached link</a>"
				       " &nbsp; "
				       "<a "
				       "style=\"font-size:18px;font-weight:600;"
				       "color:#000000;\" "
				       "href=%s>live link</a>"
				       "</b>"
				       //"</center>"
				       "</td>"
				       "</tr>\n"
				       ,st->m_coll
				       ,st->m_docId 
				       ,ebuf
				       ,thisUrl // st->ptr_ubuf
				       );

		if ( printLinks ) {
			sb->safePrintf(//p += sprintf ( p ,
				       "<tr><td bgcolor=pink>"
				       "<span style=\"font-size:18px;"
				       "font-weight:600;"
				       "color:#000000;\">"
				       "&nbsp; "
				       "<b>PAGE TITLE:</b> "
				       );
			long tlen = titleEnd - titleStart;
			sb->safeMemcpy ( titleStart , tlen );
			sb->safePrintf ( "</span></td></tr>" );
		}

		sb->safePrintf( "</table><br>\n" );

	}

	// is the content preformatted?
	bool pre = false;
	char ctype = (char)xd->m_contentType;
	if ( ctype == CT_TEXT ) pre = true ; // text/plain
	if ( ctype == CT_DOC  ) pre = true ; // filtered msword
	if ( ctype == CT_PS   ) pre = true ; // filtered postscript

	if ( format == FORMAT_XML ) pre = false;
	if ( format == FORMAT_JSON ) pre = false;

	// if it is content-type text, add a <pre>
	if ( pre ) {//p + 5 < bufEnd && pre ) {
		sb->safePrintf("<pre>");
		//p += 5;
	}

	if ( st->m_strip == 1 )
		contentLen = stripHtml( content, contentLen, 
					(long)xd->m_version, st->m_strip );
	// it returns -1 and sets g_errno on error, line OOM
	if ( contentLen == -1 ) {
		//if ( buf ) mfree ( buf , bufMaxSize , "PageGet2" );	
		return sendErrorReply ( st , g_errno );
	}

	Xml xml;
	Words ww;

	// if no highlighting, skip it
	bool queryHighlighting = st->m_queryHighlighting;
	if ( st->m_strip == 2 ) queryHighlighting = false;

	// do not do term highlighting if json
	if ( xd->m_contentType == CT_JSON )
		queryHighlighting = false;

	SafeBuf tmp;
	SafeBuf *xb = sb;
	if ( format == FORMAT_XML ) xb = &tmp;
	if ( format == FORMAT_JSON ) xb = &tmp;
	

	if ( ! queryHighlighting ) {
		xb->safeMemcpy ( content , contentLen );
		//p += contentLen ;
	}
	else {
		// get the content as xhtml (should be NULL terminated)
		//Words *ww = xd->getWords();
		if ( ! xml.set ( content , contentLen , false ,
				 0 , false , TITLEREC_CURRENT_VERSION ,
				 false , 0 , CT_HTML ) ) { // niceness is 0
			//if ( buf ) mfree ( buf , bufMaxSize , "PageGet2" );
			return sendErrorReply ( st , g_errno );
		}			
		if ( ! ww.set ( &xml , true , 0 ) ) { // niceness is 0
			//if ( buf ) mfree ( buf , bufMaxSize , "PageGet2" );
			return sendErrorReply ( st , g_errno );
		}
		// sanity check
		//if ( ! xd->m_wordsValid ) { char *xx=NULL;*xx=0; }
		// how much space left in p?
		//avail = bufEnd - p;

		Matches m;
		m.setQuery ( &qq );
		m.addMatches ( &ww );
		hilen = hi.set ( xb , // p , avail , 
				 &ww , &m ,
				 false /*doStemming?*/ ,  
				 st->m_clickAndScroll , 
				 thisUrl /*base url for click & scroll*/);
		//p += hilen;
		log(LOG_DEBUG, "query: Done highlighting cached page content");
	}


	if ( format == FORMAT_XML ) {
		sb->safePrintf("\t<content><![CDATA[");
		sb->cdataEncode ( xb->getBufStart() );
		sb->safePrintf("]]></content>\n");
		sb->safePrintf("</response>\n");
	}

	if ( format == FORMAT_JSON ) {
		sb->safePrintf("\t\"content\":\"\n");
		sb->jsonEncode ( xb->getBufStart() );
		sb->safePrintf("\"\n}\n}\n");
	}


	// if it is content-type text, add a </pre>
	if ( pre ) { // p + 6 < bufEnd && pre ) {
		sb->safeMemcpy ( "</pre>" , 6 );
		//p += 6;
	}

	// calculate bufLen
	//long bufLen = p - buf;

	long ct = xd->m_contentType;

	// now filter the entire buffer to escape out the xml tags
	// so it is displayed nice
	SafeBuf newbuf;

	if ( ct == CT_XML ) {
		// encode the xml tags into &lt;tagname&gt; sequences
		if ( !newbuf.htmlEncodeXmlTags ( sb->getBufStart() ,
						 sb->getLength(),
						 0)){// niceness=0
			//if ( buf ) mfree ( buf , bufMaxSize , "PageGet2" );
			return sendErrorReply ( st , g_errno );
		}
		// free out buffer that we alloc'd before returning since this
		// should have copied it into another buffer
		//if ( buf ) mfree ( buf , bufMaxSize , "PageGet2" );	
		// reassign
		//buf    = newbuf.getBufStart();
		//bufLen = newbuf.length();
		sb->stealBuf ( &newbuf );
	}

	// now encapsulate it in html head/tail and send it off
	// sendErr:
	contentType = "text/html";
	if ( strip == 2 ) contentType = "text/xml";
	// xml is usually buggy and this throws browser off
	//if ( ctype == CT_XML ) contentType = "text/xml";

	if ( xd->m_contentType == CT_JSON )
		contentType = "application/json";

	if ( format == FORMAT_XML ) contentType = "text/xml";
	if ( format == FORMAT_JSON ) contentType = "application/json";

	// safebuf, sb, is a member of "st" so this should copy the buffer
	// when it constructs the http reply, and we gotta call delete(st)
	// AFTER this so sb is still valid.
	bool status = g_httpServer.sendDynamicPage (s,
						    //buf,bufLen,
						    sb->getBufStart(),
						    sb->getLength(),
						    -1,false,
						    contentType,
						     -1, NULL, "utf8" );

	// nuke state2
	mdelete ( st , sizeof(State2) , "PageGet1" );
	delete (st);


	// free out buffer that we alloc'd before returning since this
	// should have copied it into another buffer

	//if      ( ct == CT_XML ) newbuf.purge();
	//else if ( buf          ) mfree ( buf , bufMaxSize , "PageGet2" );
	
	// and convey the status
	return status;
}
Example #30
0
File: URI.cpp Project: 4nkh/rhodes
String URI::urlEncode(const String& fullPath)
{
    String res;
    urlEncode(fullPath, res);
    return res;
}