2013-08-02 13:12:24 -07:00
|
|
|
// Copyright Matt Wells Nov 2000
|
|
|
|
|
|
|
|
// . derived from TcpServer
|
|
|
|
// . fill in our own getMsgSize () -- looks for Content-Length:xxx
|
|
|
|
// . fill in our own getMsgPiece() -- looks on disk
|
|
|
|
// . fill in our own putMsgPiece() -- ??? for spidering big files!
|
|
|
|
|
|
|
|
// . all the shit is just a generic non-blocking i/o system
|
|
|
|
// . move data from one file/mem to another file/mem that might be remote
|
|
|
|
//
|
|
|
|
|
|
|
|
//TODO: handle SIG_PIPEs!! use sigaction() ...
|
|
|
|
|
|
|
|
//TODO: first packet should have some file in it, not just MIME hdr (avoid TCP delayed ACKS)
|
|
|
|
|
|
|
|
// TODO: what's TCP_CORK??? it delays sending a packet until it's full
|
|
|
|
// which improves performance quite a bit. unsetting TCP_CORK flushes it.
|
|
|
|
// TODO: investigate sendfile() (copies data between file descriptors)
|
|
|
|
|
2016-03-08 22:14:30 +01:00
|
|
|
#ifndef GB_HTTPSERVER_H
|
|
|
|
#define GB_HTTPSERVER_H
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
#define MAX_DOWNLOADS (MAX_TCP_SOCKS-50)
|
|
|
|
|
|
|
|
#include "TcpServer.h"
|
2016-08-10 18:18:49 +02:00
|
|
|
|
|
|
|
class HttpRequest;
|
2013-08-02 13:12:24 -07:00
|
|
|
|
2014-06-09 12:42:05 -07:00
|
|
|
#define DEFAULT_HTTP_PROTO "HTTP/1.0"
|
|
|
|
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
typedef void (*tcp_callback_t)(void *, TcpSocket *);
|
2017-03-10 11:52:34 +01:00
|
|
|
int32_t getMsgSize(const char *buf, int32_t bufSize, TcpSocket *s);
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
class HttpServer {
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
// reset the tcp server
|
|
|
|
void reset();
|
|
|
|
|
|
|
|
// returns false if initialization was unsuccessful
|
2015-12-21 10:54:25 +01:00
|
|
|
bool init( int16_t port, int16_t sslPort, void handlerWrapper( TcpSocket *s ) = NULL );
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
// . returns false if blocked, true otherwise
|
|
|
|
// . sets errno on error
|
|
|
|
// . supports partial gets with "offset" and "size"
|
|
|
|
// . IMPORTANT: we free read/send bufs of TcpSocket after callback
|
|
|
|
// . IMPORTANT: if you don't like this set s->m_read/sendBuf to NULL
|
|
|
|
// in your callback function
|
|
|
|
// . NOTE: this should always block unless errno is set
|
|
|
|
// . the TcpSocket's callbackData is a file ptr
|
|
|
|
// . replies MUST fit in memory (we have NOT implemented putMsgPiece())
|
|
|
|
// . uses the HTTP partial GET command if size is > 0
|
|
|
|
// . uses regular GET if size is -1
|
|
|
|
// . otherwise uses the HTTP HEAD command
|
|
|
|
// . the document will be in the s->m_readBuf/s->m_bytesRead of "s"
|
|
|
|
// . use Mime class to help parse the readBuf
|
|
|
|
// . timeout is in milliseconds since last read OR write
|
|
|
|
// . this now ensures that the read content is NULL terminated!
|
|
|
|
bool getDoc ( char *url , // Url *url ,
|
2014-11-10 14:45:11 -08:00
|
|
|
int32_t ip ,
|
|
|
|
int32_t offset ,
|
|
|
|
int32_t size ,
|
2013-08-02 13:12:24 -07:00
|
|
|
time_t ifModifiedSince ,
|
|
|
|
void *state ,
|
|
|
|
void (* callback) ( void *state , TcpSocket *s ) ,
|
2014-11-10 14:45:11 -08:00
|
|
|
int32_t timeout , // 60*1000
|
|
|
|
int32_t proxyIp ,
|
|
|
|
int16_t proxyPort,
|
|
|
|
int32_t maxTextDocLen ,
|
|
|
|
int32_t maxOtherDocLen ,
|
2016-05-22 15:24:15 +02:00
|
|
|
const char *userAgent = NULL ,
|
2013-08-02 13:12:24 -07:00
|
|
|
// . say HTTP/1.1 instead of 1.0 so we can communicate
|
|
|
|
// with room alert...
|
|
|
|
// . we do not support 1.1 that is why you should always
|
|
|
|
// use 1.0
|
2016-05-22 15:24:15 +02:00
|
|
|
const char *proto = DEFAULT_HTTP_PROTO , // "HTTP/1.0" ,
|
2013-08-02 13:12:24 -07:00
|
|
|
bool doPost = false ,
|
2016-12-14 11:11:45 +01:00
|
|
|
const char *cookieJar = NULL ,
|
2016-05-22 15:24:15 +02:00
|
|
|
const char *additionalHeader = NULL , // does not include \r\n
|
2013-10-08 18:01:38 -07:00
|
|
|
// specify your own mime and post data here...
|
2016-05-22 15:24:15 +02:00
|
|
|
const char *fullRequest = NULL ,
|
|
|
|
const char *postContent = NULL ,
|
|
|
|
const char *proxyUsernamePwdAuth = NULL );
|
2013-08-02 13:12:24 -07:00
|
|
|
|
2014-11-10 14:45:11 -08:00
|
|
|
bool gotDoc ( int32_t n , TcpSocket *s );
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
// . this is public so requestHandlerWrapper() can call it
|
|
|
|
// . if it returns false "s" will be destroyed w/o a reply
|
|
|
|
void requestHandler ( TcpSocket *s );
|
|
|
|
|
|
|
|
// send an error reply, like "HTTP/1.1 404 Not Found"
|
2016-05-22 15:24:15 +02:00
|
|
|
bool sendErrorReply ( TcpSocket *s, int32_t error, const char *errmsg,
|
2014-11-10 14:45:11 -08:00
|
|
|
int32_t *bytesSent = NULL );
|
2014-07-09 20:32:30 -07:00
|
|
|
bool sendErrorReply ( class GigablastRequest *gr );
|
2014-07-06 14:13:00 -07:00
|
|
|
// xml and json uses this
|
2016-05-22 15:24:15 +02:00
|
|
|
bool sendSuccessReply ( class GigablastRequest *gr, const char *addMsg=NULL);
|
|
|
|
bool sendSuccessReply (TcpSocket *s, char format, const char *addMsg=NULL);
|
2013-08-02 13:12:24 -07:00
|
|
|
// send a "prettier" error reply, formatted in XML if necessary
|
2016-03-01 14:33:24 +01:00
|
|
|
bool sendQueryErrorReply ( TcpSocket *s , int32_t error , const char *errmsg,
|
2013-11-08 18:00:30 -08:00
|
|
|
// FORMAT_HTML=0,FORMAT_XML,FORMAT_JSON
|
|
|
|
char format, int errnum,
|
2016-05-22 15:24:15 +02:00
|
|
|
const char *content=NULL);
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
|
|
|
|
// these are for stopping annoying seo bots
|
2014-11-10 14:45:11 -08:00
|
|
|
void getKey ( int32_t *key, char *kname,
|
|
|
|
char *q , int32_t qlen , int32_t now , int32_t s , int32_t n ) ;
|
|
|
|
void getKeys ( int32_t *key1, int32_t *key2, char *kname1, char *kname2,
|
|
|
|
char *q , int32_t qlen , int32_t now , int32_t s , int32_t n ) ;
|
|
|
|
bool hasPermission ( int32_t ip , HttpRequest *r ,
|
|
|
|
char *q , int32_t qlen , int32_t s , int32_t n ) ;
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
// . used by the HttpPageX.h classes after making their dynamic content
|
|
|
|
// . returns false if blocked, true otherwise
|
|
|
|
// . sets errno on error
|
|
|
|
// . a cacheTime of -2 means browser should not cache when user
|
|
|
|
// is clicking forward or hitting back button OR anytime -- no cache!
|
|
|
|
// . a cacheTime of -1 means browser should not cache when user
|
|
|
|
// is clicking forward, but caching when clicking back button is ok
|
|
|
|
// . a cacheTime of 0 tells browser to use local caching rules
|
2016-05-11 12:05:36 +02:00
|
|
|
bool sendDynamicPage ( TcpSocket *s , const char *page , int32_t pageLen ,
|
2014-11-10 14:45:11 -08:00
|
|
|
int32_t cacheTime = -1 , bool POSTReply = false ,
|
2016-05-11 12:05:36 +02:00
|
|
|
const char *contentType = NULL,
|
2014-11-10 14:45:11 -08:00
|
|
|
int32_t httpStatus = -1,
|
2016-05-22 15:24:15 +02:00
|
|
|
const char *cookie = NULL,
|
|
|
|
const char *charset = NULL ,
|
2013-08-02 13:12:24 -07:00
|
|
|
HttpRequest *hr = NULL );
|
|
|
|
|
|
|
|
// for PageSockets
|
2015-12-21 10:54:25 +01:00
|
|
|
TcpServer *getTcp() {
|
|
|
|
return &m_tcp;
|
|
|
|
}
|
|
|
|
|
|
|
|
TcpServer *getSSLTcp() {
|
|
|
|
return &m_ssltcp;
|
|
|
|
}
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
// we contain our own tcp server
|
|
|
|
TcpServer m_tcp;
|
|
|
|
TcpServer m_ssltcp;
|
|
|
|
|
|
|
|
// cancel the transaction that had this state
|
|
|
|
void cancel ( void *state ) {
|
2016-03-02 23:09:50 +01:00
|
|
|
m_tcp.cancel ( state );
|
2016-05-19 18:37:26 +02:00
|
|
|
}
|
2013-08-02 13:12:24 -07:00
|
|
|
|
2014-11-10 14:45:11 -08:00
|
|
|
int32_t m_maxOpenSockets;
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
//for content-encoding: gzip, we unzip the reply and edit the
|
|
|
|
//header to reflect the new size and encoding
|
|
|
|
TcpSocket *unzipReply(TcpSocket* s);
|
|
|
|
|
2014-09-26 11:06:38 -07:00
|
|
|
float getCompressionRatio() {
|
|
|
|
if ( m_bytesDownloaded )
|
|
|
|
return (float)m_uncompressedBytes/m_bytesDownloaded;
|
|
|
|
else
|
|
|
|
return 0.0;
|
2016-05-19 18:37:26 +02:00
|
|
|
}
|
2013-08-02 13:12:24 -07:00
|
|
|
|
2014-06-09 12:42:05 -07:00
|
|
|
bool processSquidProxyRequest ( TcpSocket *sock, HttpRequest *hr);
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
// private:
|
|
|
|
|
|
|
|
// go ahead and start sending the file ("path") over the socket
|
|
|
|
bool sendReply ( TcpSocket *s , HttpRequest *r , bool isAdmin);
|
|
|
|
|
2016-05-22 15:24:15 +02:00
|
|
|
bool sendReply2 ( const char *mime,
|
2014-11-10 14:45:11 -08:00
|
|
|
int32_t mimeLen ,
|
2016-05-22 15:24:15 +02:00
|
|
|
const char *content,
|
2014-11-10 14:45:11 -08:00
|
|
|
int32_t contentLen ,
|
2013-08-02 13:12:24 -07:00
|
|
|
TcpSocket *s ,
|
|
|
|
bool alreadyCompressed = false ,
|
|
|
|
HttpRequest *hr = NULL) ;
|
|
|
|
|
|
|
|
void *states[MAX_DOWNLOADS];
|
|
|
|
tcp_callback_t callbacks[MAX_DOWNLOADS];
|
|
|
|
|
2014-10-30 13:36:39 -06:00
|
|
|
int64_t m_bytesDownloaded;
|
|
|
|
int64_t m_uncompressedBytes;
|
2013-08-02 13:12:24 -07:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
extern class HttpServer g_httpServer;
|
|
|
|
|
2016-03-08 22:14:30 +01:00
|
|
|
#endif // GB_HTTPSERVER_H
|