/* Web Polygraph http://www.web-polygraph.org/
* (C) 2003-2006 The Measurement Factory
* Licensed under the Apache License, Version 2.0 */
#include "base/polygraph.h"
#include "xstd/h/iostream.h"
#include "xstd/h/iomanip.h"
#include "xstd/NetAddr.h"
#include "base/RndPermut.h"
#include "base/AddrParsers.h"
#include "base/ObjId.h"
#include "runtime/httpHdrs.h"
#include "runtime/HostMap.h"
#include "csm/ContentCfg.h"
#include "csm/ContentMgr.h"
#include "csm/ContentSel.h"
#include "csm/oid2Url.h"
static
void oidDumpHttpHost(const NetAddr &host, ostream &os) {
if (host.port() == 80)
os << host.addrA();
else
os << host;
}
NetAddr Oid2UrlHost(const ObjId &oid) {
if (oid.foreignUrl()) {
const char *furi = oid.foreignUrl().data();
NetAddr host;
if (Should(SkipHostInUri(furi, furi+oid.foreignUrl().len(), host)))
return host;
} else
if (Should(oid.viserv() >= 0)) {
const HostCfg *host = TheHostMap->at(oid.viserv());
if (Should(host))
return host->theAddr;
}
return NetAddr();
}
ostream &Oid2UrlHost(const ObjId &oid, ostream &os) {
const NetAddr host = Oid2UrlHost(oid);
if (host)
oidDumpHttpHost(host, os);
else
if (oid.foreignUrl())
os << '?';
else
os << oid.viserv();
return os;
}
ostream &Oid2UrlPath(const ObjId &oid, ostream &os) {
if (oid.foreignUrl()) {
const char *p = 0;
if ((p = oid.foreignUrl().chr(':'))) { // proto
while (*++p == '/');
} else {
p = oid.foreignUrl().cstr();
}
if (const char *path = strchr(p, '/'))
os << path;
else
os << '/';
return os;
}
const ContentCfg *ccfg = 0;
if (oid.type() > 0) {
ccfg = TheContentMgr.get(oid.type());
Assert(ccfg);
}
os << '/';
if (ccfg) {
const int seed = GlbPermut(oid.hash(), rndContentPfx);
if (const String &pfx = ccfg->url_pfx(seed))
os << pfx;
}
os << 'w' << oid.world() << '/';
// use non-default formatting to save space and reduce length variation
{
const ios_fmtflags flags = os.flags();
const char fill = os.fill('0');
os << hex << setfill('0');
os << 't' << setw(2) << oid.type() << '/';
os << '_' << setw(8) << oid.name();
os.fill(fill);
os.flags(flags);
}
if (ccfg) {
const int seed = GlbPermut(oid.hash(), rndContentExt);
if (const String &ext = ccfg->url_ext(seed))
os << ext;
}
return os;
}
ostream &Oid2Url(const ObjId &oid, ostream &os) {
if (oid.foreignUrl())
return os << oid.foreignUrl();
os << "http://";
Oid2UrlHost(oid, os);
Oid2UrlPath(oid, os);
return os;
}
int Oid2ContType(const ObjId &oid) {
Assert(!oid.foreignUrl());
const HostCfg *hcfg = TheHostMap->at(oid.target());
Assert(hcfg);
Assert(hcfg->theContent);
const ContentCfg *ccfg = hcfg->theContent->getDir(oid);
return ccfg->id();
}
bool OidImpliesMarkup(const ObjId &oid, const ContentCfg *cfg) {
String urlSfx = oid.foreignUrl();
if (!urlSfx) {
Assert(cfg); // add code to compute if needed
const int seed = GlbPermut(oid.hash(), rndContentExt);
urlSfx = cfg->url_ext(seed);
}
return urlSfx && (urlSfx.last() == '/' || urlSfx.caseEndsWith("ml", 2));
}
syntax highlighted by Code2HTML, v. 0.9.1