コード例 #1
0
ファイル: httpd.c プロジェクト: MassimilianoPinto/MaxScale
/**
 * Read event for EPOLLIN on the httpd protocol module.
 *
 * @param dcb	The descriptor control block
 * @return
 */
static int
httpd_read_event(DCB* dcb)
{
//SESSION		*session = dcb->session;
//ROUTER_OBJECT	*router = session->service->router;
//ROUTER		*router_instance = session->service->router_instance;
//void		*rsession = session->router_session;

int numchars = 1;
char buf[HTTPD_REQUESTLINE_MAXLEN-1] = "";
char *query_string = NULL;
char method[HTTPD_METHOD_MAXLEN-1] = "";
char url[HTTPD_SMALL_BUFFER] = "";
int cgi = 0;
size_t i, j;
int headers_read = 0;
HTTPD_session *client_data = NULL;

	client_data = dcb->data;

	/**
	 * get the request line
	 * METHOD URL HTTP_VER\r\n
	 */

	numchars = httpd_get_line(dcb->fd, buf, sizeof(buf));

	i = 0; j = 0;
	while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) {
		method[i] = buf[j];
		i++; j++;
	}
	method[i] = '\0';

	strcpy(client_data->method, method);

	/* check allowed http methods */
	if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) {
		//httpd_unimplemented(dcb->fd);
		return 0;
	}

	if (strcasecmp(method, "POST") == 0)
		cgi = 1;

	i = 0;

	while (ISspace(buf[j]) && (j < sizeof(buf))) {
		j++;
	}

	while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) {
		url[i] = buf[j];
		i++; j++;
	}

	url[i] = '\0';

	/**
	 * Get the query string if availble
	 */

	if (strcasecmp(method, "GET") == 0) {
		query_string = url;
		while ((*query_string != '?') && (*query_string != '\0'))
			query_string++;
		if (*query_string == '?') {
			cgi = 1;
			*query_string = '\0';
			query_string++;
		}
	}

	/**
	 * Get the request headers
	 */

	while ((numchars > 0) && strcmp("\n", buf)) {
		char *value = NULL;
		char *end = NULL;
		numchars = httpd_get_line(dcb->fd, buf, sizeof(buf));
		if ( (value = strchr(buf, ':'))) {
			*value = '\0';
			value++;
			end = &value[strlen(value) -1];
			*end = '\0';

			if (strncasecmp(buf, "Hostname", 6) == 0) {
				strcpy(client_data->hostname, value);
			}
			if (strncasecmp(buf, "useragent", 9) == 0) {
				strcpy(client_data->useragent, value);
			}
		}
	}

	if (numchars) {
		headers_read = 1;
		memcpy(&client_data->headers_received, &headers_read, sizeof(int));
	}

	/**
	 * Now begins the server reply
	 */

	/* send all the basic headers and close with \r\n */
	httpd_send_headers(dcb, 1);

	/**
	 * ToDO: launch proper content handling based on the requested URI, later REST interface
	 *
	 */

	dcb_printf(dcb, "Welcome to HTTPD Gateway (c) %s\n\n", version_str);

	if (strcmp(url, "/show") == 0) {
		if (strlen(query_string)) {
			if (strcmp(query_string, "dcb") == 0)
				dprintAllDCBs(dcb);
			if (strcmp(query_string, "session") == 0)
				dprintAllSessions(dcb);
		}
	}

	/* force the client connecton close */
	dcb->func.close(dcb);	

	return 0;
}
コード例 #2
0
ファイル: server.cpp プロジェクト: CrazyCoder/mbot
long httpd_client_thread(SOCKET sock)
{
    static timeval tv = {30,30};

    long  rcv = 0;
    long  post = 0;
    long  post_len = 0;
    long  post_got = 0;
    long  ip = 0;
    long  ok = 0;
    long  fs = 0;
    char* request = NULL;
    char* str_tmp = NULL;
    char* str_tmp2 = NULL;
    char* cgi_params = NULL;
    char* query_str = NULL;
    char* req_page;
    char  buffer[1028];

    sHTTPDEnv httpd_env;
    cutSockf sf;
    cutMemf mf;
    cutMemf hdr;
    cutMemf req;
    sFDS fd;
    mb_event mbe = {MBT_WEBPAGE, 0};

    httpd_sname(sock,NULL,(DWORD*)&ip);

    if(!mf.create(4*1024) || !(req.create(1024))) {
        //malloc error
        goto Error500;
    }
    ////////////////////////////////////////
    sf.open(sock);
    ////////////////////////////////////////
    *fd.fd_array = sock;
    fd.fd_count = 1;
    ////////////////////////////////////////
    httpd_env.sf = &sf;
    httpd_env.mf = &mf;
    httpd_env.req = &req;
    ////////////////////////////////////////

    while(select(0,(fd_set*)&fd,0,0,&tv) >= 1 && mf.tellpos() < svr_maxrequest)
    {
        if(!(rcv = httpd_rrecv(sock,buffer,1024,3000))) {
            //recv error
            httpd_logaccess((const char*)mf.getdata(),500,sf.size(),ip);
            goto End;
        }
        if(!mf.write(buffer,rcv)) {
            goto Error500;
        }
        mf.putc(0);

        if(post == FALSE)
        {
            if((rcv = mf.size()) > 4 && (request = (char*)strstr((const char*)mf.getdata(),"\r\n\r\n")))
            {
                httpd_env.var_offset = req.written();
                if(httpd_parse_headers(&mf, &httpd_env) != 1) {
                    goto Error;
                }
                req.setpos(0);

                if(httpd_env.method == 1)
                {
                    post = TRUE;
                    str_tmp = httpd_hdr_get((const char*)req.getdata(),"CONTENT_LENGTH");
                    post_len = (str_tmp)?(strtoul(str_tmp,NULL,10)):(0);
                    post_got = rcv - (request - ((const char*)mf.getdata()) + 4);
                    if(!post_len || post_got >= post_len) {
                        ok = TRUE;
                        break;
                    }
                }
                else
                {
                    ok = TRUE;
                    break;
                }
            }
        }
        else
        {
            post_got += rcv;
            if(post_got >= post_len) {
                ok = TRUE;
                break;
            }
        }
    }
    ////////////////////////////////////////
    if(!ok || mf.size() < 10 || !(request = (char*)mf.getdata())) {
        goto Error;
    }
    ////////////////////////////////////////
    if(request[4 + post] != '/')goto Error;

    {
        str_tmp = strchr(request + 5,' ');
        if(!str_tmp)goto Error;
        *str_tmp = '\0';
        query_str = strchr(request + 5,'?');
        *str_tmp = ' ';
    }

    if(post == TRUE)
    {
        cgi_params = strstr(request,"\r\n\r\n");
        if(!cgi_params)goto Error;
        httpd_env.post_data = cgi_params + 4;
        httpd_env.post_length = post_len;

        if(post_got > post_len) {
            *(httpd_env.post_data + post_len) = '\0';
        }
        cgi_params = NULL;
    }

    if(httpd_env.error_code != 200)
    {
        httpd_writeformatted(&sf,"HTTP/1.0 %u ERROR\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n<h4>%u ERROR</h4>",httpd_env.error_code,httpd_env.error_code);
        goto End;
    }
    ////////////////////////////////////////
    if(query_str)
    {
        *query_str = '\0';
        req_page = request + 4 + post;
        //*cgi_params = '?';
    }
    else
    {
        str_tmp = strchr(request + 4 + post,' ');
        if(!str_tmp)goto Error;
        *str_tmp = '\0';
        req_page = request + 4 + post;
        //*str_tmp = ' ';
    }

    ///////////////////////////
    if(svr_auth_required && !httpd_authorize(
                httpd_hdr_get((const char*)req.getdata(),"HTTP_AUTHORIZATION")
            ))
    {
        goto Error401;
    }
    ///////////////////////////
    strlwr(req_page);
    httpd_unify(req_page);
    rcv = strlen(req_page);

    str_tmp = httpd_hdr_get((const char*)req.getdata(),"HTTP_AUTHORIZATION");
    str_tmp2 = inet_ntoa(*(in_addr*)&ip);


    strncpy(buffer,req_page,sizeof(buffer)-1);
    ok = httpd_unify(buffer);
    if(ok && buffer[ok-1]!='/') {
        buffer[ok]='/';
        buffer[ok+1]='\0';
    }

    if((ok = httpd_authorize_host(buffer,str_tmp2?str_tmp2:"0.0.0.0",str_tmp?str_tmp:"")) < 1) {
        if(ok < 0) {
            goto Error403;
        } else {
            goto Error401;
        }
    }

    ///////////////////////////
    if(!(*req_page)) {
        _snprintf(buffer,MAX_PATH,"%s/index.php",svr_wwwroot);
        req_page = "/index.php";
    } else if(req_page[rcv-1]=='/') {
        _snprintf(buffer,MAX_PATH,"%s%sindex.php",svr_wwwroot,req_page);
        req_page = buffer + strlen(svr_wwwroot);
    } else {
        _snprintf(buffer,MAX_PATH,"%s%s",svr_wwwroot,req_page);
    }
    httpd_unify(buffer);

    ok = help_fileexists(buffer,&fs);

    if(!ok) {
        ok = help_direxists(buffer);
        if(!ok) {
            goto Error404;
        } else {
            httpd_writeformatted(&sf,"HTTP/1.0 301 Moved Permanently\r\nConnection: close\r\nLocation: %s/\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n<h4>301 Document moved permanently!</h4>",req_page);
            goto End;
        }
    } else {
        //do the authorization for vhosts
        str_tmp = httpd_getextension(buffer);

        if(str_tmp && true == ut_str_match(".php*", str_tmp))
        {
            if(query_str) {
                *query_str = '?';
                if((str_tmp2 = strchr(query_str+1,' ')) || (str_tmp2 = strchr(query_str,'\r'))) {
                    *str_tmp2 = '\0';
                }
            }

            mbe.t1 = MBE_HTTPDENV;
            mbe.p1 = (void*)&httpd_env;

            if(!httpd_init_hdr(&hdr)) {
                goto Error500;
            }

            httpd_sname(sock,&req,NULL);
            req.write("SERVER_SOFTWARE\0MBot (c) Piotr Pawluczuk (www.piopawlu.net)",60);
            //SCRIPT_NAME
            req.write("SCRIPT_NAME",12);
            req.write(req_page,strlen(req_page)+1);
            //PHP_SELF
            req_page = strrchr(req_page,'/');
            if(!req_page) {
                goto Error404;
            }
            req_page++;
            req.write("PHP_SELF",9);
            req.write(req_page,strlen(req_page)+1);
            //END OF VARIABLES
            req.putc(0);

            if(!LPHP_ExecutePage(buffer,(query_str)?(query_str+1):NULL,
                                 (const char**)&sf,(void*)&mbe,(LPHP_ENVCB)httpd_php_cb,1)) {
                goto Error500;
            }

            if(httpd_env.out_started == 0) {
                httpd_send_headers(&httpd_env);
            }
            httpd_logaccess((const char*)mf.getdata(),200,sf.size(),ip);
            goto End;
        }
        else
        {
            if(httpd_sendfile(buffer,&httpd_env,buffer)) {
                httpd_logaccess((const char*)mf.getdata(),200,sf.size(),ip);
            } else {
                httpd_logaccess((const char*)mf.getdata(),404,sf.size(),ip);
            }
            goto End;
        }
    }

    ///////////////////////////
Error:
    ///////////////////////////
    httpd_logaccess((const char*)mf.getdata(),400,sf.size(),ip);
    httpd_writestring(&sf,"HTTP/1.0 400 Bad Request\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n<h4>400 Bad Request</h4>");
    goto End;
    ///////////////////////////
Error500:
    ///////////////////////////
    httpd_logaccess((const char*)mf.getdata(),500,sf.size(),ip);
    if(httpd_env.out_started == 0)
    {
        httpd_writestring(&sf,"HTTP/1.0 500 Internal Server Error\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n<h4>500 Internal Server Error</h4>");
    }
    goto End;
    ///////////////////////////
Error401:
    ///////////////////////////
    httpd_logaccess((const char*)mf.getdata(),401,sf.size(),ip);
    httpd_writestring(&sf,"HTTP/1.0 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"MSP Server HTTPD\"\r\nstatus: 401 Unauthorized\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n<h4>401 Authorization Required</h4>");
    goto End;
    ///////////////////////////
Error403:
    ///////////////////////////
    httpd_logaccess((const char*)mf.getdata(),401,sf.size(),ip);
    httpd_writestring(&sf,"HTTP/1.0 403 Access DENIED\r\nWWW-Authenticate: Basic realm=\"MSP Server HTTPD\"\r\nstatus: 403 Access DENIED\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n<h4>403 Access DENIED</h4>");
    goto End;
    ///////////////////////////
Error404:
    ///////////////////////////
    httpd_logaccess((const char*)mf.getdata(),404,sf.size(),ip);
    httpd_writestring(&sf,"HTTP/1.0 404 Not Found\r\nConnection: close\r\nPragma: no-cache\r\nContent-Type: text/html\r\n\r\n<h4>404 Not Found</h4>");
    ///////////////////////////
End:
    ///////////////////////////
    sf.close();
    mf.close();
    svr_cur_clients --;
    return 0;
}
コード例 #3
0
ファイル: httpd.c プロジェクト: bigshuai/MaxScale
/**
 * Read event for EPOLLIN on the httpd protocol module.
 *
 * @param dcb   The descriptor control block
 * @return
 */
