PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
happyhttp::Connection Class Reference

#include <happyhttp.h>

Public Member Functions

 Connection (const char *host, int port)
 
 ~Connection ()
 
void setcallbacks (ResponseBegin_CB begincb, ResponseData_CB datacb, ResponseComplete_CB completecb, void *userdata)
 
void connect ()
 
void close ()
 
void pump ()
 
bool outstanding () const
 
void request (const char *method, const char *url, const char *headers[]=0, const unsigned char *body=0, int bodysize=0)
 
void putrequest (const char *method, const char *url)
 
void putheader (const char *header, const char *value)
 
void putheader (const char *header, int numericvalue)
 
void endheaders ()
 
void send (const unsigned char *buf, int numbytes)
 

Protected Attributes

ResponseBegin_CB m_ResponseBeginCB
 
ResponseData_CB m_ResponseDataCB
 
ResponseComplete_CB m_ResponseCompleteCB
 
void * m_UserData
 

Friends

class Response
 

Detailed Description

Definition at line 145 of file happyhttp.h.

Constructor & Destructor Documentation

◆ Connection()

happyhttp::Connection::Connection ( const char *  host,
int  port 
)

Definition at line 229 of file happyhttp.cpp.

229 :
233 m_UserData(0),
234 m_State( IDLE ),
235 m_Host( host ),
236 m_Port( port ),
237 m_Sock(-1)
238{
239}
ResponseBegin_CB m_ResponseBeginCB
Definition happyhttp.h:217
ResponseComplete_CB m_ResponseCompleteCB
Definition happyhttp.h:219
ResponseData_CB m_ResponseDataCB
Definition happyhttp.h:218

◆ ~Connection()

happyhttp::Connection::~Connection ( )

Definition at line 298 of file happyhttp.cpp.

299{
300 close();
301}

References close().

Member Function Documentation

◆ close()

void happyhttp::Connection::close ( )

Definition at line 278 of file happyhttp.cpp.

279{
280#ifdef WIN32
281 if( m_Sock >= 0 )
282 ::closesocket( m_Sock );
283#else
284 if( m_Sock >= 0 )
285 ::close( m_Sock );
286#endif
287 m_Sock = -1;
288
289 // discard any incomplete responses
290 while( !m_Outstanding.empty() )
291 {
292 delete m_Outstanding.front();
293 m_Outstanding.pop_front();
294 }
295}

References close().

Referenced by close(), pump(), and ~Connection().

◆ connect()

void happyhttp::Connection::connect ( )

Definition at line 255 of file happyhttp.cpp.

256{
257 in_addr* addr = atoaddr( m_Host.c_str() );
258 if( !addr )
259 throw Wobbly( "Invalid network address" );
260
261 sockaddr_in address;
262 memset( (char*)&address, 0, sizeof(address) );
263 address.sin_family = AF_INET;
264 address.sin_port = htons( m_Port );
265 address.sin_addr.s_addr = addr->s_addr;
266
267 m_Sock = socket( AF_INET, SOCK_STREAM, 0 );
268 if( m_Sock < 0 )
269 BailOnSocketError( "socket()" );
270
271// printf("Connecting to %s on port %d.\n",inet_ntoa(*addr), port);
272
273 if( ::connect( m_Sock, (sockaddr const*)&address, sizeof(address) ) < 0 )
274 BailOnSocketError( "connect()" );
275}
void BailOnSocketError(const char *context)
Definition happyhttp.cpp:76
struct in_addr * atoaddr(const char *address)

References happyhttp::atoaddr(), happyhttp::BailOnSocketError(), and connect().

Referenced by connect(), and send().

◆ endheaders()

void happyhttp::Connection::endheaders ( )

Definition at line 390 of file happyhttp.cpp.

