1465 lines
39 KiB
C++
1465 lines
39 KiB
C++
//
|
|
// TO AUTOMATE:
|
|
//
|
|
// instead of inserting default values into input tags in processLoop24()
|
|
// generate an HTTP reply and send it back. we have to use
|
|
// <form enctype=multipart/form-data ...> to support the uploading of images
|
|
// so that each input tag will be it's own Content-Type:... along with
|
|
// a boundary delimeter. make a fake form in the <form> tag in here
|
|
// with that enctype and you can see the multipart formatting.
|
|
//
|
|
|
|
|
|
|
|
#include "gb-include.h"
|
|
|
|
#include "XmlDoc.h"
|
|
#include "HttpServer.h"
|
|
#include "Msg1.h"
|
|
#include "Msg20.h"
|
|
|
|
void processLoop24 ( void *state );
|
|
bool printFilledOutForm ( class State24 *st , char *coll );
|
|
void gotSearchResults ( void *state ) ;
|
|
// from PageEvents.cpp:
|
|
bool printEventTitle ( SafeBuf &sb , Msg20Reply *mr , class State7 *st ) ;
|
|
bool printEventSummary ( SafeBuf &sb , class Msg20Reply *mr , int32_t width ,
|
|
int32_t minusFlags , int32_t requiredFlags ,
|
|
class State7 *st , ExpandedResult *er ,
|
|
int32_t maxChars );
|
|
|
|
// from PageEvents.cpp:
|
|
extern bool sendPageEvents2 ( TcpSocket *s ,
|
|
HttpRequest *hr ,
|
|
SafeBuf *resultsBuf,
|
|
SafeBuf *emailLikedbListBuf,
|
|
void *state ,
|
|
void (* emailCallback)(void *state) ,
|
|
SafeBuf *providedBuf ,
|
|
void *providedState ,
|
|
void (* providedCallback)(void *state) );
|
|
|
|
enum InputType {
|
|
IT_EVENT_TITLE = 1,
|
|
IT_EVENT_DESC = 2,
|
|
IT_EVENT_URL = 3,
|
|
IT_EVENT_START_DATE1 = 4,
|
|
IT_EVENT_END_DATE1 = 5
|
|
};
|
|
|
|
class State24 {
|
|
public:
|
|
|
|
// . put this junk in top left frame
|
|
// . this is the url of the form we have selected
|
|
Url m_formUrl;
|
|
// . for querying the form urls themselves
|
|
// . we treat them as events but index the gbeventform:1 term
|
|
// . TODO: do this later. for now just use a simple input box
|
|
// to set m_formUrl directly
|
|
//Query m_formQuery;
|
|
|
|
TagRec m_tagRec;
|
|
Msg8a m_msg8a;
|
|
|
|
// . print the form itself in the bottom left frame from m_formUrl
|
|
XmlDoc m_formDoc;
|
|
// . this describes the form for m_formUrl
|
|
// . it maps tag hashes to input types, like IT_EVENT_TITLE
|
|
// or IT_EVENT_DESC or IT_EVENT_URL etc.
|
|
// . its is stored in tagdb for the form url
|
|
// . it is a string whose format is like "1:12abef;2:34cd01;..."
|
|
// which is InputType:32bitValue;...
|
|
// . we use these values to make a dropdown menu that popups up
|
|
// over each visible form element when you right-click on it
|
|
// and the default value is the one in m_inputMap.
|
|
SafeBuf m_formInputMap;
|
|
|
|
collnum_t m_collnum;
|
|
|
|
// . put this junk in top right frame. the query PLUS search results.
|
|
// we select the event from the search results to put into the form.
|
|
// . query #1 is for querying events to fill in the forms
|
|
Query m_eventQuery;
|
|
// the location
|
|
SafeBuf m_eventWhere;
|
|
// radius from location in miles
|
|
int32_t m_eventRadius;
|
|
|
|
// then put the event search result pageget.cpp into the
|
|
// bottom right frame.
|
|
int64_t m_formDocId;
|
|
int32_t m_formEventId;
|
|
int32_t m_formClockSet;
|
|
|
|
TcpSocket *m_socket;
|
|
HttpRequest m_hr;
|
|
|
|
SafeBuf m_sb;
|
|
|
|
SafeBuf m_tbuf;
|
|
Msg1 m_msg1;
|
|
RdbList m_tagList;
|
|
|
|
Msg20 m_msg20;
|
|
Msg20Request m_msg20Request;
|
|
};
|
|
|
|
static bool sendErrorReply ( void *state , int32_t err ) {
|
|
// ensure this is set
|
|
if ( ! err ) { char *xx=NULL;*xx=0; }
|
|
// get it
|
|
State24 *st = (State24 *)state;
|
|
// get the tcp socket from the state
|
|
TcpSocket *s = st->m_socket;
|
|
char tmp [ 1024*32 ] ;
|
|
sprintf ( tmp , "<b>had server-side error: %s</b><br>",
|
|
mstrerror(g_errno));
|
|
// nuke state8
|
|
mdelete ( st , sizeof(State24) , "pagesubmit" );
|
|
delete (st);
|
|
// erase g_errno for sending
|
|
//g_errno = 0;
|
|
return g_httpServer.sendErrorReply ( s, err, mstrerror(err) );
|
|
}
|
|
|
|
static bool sendReply ( void *state ) {
|
|
// get it
|
|
State24 *st = (State24 *)state;
|
|
SafeBuf *sb = &st->m_sb;
|
|
// now encapsulate it in html head/tail and send it off
|
|
g_httpServer.sendDynamicPage( st->m_socket ,
|
|
sb->getBufStart(),
|
|
sb->length() ,
|
|
-1, //cachtime
|
|
false ,//postreply?
|
|
NULL, //ctype
|
|
-1 , //httpstatus
|
|
NULL,//cookie
|
|
"utf-8");
|
|
// nuke state8
|
|
mdelete ( st , sizeof(State24) , "pagesubmit" );
|
|
delete (st);
|
|
return true;
|
|
}
|
|
|
|
//static void gotTagRec24 ( void *state ) ;
|
|
|
|
// . returns false if blocked, true otherwise
|
|
// . sets g_errno on error
|
|
// . the event submission tool
|
|
bool sendPageSubmit ( TcpSocket *s , HttpRequest *hr ) {
|
|
|
|
// make a state
|
|
State24 *st = NULL;
|
|
try { st = new (State24); }
|
|
catch ( ... ) {
|
|
g_errno = ENOMEM;
|
|
log("PageParser: new(%i): %s",
|
|
sizeof(State24),mstrerror(g_errno));
|
|
return g_httpServer.sendErrorReply(s,500,
|
|
mstrerror(g_errno));}
|
|
mnew ( st , sizeof(State24) , "PageParser" );
|
|
|
|
// save socket ptr
|
|
st->m_socket = s;
|
|
st->m_hr.copy ( hr );
|
|
|
|
// must be local
|
|
if ( ! hr->isLocal() ) return sendErrorReply(st,ENOTLOCAL);
|
|
|
|
// get the collection
|
|
int32_t collLen;
|
|
char *coll = hr->getString ( "c" , &collLen ,NULL );
|
|
if ( ! coll ) coll = g_conf.m_defaultColl;
|
|
st->m_collnum = g_collectiondb.getCollnum ( coll );
|
|
|
|
// set query
|
|
int32_t eqlen;
|
|
char *eq = hr->getString("q",&eqlen,NULL);
|
|
if ( eq ) st->m_eventQuery.set ( eq , 2 );
|
|
|
|
// form url
|
|
int32_t fulen;
|
|
char *fu = hr->getString("formurl",&fulen,NULL);
|
|
if ( fu ) st->m_formUrl.set(fu);
|
|
|
|
st->m_formDocId = hr->getLongLong("formdocid",0LL);
|
|
st->m_formEventId = hr->getLong("formeventid",0);
|
|
st->m_formClockSet = hr->getLong("formclockset",0);
|
|
|
|
|
|
// use now if its 0
|
|
if ( st->m_formClockSet == 0 )
|
|
st->m_formClockSet = getTimeGlobal();
|
|
|
|
// if we are the form iframe
|
|
if ( hr->getLong("showform",0) )
|
|
// return false if blocked
|
|
return printFilledOutForm ( st , coll );
|
|
|
|
// header
|
|
SafeBuf *sb = &st->m_sb;
|
|
|
|
sb->safePrintf("<meta http-equiv=\"Content-Type\" "
|
|
"content=\"text/html; charset=utf-8\">\n");
|
|
|
|
|
|
/*
|
|
SafeBuf cubuf;
|
|
st->m_hr.getCurrentUrl ( cubuf );
|
|
char *cu = cubuf.getBufStart();
|
|
|
|
// . when this page loads, save the url to tagdb if we should
|
|
// . i took this out since i am tring to do this without mappings
|
|
if ( strstr (cu,"&save=1") ) {
|
|
// make a tagrec
|
|
SafeBuf *tbuf = &st->m_tbuf;
|
|
tbuf->addTag3 ( fu , // mysite
|
|
"eventformurl", // tagname
|
|
getTimeGlobal(), // now
|
|
"bridge",
|
|
0, // ip
|
|
cu ,// data is the url
|
|
RDB_TAGDB );
|
|
// use the list we got
|
|
RdbList *list = &st->m_tagList;
|
|
key128_t startKey;
|
|
key128_t endKey;
|
|
startKey.setMin();
|
|
endKey.setMax();
|
|
// set it from safe buf
|
|
list->set ( tbuf->getBufStart() ,
|
|
tbuf->length() ,
|
|
NULL ,
|
|
0 ,
|
|
(char *)&startKey ,
|
|
(char *)&endKey ,
|
|
-1 ,
|
|
false ,
|
|
false ,
|
|
sizeof(key128_t) );
|
|
// . just use TagRec::m_msg1 now
|
|
// . no, can't use that because tags are added using
|
|
// SafeBuf::addTag() which first pushes the rdbid, so we
|
|
// gotta use msg4
|
|
if ( ! st->m_msg1.addList ( list ,
|
|
RDB_TAGDB ,
|
|
coll ,
|
|
st ,
|
|
gotTagRec24 ,
|
|
false ,
|
|
0 ) ) // st->m_niceness ) )
|
|
return false;
|
|
// . if addTagRecs() doesn't block then sendReply right away
|
|
// . this returns false if blocks, true otherwise
|
|
gotTagRec24 ( st );
|
|
return true;
|
|
}
|
|
|
|
// just get the tag rec otherwise
|
|
TagRec *gr = &st->m_tagRec;
|
|
// lookup tag rec for form url
|
|
if ( ! st->m_msg8a.getTagRec ( &st->m_formUrl ,
|
|
coll,
|
|
true,
|
|
0, // niceness
|
|
st ,
|
|
gotTagRec24 ,
|
|
gr ) )
|
|
return false;
|
|
|
|
gotTagRec24 ( st );
|
|
return true;
|
|
}
|
|
|
|
void gotTagRec24 ( void *state ) {
|
|
|
|
State24 *st = (State24 *)state;
|
|
SafeBuf *sb = &st->m_sb;
|
|
|
|
TagRec *gr = &st->m_tagRec;
|
|
|
|
SafeBuf cubuf;
|
|
st->m_hr.getCurrentUrl ( cubuf );
|
|
char *cu = cubuf.getBufStart();
|
|
|
|
// if we were fetching a tag rec for a form url, let's reload the
|
|
// page then!!
|
|
if ( strstr ( cu,"&reload=1") ) {
|
|
// use the tag rec
|
|
char *newurl = gr->getString( "eventformurl",NULL);
|
|
if ( newurl ) {
|
|
// send a page redirect
|
|
sb->safePrintf("<meta name=redirect value=\"%s\">",
|
|
newurl);
|
|
sendReply(st);
|
|
return;
|
|
}
|
|
}
|
|
*/
|
|
|
|
|
|
sb->safePrintf(//"<td valign=top>"
|
|
"<form name=topform method=post "
|
|
//"enctype=\"multipart/form-data\" "
|
|
"action=/>"
|
|
"<input type=hidden name=form value=1>"
|
|
"<input type=text name=formurl id=formurl "
|
|
"size=100 "
|
|
"value=\"%s\">"
|
|
"<br>"
|
|
//"<input type=file name=stuff>"
|
|
//"<br>"
|
|
//"<input type=submit value=submit>"
|
|
"</form>"
|
|
//"</td>"
|
|
, st->m_formUrl.getUrl() );
|
|
|
|
|
|
// parse these out of the url!
|
|
char *query = "";
|
|
char *location = "";
|
|
int32_t radius = 30;
|
|
|
|
// put in a div that scrolls like an iframe
|
|
sb->safePrintf("<iframe " //<div "
|
|
"id=iframe1 "
|
|
"style=\""
|
|
"width:800px;"
|
|
"height:95%%;"
|
|
"overflow:scroll;"
|
|
"display:inline-block;"
|
|
"\" "
|
|
// make this gk144 so we get the search results from
|
|
// there! we will need to send our msg20 that
|
|
// we use to generate the 2nd iframe to gk144 as well.
|
|
"src=\"http://10.5.54.154:8000/?"
|
|
"forform=1&showpersonal=0&usefbid=0"
|
|
);
|
|
sb->safePrintf("&formurl=");
|
|
sb->urlEncode(st->m_formUrl.getUrl());
|
|
sb->safePrintf("&q=");
|
|
sb->urlEncode ( query );
|
|
sb->safePrintf("&wherebox=");
|
|
sb->urlEncode ( location );
|
|
sb->safePrintf("&radius=%"INT32"\">",radius);
|
|
|
|
sb->safePrintf("</iframe>");
|
|
|
|
// put in a div that scrolls like an iframe
|
|
sb->safePrintf("<iframe " // <div "
|
|
"id=iframe2 "
|
|
"style=\""
|
|
"width:800px;"
|
|
"height:95%%;"
|
|
"overflow:scroll;"
|
|
"display:inline-block;"
|
|
"\" "
|
|
// . make this local for debugging easily!
|
|
// . that way we do not have to keep rolling out
|
|
// changes to the gk144 cluster but we can use
|
|
// its events to populate these forms. HOWEVER
|
|
// it will still need to send its msg20 to gk144,
|
|
// UNLESS we supplied the msg20 here, maybe
|
|
// encoded... let's first try sending the msg20
|
|
// request form titan to gk144 though.
|
|
"src=\"http://10.5.1.203:8000/?form=1&"
|
|
"showform=1&"
|
|
"formdocid=%"INT64"&"
|
|
"formeventid=%"INT32"&"
|
|
"formclockset=%"UINT32"&"
|
|
"formurl="
|
|
, st->m_formDocId
|
|
, st->m_formEventId
|
|
, st->m_formClockSet
|
|
);
|
|
sb->urlEncode(st->m_formUrl.getUrl());
|
|
sb->safePrintf("\">");
|
|
|
|
|
|
|
|
sb->safePrintf("</iframe>");
|
|
|
|
// now encapsulate it in html head/tail and send it off
|
|
sendReply ( st );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool gotMsg20Result ( void *state ) ;
|
|
|
|
// . assume we are an event submission form
|
|
// . print ourselves out into "sb"
|
|
// . detect event form inputs and put a dropdown that shows up on a right
|
|
// click that allows the admin to change the type of input form from
|
|
// what we've detected it to be. i.e. startdate|title|description|...
|
|
bool printFilledOutForm ( State24 *st , char *coll ) {
|
|
|
|
char *fu = st->m_formUrl.getUrl();
|
|
if ( ! fu || ! fu[0] ) {
|
|
g_errno = EBADURL;
|
|
return sendErrorReply ( st , g_errno );
|
|
}
|
|
|
|
//
|
|
// get the event we are putting into the form
|
|
//
|
|
Msg20Request *rr = &st->m_msg20Request;
|
|
rr->reset();
|
|
rr->m_docId = st->m_formDocId;
|
|
rr->m_eventId = st->m_formEventId;
|
|
//rr->ptr_coll = coll;
|
|
//rr->size_coll = gbstrlen(coll)+1;
|
|
// now we are going to gk144, use "main"
|
|
rr->ptr_coll = "main\0";
|
|
rr->size_coll = 5;
|
|
rr->m_callback = gotMsg20Result;
|
|
rr->m_state = st;
|
|
rr->m_getEventSummary = 1;
|
|
|
|
rr->m_clockSet = st->m_formClockSet;
|
|
|
|
// HACK: send to gk144!!! it has all the events, not titan!
|
|
//rr->m_hostIP = atoip("10.5.54.154");
|
|
//rr->m_hostUDPPort = 9000;
|
|
|
|
// send to gk144 cluster
|
|
rr->m_hostdb = &g_hostdb2;
|
|
|
|
// also get the search result we are using to populate this form
|
|
if ( st->m_formDocId > 0 && ! st->m_msg20.getSummary ( rr ) )
|
|
return false;
|
|
|
|
// we got it
|
|
return gotMsg20Result ( st );
|
|
}
|
|
|
|
bool gotMsg20Result ( void *state ) {
|
|
|
|
State24 *st = (State24 *)state;
|
|
|
|
// set this up for passing to XmlDoc::set4()
|
|
SpiderRequest sreq;
|
|
sreq.reset();
|
|
strcpy(sreq.m_url,st->m_formUrl.getUrl());
|
|
int32_t firstIp = hash32n(sreq.m_url);
|
|
sreq.setKey( firstIp, 0LL, false );
|
|
sreq.m_isPageParser = 0; // was 1
|
|
sreq.m_isPageSubmit = 1;
|
|
sreq.m_hopCount = 0;//st->m_hopCount;
|
|
sreq.m_hopCountValid = 1;
|
|
sreq.m_fakeFirstIp = 0;//1;
|
|
sreq.m_firstIp = 0;//firstIp;
|
|
sreq.m_domHash32 = st->m_formUrl.getDomainHash32();
|
|
sreq.m_siteHash32 = st->m_formUrl.getHostHash32();
|
|
|
|
XmlDoc *fd = &st->m_formDoc;
|
|
|
|
//Msg20Request *rr = &st->m_msg20Request;
|
|
|
|
|
|
char *coll = g_collectiondb.getColl(st->m_collnum);
|
|
|
|
// . use the enormous power of our new XmlDoc class
|
|
// . this returns false if blocked
|
|
// . also gets XmlDoc::m_tagRec which contains the input mapping
|
|
if ( ! fd->set4 ( &sreq ,
|
|
NULL ,
|
|
coll ,
|
|
NULL , // pbuf
|
|
1 , // niceness
|
|
NULL , // content
|
|
false , // deletefromindex
|
|
0 , // forced ip
|
|
CT_HTML )) // contentType
|
|
// return error reply if g_errno is set
|
|
return sendErrorReply ( st , g_errno );
|
|
// make this our callback in case something blocks
|
|
fd->setCallback ( st , processLoop24 );
|
|
|
|
processLoop24 ( st );
|
|
// this should always block
|
|
return false;
|
|
}
|
|
|
|
#define FI_VENUE 1
|
|
#define FI_TITLE 2
|
|
#define FI_DESC 3
|
|
#define FI_DATE_START 4
|
|
#define FI_DATE_END 5
|
|
#define FI_DOW 6
|
|
#define FI_URL 7
|
|
#define FI_EMAIL 8
|
|
#define FI_PHONE 9
|
|
#define FI_STREET 10
|
|
#define FI_CITY 11
|
|
#define FI_STATE 12
|
|
#define FI_ZIP 13
|
|
#define FI_COUNTRY 14
|
|
#define FI_TIME_START 15
|
|
#define FI_TIME_END 16
|
|
#define FI_PRICE 17
|
|
#define FI_MY_NAME 18
|
|
#define FI_MY_PHONE 19
|
|
#define FI_MY_EMAIL 20
|
|
#define FI_IMAGE 21
|
|
|
|
void processLoop24 ( void *state ) {
|
|
|
|
// cast it
|
|
State24 *st = (State24 *)state;
|
|
// get the xmldoc
|
|
XmlDoc *fd = &st->m_formDoc;
|
|
|
|
Words *w = fd->getWords();
|
|
// blocked?
|
|
if ( w == (void *)-1 ) return;
|
|
// error?
|
|
if ( ! w ) {
|
|
sendErrorReply ( st , g_errno );
|
|
return;
|
|
}
|
|
Sections *sx = fd->getSections();
|
|
if ( sx == (void *)-1 ) return;
|
|
if ( ! sx ) {
|
|
sendErrorReply ( st , g_errno );
|
|
return;
|
|
}
|
|
|
|
SafeBuf *sb = &st->m_sb;
|
|
sb->safePrintf("<base href=\"%s\">", fd->getFirstUrl()->getUrl() );
|
|
|
|
// is this basically in PageEvents.cpp?
|
|
Msg20Reply *mr = st->m_msg20.getReply();
|
|
|
|
if ( ! mr ) {
|
|
sb->safeMemcpy ( fd->ptr_utf8Content,
|
|
fd->size_utf8Content - 1 );
|
|
sendReply ( st );
|
|
return;
|
|
}
|
|
|
|
// this logic taken from Msg40.cpp!!
|
|
int32_t ni = mr->size_eventDateIntervals/sizeof(Interval);
|
|
Interval *ii = (Interval *)mr->ptr_eventDateIntervals;
|
|
int32_t timeStart = 0;
|
|
int32_t timeEnd = 0;
|
|
for ( int32_t j = 0 ; j < ni ; j++ ) {
|
|
if ( mr->m_prevStart >= 0 &
|
|
(uint32_t)ii[j].m_a <
|
|
(uint32_t)mr->m_prevStart )
|
|
continue;
|
|
if ( ii[j].m_a < st->m_formClockSet ) continue;
|
|
timeStart = ii[j].m_a;
|
|
timeEnd = ii[j].m_b;
|
|
break;
|
|
}
|
|
int32_t start1 = timeStart;
|
|
bool isDST1 = getIsDST (start1,mr->m_timeZoneOffset);
|
|
start1 += mr->m_timeZoneOffset * 3600;
|
|
if ( mr->m_useDST && isDST1 ) start1 += 3600;
|
|
struct tm *timeStruct = gmtime ( &start1 );
|
|
ExpandedResult er;
|
|
er.m_mapi = 0;
|
|
er.m_timeStart = timeStart;
|
|
er.m_timeEnd = timeEnd;
|
|
er.m_dayNum1 = timeStruct->tm_mday;
|
|
er.m_month1 = timeStruct->tm_mon;
|
|
er.m_year1 = timeStruct->tm_year+1900;
|
|
er.m_hour1 = timeStruct->tm_hour;
|
|
er.m_min1 = timeStruct->tm_min;
|
|
er.m_dow1 = timeStruct->tm_wday;
|
|
time_t start2 = timeEnd;
|
|
bool isDST2 = getIsDST (start2,mr->m_timeZoneOffset);
|
|
start2 += mr->m_timeZoneOffset * 3600;
|
|
if ( mr->m_useDST && isDST2 ) start2 += 3600;
|
|
timeStruct = gmtime ( &start2 );
|
|
er.m_dayNum2 = timeStruct->tm_mday;
|
|
er.m_month2 = timeStruct->tm_mon;
|
|
er.m_year2 = timeStruct->tm_year+1900;
|
|
er.m_hour2 = timeStruct->tm_hour;
|
|
er.m_min2 = timeStruct->tm_min;
|
|
er.m_dow2 = timeStruct->tm_wday;
|
|
|
|
|
|
// parse out address (from PageEvents.cpp::printEventAddress)
|
|
char *addr = mr->ptr_eventAddr;
|
|
char *name1 ;
|
|
char *name2 ;
|
|
char *suite ;
|
|
char *street ;
|
|
char *city ;
|
|
char *adm1 ;
|
|
char *zip ;
|
|
char *country;
|
|
double lat,lon;
|
|
// this now makes "city" etc point into a static buffer, beware!
|
|
setFromStr2 ( addr, &name1 , &name2, &suite, &street, &city,
|
|
&adm1, &zip, &country,&lat , &lon );
|
|
|
|
// override with this
|
|
name1 = mr->ptr_eventBestPlaceName;
|
|
|
|
|
|
// get the event display for this event id
|
|
//EventDisplay *ed = fd->getEventDisplay ( st->m_eventId );
|
|
|
|
// use the msg20reply now
|
|
|
|
|
|
//TagRec *gr = &fd->m_tagRec;
|
|
|
|
// print out each word
|
|
int32_t nw = w->getNumWords();
|
|
char **wptrs = w->getWords();
|
|
int32_t *wlens = w->getWordLens();
|
|
int64_t *wids = w->getWordIds();
|
|
nodeid_t *tids = w->getTagIds();
|
|
|
|
for ( int32_t i = 0 ; i < nw ; i++ ) {
|
|
|
|
// if no event selected, skip all this!
|
|
//if ( ! mr ) {
|
|
// sb->safeMemcpy ( wptrs[i], wlens[i] );
|
|
// continue;
|
|
//}
|
|
|
|
//
|
|
// . if its the <form> tag then make sure it goes
|
|
// back to the gbhom/gk144 host and does not use
|
|
// the <base href> tag. that way gk144 can insert the
|
|
// event image into the http reply from the browser before
|
|
// passing it on to the external event form server.
|
|
// we should insert a "formproxy=http://..."
|
|
// input into the form so we know to forward the form reply
|
|
// to that url. and also to substitute in the picture.
|
|
// . we detect "formproxy=..." in pageevents.cpp like we
|
|
// look for "form". see top of sendPageEvents2() which
|
|
// calls sendPageFormProxy() when it sees that.
|
|
// . don't nuke the "url" in this <form> tag, but rather
|
|
// include it as a text input named "formproxy".
|
|
//
|
|
//
|
|
if ( ! strncasecmp(wptrs[i] ,"<form ",6 ) ) {
|
|
// scan up until we hit "action="
|
|
char *as = strncasestr (wptrs[i],wlens[i],"action=");
|
|
// if not there, that is strange!
|
|
if ( ! as ) {
|
|
sb->safeMemcpy ( wptrs[i], wlens[i] );
|
|
continue;
|
|
}
|
|
// int16_tcut
|
|
char *wend = wptrs[i] + wlens[i];
|
|
// skip action=
|
|
as += 7;
|
|
// skip quote
|
|
bool hasQuote = false;
|
|
if ( *as == '\"' ) { hasQuote = true; as++; }
|
|
// now point to original submission url
|
|
char *origUrl = as;
|
|
// find end of that
|
|
char *end = origUrl;
|
|
for ( ; end < wend ; end++ ) {
|
|
if ( hasQuote &&
|
|
*end =='\"' )
|
|
break;
|
|
if ( ! hasQuote &&
|
|
*end !='>' &&
|
|
! is_wspace_a(*end) )
|
|
break;
|
|
}
|
|
// length of the original submission url
|
|
int32_t origUrlLen = end - origUrl;
|
|
// copy up until that
|
|
int32_t leftLen = as - wptrs[i];
|
|
sb->safeMemcpy ( wptrs[i] , leftLen );
|
|
// insert our url so form is submitted to us
|
|
sb->safePrintf("http://10.5.1.203:8000/");
|
|
// end the rest of the form tag
|
|
sb->safeMemcpy ( end , wend - end );
|
|
// put a hidden input tag for us to use
|
|
sb->safePrintf ("<input "
|
|
"type=hidden "
|
|
"name=formproxyto "
|
|
"value=\"");
|
|
// make it absolute if its relative
|
|
if ( strncasecmp(origUrl,"http://",7) &&
|
|
strncasecmp(origUrl,"https://",8) ) {
|
|
char *fu = st->m_hr.getString("formurl",NULL);
|
|
Url uu;
|
|
uu.set ( fu );
|
|
char *us = uu.getUrl();
|
|
int32_t uslen = uu.getUrlLen();
|
|
// hack off filename, if there
|
|
uslen -= uu.getFilenameLen();
|
|
// then prepend to form url
|
|
sb->safeMemcpy(us,uslen);
|
|
}
|
|
// print original url into the submission url as
|
|
// a cgi parm
|
|
sb->safeMemcpy ( origUrl , origUrlLen );
|
|
sb->safePrintf ( "\">");
|
|
// and put the url of the image so we can download
|
|
// it and insert it before returning the final
|
|
// reply to the external event submission server
|
|
sb->safePrintf("<input type=hidden "
|
|
"name=egimgurl value=\"%s\">"
|
|
, mr->ptr_imgUrl
|
|
);
|
|
|
|
// make the facebook thumb into a larger image
|
|
if ( mr->m_eventFlags & EV_FACEBOOK ) {
|
|
char *end = sb->getBuf() - 7;
|
|
if ( *end == 'q' ) *end = 'n';
|
|
}
|
|
|
|
// that's it!
|
|
continue;
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isTextArea = false;
|
|
if ( ! strncasecmp(wptrs[i] ,"<textarea",9)) isTextArea = true;
|
|
|
|
// if not an input tag, just copy over and get next one
|
|
if ( strncasecmp(wptrs[i] ,"<input ",7 ) &&
|
|
// textareas used for descriptions a lot
|
|
! isTextArea ) {
|
|
sb->safeMemcpy ( wptrs[i], wlens[i] );
|
|
continue;
|
|
}
|
|
|
|
// if its hidden skip as well
|
|
if ( strncasestr(wptrs[i] , wlens[i], " type=hidden" ) ) {
|
|
sb->safeMemcpy ( wptrs[i], wlens[i] );
|
|
continue;
|
|
}
|
|
if ( strncasestr(wptrs[i] , wlens[i], " type=\"hidden" ) ) {
|
|
sb->safeMemcpy ( wptrs[i], wlens[i] );
|
|
continue;
|
|
}
|
|
|
|
// now get the sentence previous to this input tag
|
|
Section *ss = sx->m_sectionPtrs[i-1];
|
|
// hit prev unti we got a sentence
|
|
for ( ; ss ; ss = ss->m_prev )
|
|
if ( ss->m_flags & SEC_SENTENCE ) break;
|
|
|
|
// if not sentence forget it!
|
|
if ( ! ss ) {
|
|
sb->safeMemcpy ( wptrs[i], wlens[i] );
|
|
continue;
|
|
}
|
|
|
|
// ok, now scan the words sentence and normalize them
|
|
// into a string
|
|
SafeBuf nb;
|
|
bool lastWasSpace = true;
|
|
for ( int32_t j = ss->m_a ; j < ss->m_b ; j++ ) {
|
|
// punct?
|
|
if ( ! wids[j] ) {
|
|
if ( lastWasSpace ) continue;
|
|
nb.pushChar(' ');
|
|
lastWasSpace = true;
|
|
continue;
|
|
}
|
|
// skip isolated s like "Day(s) of week"
|
|
if ( wlens[j] == 1 && to_lower_a(wptrs[j][0])=='s' )
|
|
continue;
|
|
// ignore this ("content photo")
|
|
if ( !strncasecmp(wptrs[j],"content",wlens[j]) )
|
|
continue;
|
|
if ( !strncasecmp(wptrs[j],"event",wlens[j]) )
|
|
continue;
|
|
// word?
|
|
nb.safeMemcpy ( wptrs[j], wlens[j] );
|
|
lastWasSpace = false;
|
|
}
|
|
|
|
// convert to lower case
|
|
//sb.toLowerUtf8();
|
|
|
|
// now get that buf
|
|
char *s = nb.getBufStart();
|
|
if ( nb.length() <= 0 ) s = NULL;
|
|
|
|
// if no words before it we can't idenfity it, so just
|
|
// print the input tag here and continue
|
|
if ( ! s ) {
|
|
sb->safeMemcpy ( wptrs[i],wlens[i]);
|
|
continue;
|
|
}
|
|
|
|
int32_t flags = 0;
|
|
|
|
// look for indicative phrases
|
|
if ( ! strcasecmp(s,"venue name") ) flags = FI_VENUE;
|
|
if ( ! strcasecmp(s,"location") ) flags = FI_VENUE;
|
|
|
|
if ( ! strcasecmp(s,"name") ) flags = FI_TITLE;
|
|
if ( ! strcasecmp(s,"title") ) flags = FI_TITLE;
|
|
|
|
if ( ! strcasecmp(s,"int16_t description") ) flags = FI_DESC;
|
|
// mm/dd/yy
|
|
if ( ! strcasecmp(s,"start date") ) flags = FI_DATE_START;
|
|
// mm/dd/yy
|
|
if ( ! strcasecmp(s,"end date") ) flags = FI_DATE_END;
|
|
// day of week
|
|
if ( ! strcasecmp(s,"day of week") ) flags = FI_DOW;
|
|
|
|
if ( ! strcasecmp(s,"website") ) flags = FI_URL;
|
|
if ( ! strcasecmp(s,"website or map") ) flags = FI_URL;
|
|
if ( ! strcasecmp(s,"url") ) flags = FI_URL;
|
|
|
|
if ( ! strcasecmp(s,"email") ) flags = FI_EMAIL;
|
|
|
|
if ( ! strcasecmp(s,"main phone number") ) flags = FI_PHONE;
|
|
if ( ! strcasecmp(s,"main phone") ) flags = FI_PHONE;
|
|
if ( ! strcasecmp(s,"phone") ) flags = FI_PHONE;
|
|
|
|
if ( ! strcasecmp(s,"address") ) flags = FI_STREET;
|
|
|
|
if ( ! strcasecmp(s,"city") ) flags = FI_CITY;
|
|
if ( ! strcasecmp(s,"town") ) flags = FI_CITY;
|
|
if ( ! strcasecmp(s,"city town") ) flags = FI_CITY;
|
|
if ( ! strcasecmp(s,"town city") ) flags = FI_CITY;
|
|
|
|
if ( ! strcasecmp(s,"state") ) flags = FI_STATE;
|
|
|
|
if ( ! strcasecmp(s,"zip") ) flags = FI_ZIP;
|
|
|
|
if ( ! strcasecmp(s,"country") ) flags = FI_COUNTRY;
|
|
|
|
if ( ! strcasecmp(s,"time") ) flags = FI_TIME_START;
|
|
|
|
if ( ! strcasecmp(s,"admission") ) flags = FI_PRICE;
|
|
if ( ! strcasecmp(s,"price") ) flags = FI_PRICE;
|
|
if ( ! strcasecmp(s,"ticket admission") ) flags = FI_PRICE;
|
|
if ( ! strcasecmp(s,"ticket price") ) flags = FI_PRICE;
|
|
if ( ! strcasecmp(s,"ticket cost") ) flags = FI_PRICE;
|
|
|
|
if ( ! strcasecmp(s,"your name") ) flags = FI_MY_NAME;
|
|
if ( ! strcasecmp(s,"organized by") ) flags = FI_MY_NAME;
|
|
if ( ! strcasecmp(s,"your phone number") ) flags = FI_MY_PHONE;
|
|
|
|
if ( ! strcasecmp(s,"your email address") ) flags =FI_MY_EMAIL;
|
|
if ( ! strcasecmp(s,"your email") ) flags = FI_MY_EMAIL;
|
|
|
|
|
|
if ( ! strcasecmp(s,"image") ) flags = FI_IMAGE;
|
|
if ( ! strcasecmp(s,"photo") ) flags = FI_IMAGE;
|
|
if ( ! strcasecmp(s,"picture") ) flags = FI_IMAGE;
|
|
|
|
SafeBuf vbuf;
|
|
|
|
|
|
// ok, now determine value of the input box
|
|
if ( flags == FI_TITLE ) {
|
|
printEventTitle ( vbuf , mr , NULL );
|
|
}
|
|
|
|
if ( flags == FI_DESC ) {
|
|
printEventSummary ( vbuf ,
|
|
mr ,
|
|
99999 , // width
|
|
EDF_SUBEVENTBROTHER , // donotprint
|
|
0 ,
|
|
NULL , // state
|
|
NULL , // expanded result
|
|
200 ); // maxchars
|
|
}
|
|
|
|
if ( flags == FI_DATE_START ) {
|
|
vbuf.safePrintf("%s %"INT32""
|
|
, getMonthName(er.m_month1)
|
|
, (int32_t)er.m_dayNum1
|
|
);
|
|
}
|
|
|
|
if ( flags == FI_DATE_END ) {
|
|
vbuf.safePrintf("%s %"INT32""
|
|
, getMonthName(er.m_month2)
|
|
, (int32_t)er.m_dayNum2
|
|
);
|
|
}
|
|
|
|
if ( flags == FI_TIME_START ) {
|
|
char *ampm = "am";
|
|
int32_t h = er.m_hour1;
|
|
if ( h == 12 ) ampm = "pm";
|
|
if ( h > 12 ) { ampm = "pm"; h -= 12; }
|
|
vbuf.safePrintf("%"INT32":%02"INT32" %s"
|
|
, (int32_t)h
|
|
, (int32_t)er.m_min1
|
|
, ampm
|
|
);
|
|
}
|
|
|
|
if ( flags == FI_TIME_END ) {
|
|
char *ampm = "am";
|
|
int32_t h = er.m_hour2;
|
|
if ( h == 12 ) ampm = "pm";
|
|
if ( h > 12 ) { ampm = "pm"; h -= 12; }
|
|
vbuf.safePrintf("%"INT32":%02"INT32" %s"
|
|
, (int32_t)h
|
|
, (int32_t)er.m_min2
|
|
, ampm
|
|
);
|
|
}
|
|
|
|
if ( flags == FI_URL ) {
|
|
// make event guru url
|
|
vbuf.safePrintf("http://www.eventguru.com/?id=%"UINT64"."
|
|
"%"UINT64""
|
|
, mr->m_docId
|
|
, mr->m_eventHash64
|
|
);
|
|
}
|
|
|
|
if ( flags == FI_EMAIL ) {
|
|
// make event guru url
|
|
vbuf.safePrintf("guru@eventguru.com");
|
|
}
|
|
|
|
if ( flags == FI_STREET && street ) {
|
|
vbuf.safePrintf("%s",street);
|
|
}
|
|
|
|
if ( flags == FI_CITY && city) {
|
|
vbuf.safePrintf("%s",city);
|
|
}
|
|
|
|
if ( flags == FI_STATE && adm1 ) {
|
|
vbuf.safePrintf("%s",adm1);
|
|
}
|
|
|
|
if ( flags == FI_ZIP && zip ) {
|
|
vbuf.safePrintf("%s",zip);
|
|
}
|
|
|
|
if ( flags == FI_COUNTRY && country ) {
|
|
vbuf.safePrintf("%s",country);
|
|
}
|
|
|
|
if ( flags == FI_VENUE && name1 ) {
|
|
vbuf.safePrintf("%s",name1);
|
|
}
|
|
|
|
if ( flags == FI_MY_NAME ) {
|
|
vbuf.safePrintf("Matt Wells");
|
|
}
|
|
|
|
if ( flags == FI_MY_PHONE ) {
|
|
vbuf.safePrintf("505 450 3518");
|
|
}
|
|
|
|
if ( flags == FI_MY_EMAIL ) {
|
|
vbuf.safePrintf("guru@eventguru.com");
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char *val = vbuf.getBufStart();
|
|
int32_t vlen = vbuf.length();
|
|
if ( vlen <= 0 ) val = NULL;
|
|
|
|
// if no value, just print the input tag with no value
|
|
if ( ! val ) {
|
|
sb->safeMemcpy ( wptrs[i],wlens[i]);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// TEXTAREA logic
|
|
//
|
|
if ( isTextArea ) {
|
|
// finish text area tag
|
|
sb->safeMemcpy ( wptrs[i],wlens[i]);
|
|
// then insert our value
|
|
sb->safeMemcpy ( val , vlen );
|
|
// scan for next </textarea>
|
|
for ( ; i+1 < nw ; i++ ) {
|
|
// stop if it follows next
|
|
if ( tids[i+1] == TAG_TEXTAREA|BACKBIT )
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// . print input box, but not "value="
|
|
// . substitute our own value here
|
|
//
|
|
char *x = wptrs[i];
|
|
char *xend = x + wlens[i];
|
|
bool didIt = false;
|
|
for ( ; x < xend ; x++ ) {
|
|
if ( strncasecmp(x," value=",7) && *x != '>' ) {
|
|
sb->pushChar(*x);
|
|
continue;
|
|
}
|
|
// substitute
|
|
sb->safePrintf(" value=\"");
|
|
sb->safeMemcpy(val,vlen);
|
|
sb->safePrintf("\"");
|
|
didIt = true;
|
|
// end?
|
|
if ( *x == '>' ) {
|
|
sb->pushChar('>');
|
|
break;
|
|
}
|
|
// skip over original val
|
|
x += 6;
|
|
// quote?
|
|
bool inQuote = false;
|
|
if ( *x == '\"' ) { inQuote = true; x++; }
|
|
// skip till space, or quote if in quotes
|
|
for ( ; x < xend ; x++ ) {
|
|
if ( is_wspace_a (*x) && ! inQuote){x--;break;}
|
|
if ( *x == '\"' ) break;
|
|
if ( *x == '>' && ! inQuote ) {x--;break;}
|
|
}
|
|
// ok, its pointing to a space or quote, do not
|
|
// print out that space or quote
|
|
continue;
|
|
}
|
|
|
|
}
|
|
|
|
sendReply ( st );
|
|
}
|
|
|
|
static void gotImage ( void *state , TcpSocket *s ) ;
|
|
|
|
/////////////
|
|
//
|
|
// TAKE THE HTTP REQUEST from the browser meant as an event submission
|
|
// and proxy it to the external event submission server.
|
|
//
|
|
// We do this so we can insert the event image into the supplied HTTP REQUEST.
|
|
//
|
|
// The <input type=file> tag typically has a "filename=\"" string in the
|
|
// POSTed form data. so we just have to insert the image file contents
|
|
// after that.
|
|
//
|
|
/////////////
|
|
|
|
class State27 {
|
|
public:
|
|
TcpSocket *m_socket;
|
|
SafeBuf m_replyBuf;
|
|
SafeBuf m_relayBuf;
|
|
HttpRequest m_hr;
|
|
};
|
|
|
|
static void relayReply ( void *state , TcpSocket *subsock ) ;
|
|
|
|
// . returns false if blocked, true otherwise
|
|
// . sets g_errno on error
|
|
bool sendPageFormProxy ( TcpSocket *s , HttpRequest *hr ) {
|
|
|
|
// must be local
|
|
if ( ! hr->isLocal() ) return sendErrorReply(NULL,ENOTLOCAL);
|
|
|
|
// get the image url
|
|
char *imgUrl = hr->getString ( "egimgurl" , NULL );
|
|
|
|
// the original form submission url, a page on the external
|
|
// event submission server
|
|
char *formUrl = hr->getString ("formproxyto",NULL);
|
|
|
|
// fake it
|
|
//formUrl = "http://www.itsatrip.org/events/submit.aspx";
|
|
|
|
char *req = s->m_readBuf;
|
|
int32_t reqSize = s->m_readOffset;
|
|
int32_t allocSize = s->m_readBufSize;
|
|
|
|
// make a state
|
|
State27 *st = NULL;
|
|
try { st = new (State27); }
|
|
catch ( ... ) {
|
|
g_errno = ENOMEM;
|
|
log("PageParser: new(%i): %s",
|
|
sizeof(State27),mstrerror(g_errno));
|
|
return g_httpServer.sendErrorReply(s,500,
|
|
mstrerror(g_errno));}
|
|
mnew ( st , sizeof(State27) , "PageParser" );
|
|
|
|
// save socket ptr
|
|
st->m_socket = s;
|
|
st->m_hr.copy ( hr );
|
|
|
|
// copy the original reply we need to forward
|
|
st->m_replyBuf.safeMemcpy ( s->m_readBuf ,s->m_readOffset );
|
|
|
|
|
|
// if not there, just proxy it now as it is
|
|
if ( ! imgUrl ) {
|
|
// assume we got one
|
|
gotImage ( st , NULL );
|
|
return false;
|
|
}
|
|
|
|
log("formprox: downloading image %s",imgUrl);
|
|
|
|
g_errno = 0;
|
|
|
|
// re-write it
|
|
//if ( strncasecmp(imgUrl,"https://",8) == 0 ) imgUrl += 8;
|
|
|
|
// otherwise, get the image, scale it and insert it into the
|
|
// post request... look for "filename=\"" as a form element.
|
|
if ( ! g_httpServer.getDoc ( imgUrl ,
|
|
0 , // ip - look it up
|
|
0 , // ofset
|
|
-1 , // size
|
|
0 , // if modified since
|
|
st ,
|
|
gotImage ,
|
|
60000 , // timeout
|
|
0 , // proxyip
|
|
0 , // proxyport
|
|
9999999 , // maxtextdoclen
|
|
9999999 // maxotherdoclen
|
|
))
|
|
return false;
|
|
// must be error
|
|
log("formprox: error downloading image url %s : %s",
|
|
imgUrl,mstrerror(g_errno));
|
|
|
|
// delete state then
|
|
mdelete ( st , sizeof(State27) , "pageprox" );
|
|
delete (st);
|
|
|
|
// prevent it from being freed when we return here
|
|
s->m_readBuf = NULL;
|
|
// use this directly since we are just forwarding the request
|
|
TcpServer *tcp = &g_httpServer.m_tcp;
|
|
// because buffer is now owned by this socket
|
|
if ( ! tcp->sendMsg ( formUrl , // host/port
|
|
req ,
|
|
reqSize ,
|
|
allocSize ,
|
|
reqSize ,
|
|
NULL, // st ,
|
|
NULL,//callback
|
|
60 , // timeout
|
|
999999999 ,// maxtextdoclen
|
|
999999999 // maxotherdoclen
|
|
) )
|
|
return false;
|
|
// it did not block
|
|
return true;
|
|
}
|
|
|
|
static void removeLine ( SafeBuf *rb , char *lineStart ) ;
|
|
static void removeDisposition ( SafeBuf *rb , char *name ) ;
|
|
static void adjustContentLength ( SafeBuf *rb ) ;
|
|
|
|
void gotImage ( void *state , TcpSocket *socket ) {
|
|
// cast it
|
|
State27 *st = (State27 *)state;
|
|
// if image failed!
|
|
if ( g_errno ) {
|
|
hadError:
|
|
log("submit: image download failed: %s",mstrerror(g_errno));
|
|
TcpSocket *s = st->m_socket;
|
|
mdelete ( st , sizeof(State27) , "pageprox" );
|
|
delete (st);
|
|
g_httpServer.sendErrorReply(s,500,mstrerror(g_errno));
|
|
return;
|
|
}
|
|
|
|
// int16_tcut
|
|
SafeBuf *rb = &st->m_replyBuf;
|
|
|
|
HttpMime hm;
|
|
if ( socket ) {
|
|
hm.set ( socket->m_readBuf , socket->m_readOffset , NULL );
|
|
if ( hm.getHttpStatus() != 200 ) {
|
|
g_errno = EBADREPLY; goto hadError;}
|
|
// save it
|
|
SafeBuf imgBuf;
|
|
imgBuf.safeMemcpy ( hm.getContent() , hm.getContentLen() );
|
|
char fn[128];
|
|
sprintf(fn,"/tmp/tmpimg%"UINT32"",getTimeLocal());
|
|
imgBuf.save ( "" , fn );
|
|
// convert it
|
|
char cmd[512];
|
|
sprintf ( cmd , "anytopnm %s > %s-2", fn , fn );
|
|
system ( cmd );
|
|
// scale it
|
|
sprintf ( cmd , "pnmscale -xysize 128 128 %s-2 > %s-3",fn,fn);
|
|
system ( cmd );
|
|
// convert it to png
|
|
sprintf ( cmd , "pnmtopng %s-3 > %s-4.png", fn , fn );
|
|
system ( cmd );
|
|
// load it (tmp/tmpimgxxxxxx4.png)
|
|
imgBuf.purge();
|
|
char fn2[128];
|
|
sprintf(fn2,"/tmp/tmpimg%"UINT32"-4.png",getTimeLocal());
|
|
imgBuf.load ( "" , fn2 );
|
|
// now insert that into the http reply
|
|
char *insertionPoint = strstr(rb->getBufStart(),"filename=\"");
|
|
// skip if can't find it
|
|
if ( ! insertionPoint ) return;
|
|
// skip over filename=\"
|
|
insertionPoint += 10;
|
|
// put our junk there
|
|
int32_t insertPos = insertionPoint - rb->getBufStart();
|
|
rb->insert("img.png", insertPos );
|
|
// find the \r\n\r\n after that point
|
|
char *imgData = strstr(rb->getBufStart()+insertPos,"\r\n\r\n");
|
|
imgData += 4;
|
|
int32_t dataPos = imgData - rb->getBufStart();
|
|
// note it
|
|
log("submit: inserting image of %"INT32" bytes",imgBuf.length());
|
|
// then the image content
|
|
rb->insert2 ( imgBuf.getBufStart() , imgBuf.length(),dataPos );
|
|
}
|
|
|
|
// the original form submission url, a page on the external
|
|
// event submission server
|
|
char *formUrl = st->m_hr.getString ("formproxyto",NULL);
|
|
// now get formurl from the file
|
|
//SafeBuf info;
|
|
//info.loadFromFile2("/tmp/tmpfile",formUrlHash32);
|
|
//char *formUrl = info.getBufStart();
|
|
|
|
// fake it
|
|
//formUrl = "http://www.itsatrip.org/events/submit.aspx";
|
|
|
|
|
|
// now the request buf will be like "POST / HTTP/1.1\r\n...."
|
|
// so we have to replace "/" with "formUrl" which is the original
|
|
// url being submitted to because we had made it our own server ip
|
|
// on the path of "/". so formUrl's path needs to go there.
|
|
char *ourPath = strstr(rb->getBufStart()," / ");
|
|
if ( ! ourPath ) { g_errno = EBADREPLY; goto hadError; }
|
|
ourPath += 1;
|
|
Url ff; ff.set(formUrl);
|
|
char *path = ff.getPath();
|
|
int32_t plen = ff.getPathLen();
|
|
rb->safeReplace ( path , plen , ourPath - rb->getBufStart() , 1 );
|
|
|
|
// replace "Host: 10.5.1.203:8000\r\n" with the right host
|
|
char *host = ff.getHost();
|
|
int32_t hlen = ff.getHostLen();
|
|
char *hostLine = strstr(rb->getBufStart(),"Host: ");
|
|
hostLine += 6;
|
|
char *hostLineEnd = strstr(hostLine,"\r\n");
|
|
if ( ! hostLine || ! hostLineEnd){g_errno = EBADREPLY; goto hadError; }
|
|
int32_t hostLinePos = hostLine - rb->getBufStart();
|
|
int32_t hostLineLen = hostLineEnd - hostLine;
|
|
rb->safeReplace ( host, hlen , hostLinePos, hostLineLen );
|
|
|
|
// remove stuff. otherwise we pass them in cookie from eventguru!
|
|
// and referer is like 10.5.1.203/...
|
|
removeLine ( rb , "Referer: ");
|
|
removeLine ( rb , "Cookie: ");
|
|
|
|
// take out the gzip encoding
|
|
removeLine ( rb , "Accept-Encoding:");
|
|
|
|
// we added these hidden form variables for proxying purposes
|
|
// so we have to remove them now
|
|
removeDisposition ( rb , "formproxyto" );
|
|
removeDisposition ( rb , "egimgurl" );
|
|
|
|
// . now we must adjust the content-length
|
|
// . YEAH, because inserting the image screws this up!!!
|
|
adjustContentLength ( rb );
|
|
|
|
char *req = rb->getBufStart();
|
|
int32_t allocated = rb->getCapacity();
|
|
int32_t reqSize = rb->length();
|
|
rb->detachBuf();
|
|
|
|
// use this directly since we are just forwarding the request
|
|
TcpServer *tcp = &g_httpServer.m_tcp;
|
|
// . because buffer is now owned by this socket
|
|
// . we should relay the reply from the submission server back to
|
|
// our st->m_socket when it comes in!!!
|
|
// . so set the callback to do that
|
|
if ( ! tcp->sendMsg ( formUrl , // host/port
|
|
req,
|
|
allocated,
|
|
reqSize,
|
|
reqSize,
|
|
st ,
|
|
relayReply,//callback
|
|
60 , // timeout
|
|
999999999 ,// maxtextdoclen
|
|
999999999 // maxotherdoclen
|
|
) )
|
|
return;
|
|
// did not block, must have been an error
|
|
relayReply ( st , NULL );
|
|
}
|
|
|
|
void relayReply ( void *state , TcpSocket *subsock ) {
|
|
// cast it
|
|
State27 *st = (State27 *)state;
|
|
// if failed to submit the event
|
|
if ( g_errno || ! subsock ) {
|
|
log("submit: failed to send to submission server: %s",
|
|
mstrerror(g_errno));
|
|
TcpSocket *s = st->m_socket;
|
|
mdelete ( st , sizeof(State27) , "pageprox" );
|
|
delete (st);
|
|
g_httpServer.sendErrorReply(s,500,mstrerror(g_errno));
|
|
return;
|
|
}
|
|
// return reply back as it is
|
|
char *reply = subsock->m_readBuf;
|
|
int32_t replySize = subsock->m_readOffset;
|
|
//int32_t allocSize = subsock->m_readBufSize;
|
|
|
|
// do not double free
|
|
//subsock->m_readBuf = NULL;
|
|
|
|
// copy over
|
|
st->m_relayBuf.safeMemcpy ( reply , replySize );
|
|
|
|
|
|
char *formUrl = st->m_hr.getString ("formproxyto",NULL);
|
|
|
|
char ttt[128+MAX_URL_LEN];
|
|
sprintf(ttt,"<base href=\"%s\">\n",formUrl);
|
|
char *cstart = strstr(st->m_relayBuf.getBufStart(),"\r\n\r\n");
|
|
int32_t cpos;
|
|
if ( cstart ) cstart += 4;
|
|
if ( cstart ) cpos = cstart - st->m_relayBuf.getBufStart();
|
|
// insert the base href tag!
|
|
st->m_relayBuf.insert2 ( ttt,gbstrlen(ttt),cpos );
|
|
// re-set Content-Length
|
|
adjustContentLength ( &st->m_relayBuf );
|
|
|
|
// int16_tcuts
|
|
char *relay = st->m_relayBuf.getBufStart();
|
|
int32_t relaySize = st->m_relayBuf.length();
|
|
int32_t relayAllocSize = st->m_relayBuf.getCapacity();
|
|
|
|
// . let tcpserver free it when done transmitting it
|
|
// . detach after setting "relay" because it sets m_buf to null
|
|
st->m_relayBuf.detachBuf();
|
|
|
|
// . relay the submission server's reply back to the admin
|
|
// . crap this is including the http mime!
|
|
/*
|
|
g_httpServer.sendDynamicPage( st->m_socket ,
|
|
reply ,
|
|
replySize ,
|
|
-1, //cachtime
|
|
false ,//postreply?
|
|
NULL, //ctype
|
|
-1 , //httpstatus
|
|
NULL,//cookie
|
|
"utf-8");
|
|
*/
|
|
// use this directly since we are just forwarding the request
|
|
TcpServer *tcp = &g_httpServer.m_tcp;
|
|
// . because buffer is now owned by this socket
|
|
// . we should relay the reply from the submission server back to
|
|
// our st->m_socket when it comes in!!!
|
|
// . so set the callback to do that
|
|
tcp->sendMsg ( st->m_socket ,
|
|
relay, // st->m_relayBuf.getBufStart(), // reply,
|
|
relayAllocSize,
|
|
relaySize, // replySize,
|
|
relaySize, // replySize,
|
|
NULL , // state
|
|
NULL//callback
|
|
);
|
|
|
|
// nuke it after sendMsg() call so formUrl is valid for it
|
|
mdelete ( st , sizeof(State27) , "pageprox" );
|
|
delete (st);
|
|
}
|
|
|
|
void removeLine ( SafeBuf *rb , char *lineStart ) {
|
|
char *s = rb->getBufStart();
|
|
char *line = strstr(s , lineStart );
|
|
if ( ! line ) return;
|
|
// find end of line
|
|
char *end = line;
|
|
for ( ; *end ; end++ )
|
|
if ( *end == '\r' && end[1] == '\n' ) break;
|
|
// no end?
|
|
if ( ! end ) return;
|
|
end += 2;
|
|
rb->safeReplace ( "" , 0 , line - s , end - line );
|
|
}
|
|
|
|
// name = "formproxyto" etc.
|
|
// \r\n\r\n", '-' <repeats 29 times>, "148434662416964166751880432549\r\nContent-Disposition: form-data; name=\"formproxyto\"\r\n\r\nhttp://www.itsatrip.org/events/submit.aspx\r\n", '-' <repeats 29 times>, "148434662416964166751880432549
|
|
void removeDisposition ( SafeBuf *rb , char *name ) {
|
|
|
|
char *start = rb->getBufStart();
|
|
|
|
char *f = strstr(start,name);
|
|
|
|
if ( ! f ) return;
|
|
|
|
// back up to start of "Content-Disposition:" line
|
|
char *b = f;
|
|
for ( ; b > start ; b-- )
|
|
if ( !strncasecmp(b,"Content-Disposition:",20)) break;
|
|
if ( b == start ) return;
|
|
|
|
// now go forward until next Content-Disposition: line
|
|
char *next = f;
|
|
for ( ; *next ; next++ )
|
|
if ( !strncasecmp(next,"Content-Disposition:",20)) break;
|
|
if ( ! *next ) return;
|
|
|
|
// nuke that
|
|
rb->safeReplace ( "" , 0 , b - start , next - b );
|
|
}
|
|
|
|
void adjustContentLength ( SafeBuf *rb ) {
|
|
|
|
char *start = rb->getBufStart();
|
|
|
|
char *f = strstr(start,"Content-Length:");
|
|
if ( ! f ) return;
|
|
|
|
// skip to number
|
|
for ( ; *f ; f++ ) {
|
|
if ( is_digit(*f) ) break;
|
|
}
|
|
|
|
// find start of content
|
|
char *cs = strstr(start,"\r\n\r\n");
|
|
if ( ! cs ) return;
|
|
cs += 4;
|
|
int32_t headerLen = cs - start;
|
|
//int32_t clen = gbstrlen(cs);
|
|
int32_t clen = rb->length() - headerLen;
|
|
|
|
// find length of number, nd = # of digits
|
|
int32_t nd = 0;
|
|
char *fe = f;
|
|
for ( ; *fe ; fe++ ) {
|
|
if ( ! is_digit(*fe) ) break;
|
|
nd++;
|
|
}
|
|
|
|
// write that out
|
|
char format[64];
|
|
sprintf(format,"%%0%"INT32"li",nd);
|
|
char ttt[32];
|
|
int32_t toPrint = sprintf(ttt,format,clen);
|
|
// just copy it over, padded with zeroes
|
|
gbmemcpy ( f , ttt , toPrint );
|
|
}
|