static int httpd_read_event(DCB* dcb)
{
    SESSION *session = dcb->session;
    ROUTER_OBJECT *router = session->service->router;
    ROUTER *router_instance = session->service->router_instance;
    void *rsession = session->router_session;

    int numchars = 1;
    char buf[HTTPD_REQUESTLINE_MAXLEN-1] = "";
    char *query_string = NULL;
    char method[HTTPD_METHOD_MAXLEN-1] = "";
    char url[HTTPD_SMALL_BUFFER] = "";
    size_t i, j;
    int headers_read = 0;
    HTTPD_session *client_data = NULL;
    GWBUF *uri;

    client_data = dcb->data;

    /**
     * get the request line
     * METHOD URL HTTP_VER\r\n
     */

    numchars = httpd_get_line(dcb->fd, buf, sizeof(buf));

    i = 0; j = 0;
    while (!ISspace(buf[j]) && (i < sizeof(method) - 1))
    {
        method[i] = buf[j];
        i++; j++;
    }
    method[i] = '\0';

    strcpy(client_data->method, method);

    /* check allowed http methods */
    if (strcasecmp(method, "GET") && strcasecmp(method, "POST"))
    {
        //httpd_unimplemented(dcb->fd);
        return 0;
    }

    i = 0;

    while ( (j < sizeof(buf)) && ISspace(buf[j]))
    {
        j++;
    }

    while ((j < sizeof(buf) - 1) && !ISspace(buf[j]) && (i < sizeof(url) - 1))
    {
        url[i] = buf[j];
        i++; j++;
    }

    url[i] = '\0';

    /**
     * Get the query string if availble
     */

    if (strcasecmp(method, "GET") == 0)
    {
        query_string = url;
        while ((*query_string != '?') && (*query_string != '\0'))
        {
            query_string++;
        }
        if (*query_string == '?')
        {
            *query_string = '\0';
            query_string++;
        }
    }

    /**
     * Get the request headers
     */

    while ((numchars > 0) && strcmp("\n", buf))
    {
        char *value = NULL;
        char *end = NULL;
        numchars = httpd_get_line(dcb->fd, buf, sizeof(buf));
        if ((value = strchr(buf, ':')))
        {
            *value = '\0';
            value++;
            end = &value[strlen(value) -1];
            *end = '\0';

            if (strncasecmp(buf, "Hostname", 6) == 0)
            {
                strcpy(client_data->hostname, value);
            }
            if (strncasecmp(buf, "useragent", 9) == 0)
            {
                strcpy(client_data->useragent, value);
            }
        }
    }

    if (numchars)
    {
        headers_read = 1;
        memcpy(&client_data->headers_received, &headers_read, sizeof(int));
    }

    /**
     * Now begins the server reply
     */

    /* send all the basic headers and close with \r\n */
    httpd_send_headers(dcb, 1);

#if 0
    /**
     * ToDO: launch proper content handling based on the requested URI, later REST interface
     *
     */
    if (strcmp(url, "/show") == 0)
    {
        if (query_string && strlen(query_string))
        {
            if (strcmp(query_string, "dcb") == 0)
            {
                dprintAllDCBs(dcb);
            }
            if (strcmp(query_string, "session") == 0)
            {
                dprintAllSessions(dcb);
            }
        }
    }
    if (strcmp(url, "/services") == 0)
    {
        RESULTSET *set, *seviceGetList();
        if ((set = serviceGetList()) != NULL)
        {
            resultset_stream_json(set, dcb);
            resultset_free(set);
        }
    }
#endif
    if ((uri = gwbuf_alloc(strlen(url) + 1)) != NULL)
    {
        strcpy((char *)GWBUF_DATA(uri), url);
        gwbuf_set_type(uri, GWBUF_TYPE_HTTP);
        SESSION_ROUTE_QUERY(session, uri);
    }

    /* force the client connecton close */
    dcb_close(dcb);

    return 0;
}
コード例 #4
0
ファイル: server.cpp プロジェクト: CrazyCoder/mbot
long  httpd_php_cb(long code, void* param1, void* param2, mb_event* mbe)
{
    sHTTPDEnv* env;

    if(!mbe) {
        return 0;
    }
    env = (sHTTPDEnv*)mbe->p1;

    if(code == LPHP_CB_SETHDR)
    {
        char* hdr = (char*)param1;
        char* cp = NULL;
        char* sn;
        char* sv;
        char* cx;

        if(env->out_started || !hdr || !(cp = strchr(hdr,':'))) {
            return 0;
        } else {
            *cp = 0;
            sn = hdr;
            sv = cp + 1;
            cp = strchr(sv,'\r');
            if(cp) {
                *cp = '\0';
                cx = cp - 1;
                while(isspace(*cx) && cx!=sn) {
                    *(cx--)=0;
                }
            }
            while(isspace(*sv)) {
                sv++;
            }
            while(isspace(*sn)) {
                sn++;
            }
            env->hdr[sn] = sv;

            if(stricmp(sn,"location") == 0) {
                env->error_code = 301;
            }
            return 1;
        }
        return 0;
    } else if(code == LPHP_CB_OUTSTARTED) { //start output
        if(env->out_started == 0) {
            httpd_send_headers(env);
            env->out_started = 1;
        }
        return 1;
    } else if(code == LPHP_CB_GETMETHOD) { //get method
        return (int)((env->method == 1)?"POST":"GET");
    } else if(code == LPHP_CB_GETCOOKIE) { //get cookie
        return (int)httpd_hdr_get((const char*)env->req->getdata(),"HTTP_COOKIE");
    } else if(code == 4) { // n/a
        return (int)NULL;
    } else if(code == LPHP_CB_POST_LENGTH) { //get post data length
        return (int)env->post_length;
    } else if(code == LPHP_CB_POST_DATA) { //get post data pointer
        return (int)env->post_data;
    } else if(code == LPHP_CB_GETENV) {
        param2 = (void*)httpd_hdr_get((const char*)env->req->getdata(),(const char*)param1);
        return (long)((param2)?(param2):getenv((const char*)param1));
    } else if(code == LPHP_CB_GETCT) {
        return (long)httpd_hdr_get((const char*)env->req->getdata(),"CONTENT_TYPE");
    } else if(code == LPHP_CB_GETCL) {
        char* tmp = httpd_hdr_get((const char*)env->req->getdata(),"CONTENT_LENGTH");
        return (tmp)?(strtoul(tmp,NULL,10)):(0);
    } else if(code == LPHP_CB_GETVARS) {
        return ((long)env->req->getdata() + env->var_offset);
    } else {
        return NULL;
    }
}