391{
392 if( m_State != REQ_STARTED )
393 throw Wobbly( "Cannot send header" );
394 m_State = IDLE;
395
396 m_Buffer.push_back( "" );
397
398 string msg;
399 vector< string>::const_iterator it;
400 for( it = m_Buffer.begin(); it != m_Buffer.end(); ++it )
401 msg += (*it) + "\r\n";
402
403 m_Buffer.clear();
404
405// printf( "%s", msg.c_str() );
406 send( (const unsigned char*)msg.c_str(), msg.size() );
407}
void send(const unsigned char *buf, int numbytes)

References send().

Referenced by request(), Test3(), Test4(), and Test5().

◆ outstanding()

bool happyhttp::Connection::outstanding ( ) const
inline

Definition at line 179 of file happyhttp.h.

180 { return !m_Outstanding.empty(); }

Referenced by Test1(), Test2(), Test3(), Test4(), and Test5().

◆ pump()

void happyhttp::Connection::pump ( )

Definition at line 433 of file happyhttp.cpp.

434{
435 if( m_Outstanding.empty() )
436 return; // no requests outstanding
437
438 assert( m_Sock >0 ); // outstanding requests but no connection!
439
440 if( !datawaiting( m_Sock ) )
441 return; // recv will block
442
443 unsigned char buf[ 2048 ];
444 int a = recv( m_Sock, (char*)buf, sizeof(buf), 0 );
445 if( a<0 )
446 BailOnSocketError( "recv()" );
447
448 if( a== 0 )
449 {
450 // connection has closed
451
452 Response* r = m_Outstanding.front();
453 r->notifyconnectionclosed();
454 assert( r->completed() );
455 delete r;
456 m_Outstanding.pop_front();
457
458 // any outstanding requests will be discarded
459 close();
460 }
461 else
462 {
463 int used = 0;
464 while( used < a && !m_Outstanding.empty() )
465 {
466
467 Response* r = m_Outstanding.front();
468 int u = r->pump( &buf[used], a-used );
469
470 // delete response once completed
471 if( r->completed() )
472 {
473 delete r;
474 m_Outstanding.pop_front();
475 }
476 used += u;
477 }
478
479 // NOTE: will lose bytes if response queue goes empty
480 // (but server shouldn't be sending anything if we don't have
481 // anything outstanding anyway)
482 assert( used == a ); // all bytes should be used up by here.
483 }
484}
friend class Response
Definition happyhttp.h:147
bool datawaiting(int sock)

References happyhttp::BailOnSocketError(), close(), happyhttp::Response::completed(), happyhttp::datawaiting(), happyhttp::Response::notifyconnectionclosed(), and happyhttp::Response::pump().

Referenced by Test1(), Test2(), Test3(), Test4(), and Test5().

◆ putheader() [1/2]

void happyhttp::Connection::putheader ( const char *  header,
const char *  value 
)

Definition at line 376 of file happyhttp.cpp.

377{
378 if( m_State != REQ_STARTED )
379 throw Wobbly( "putheader() failed" );
380 m_Buffer.push_back( string(header) + ": " + string( value ) );
381}

Referenced by putheader(), putrequest(), request(), Test3(), Test4(), and Test5().

◆ putheader() [2/2]

void happyhttp::Connection::putheader ( const char *  header,
int  numericvalue 
)

Definition at line 383 of file happyhttp.cpp.

384{
385 char buf[32];
386 sprintf( buf, "%d", numericvalue );
387 putheader( header, buf );
388}
void putheader(const char *header, const char *value)

References putheader().

◆ putrequest()

void happyhttp::Connection::putrequest ( const char *  method,
const char *  url 
)

Definition at line 354 of file happyhttp.cpp.

355{
356 if( m_State != IDLE )
357 throw Wobbly( "Request already issued" );
358
359 m_State = REQ_STARTED;
360
361 char req[ 512 ];
362 sprintf( req, "%s %s HTTP/1.1", method, url );
363 m_Buffer.push_back( req );
364
365 putheader( "Host", m_Host.c_str() ); // required for HTTP1.1
366
367 // don't want any fancy encodings please
368 putheader("Accept-Encoding", "identity");
369
370 // Push a new response onto the queue
371 Response *r = new Response( method, *this );
372 m_Outstanding.push_back( r );
373}

References putheader(), and Response.

Referenced by request(), Test3(), Test4(), and Test5().

◆ request()

void happyhttp::Connection::request ( const char *  method,
const char *  url,
const char *  headers[] = 0,
const unsigned char *  body = 0,
int  bodysize = 0 
)

Definition at line 303 of file happyhttp.cpp.

308{
309
310 bool gotcontentlength = false; // already in headers?
311
312 // check headers for content-length
313 // TODO: check for "Host" and "Accept-Encoding" too
314 // and avoid adding them ourselves in putrequest()
315 if( headers )
316 {
317 const char** h = headers;
318 while( *h )
319 {
320 const char* name = *h++;
321 const char* value = *h++;
322 assert( value != 0 ); // name with no value!
323
324 if( 0==strcasecmp( name, "content-length" ) )
325 gotcontentlength = true;
326 }
327 }
328
329 putrequest( method, url );
330
331 if( body && !gotcontentlength )
332 putheader( "Content-Length", bodysize );
333
334 if( headers )
335 {
336 const char** h = headers;
337 while( *h )
338 {
339 const char* name = *h++;
340 const char* value = *h++;
341 putheader( name, value );
342 }
343 }
344 endheaders();
345
346 if( body )
347 send( body, bodysize );
348
349}
void putrequest(const char *method, const char *url)

References endheaders(), putheader(), putrequest(), and send().

Referenced by Test1(), and Test2().

◆ send()

void happyhttp::Connection::send ( const unsigned char *  buf,
int  numbytes 
)

Definition at line 411 of file happyhttp.cpp.

412{
413// fwrite( buf, 1,numbytes, stdout );
414
415 if( m_Sock < 0 )
416 connect();
417
418 while( numbytes > 0 )
419 {
420#ifdef WIN32
421 int n = ::send( m_Sock, (const char*)buf, numbytes, 0 );
422#else
423 int n = ::send( m_Sock, buf, numbytes, 0 );
424#endif
425 if( n<0 )
426 BailOnSocketError( "send()" );
427 numbytes -= n;
428 buf += n;
429 }
430}

References happyhttp::BailOnSocketError(), connect(), and send().

Referenced by endheaders(), request(), send(), Test3(), Test4(), and Test5().

◆ setcallbacks()

void happyhttp::Connection::setcallbacks ( ResponseBegin_CB  begincb,
ResponseData_CB  datacb,
ResponseComplete_CB  completecb,
void *  userdata 
)

Definition at line 242 of file happyhttp.cpp.

247{
248 m_ResponseBeginCB = begincb;
249 m_ResponseDataCB = datacb;
250 m_ResponseCompleteCB = completecb;
251 m_UserData = userdata;
252}

References m_ResponseBeginCB, m_ResponseCompleteCB, m_ResponseDataCB, and m_UserData.

Referenced by Test1(), Test2(), Test3(), Test4(), and Test5().

Friends And Related Symbol Documentation

◆ Response

friend class Response
friend

Definition at line 147 of file happyhttp.h.

Referenced by putrequest().

Member Data Documentation

◆ m_ResponseBeginCB

ResponseBegin_CB happyhttp::Connection::m_ResponseBeginCB
protected

Definition at line 217 of file happyhttp.h.

Referenced by setcallbacks().

◆ m_ResponseCompleteCB

ResponseComplete_CB happyhttp::Connection::m_ResponseCompleteCB
protected

Definition at line 219 of file happyhttp.h.

Referenced by setcallbacks().

◆ m_ResponseDataCB

ResponseData_CB happyhttp::Connection::m_ResponseDataCB
protected

Definition at line 218 of file happyhttp.h.

Referenced by setcallbacks().

◆ m_UserData

void* happyhttp::Connection::m_UserData
protected

Definition at line 220 of file happyhttp.h.

Referenced by setcallbacks().


The documentation for this class was generated from the following files: