示例#1
0
文件: http.c 项目: AllardJ/Tomato
GHashTable *http_parse_header (http_request *h, gchar *req) {
    GHashTable *head = g_hash_new();
    gchar **lines, **items, *key, *val, *p, prefix[50];
    guint i;

    h->method = NULL;
    h->uri    = NULL;
    h->header = head;
    
    if (req == NULL)
	return head;
    
    lines = g_strsplit( req, "\r\n", 0 );

    if (lines == NULL || lines[0] == NULL)
	return head;

    items = g_strsplit( lines[0], " ", 3 );

    h->method = g_strdup( items[0] );
    h->uri    = g_strdup( items[1] );
    // if (CONFd("Verbosity") >= 8) g_message( "http_parse_header: method_len: %d, uri_len: %d", strlen(h->method), strlen(h->uri));
    if (CONFd("Verbosity") >= 8) g_message( "http_parse_header: Method: %s", h->method );
    if (CONFd("Verbosity") >= 8) g_message( "http_parse_header: URI: %s", url_decode(h->uri) );
    g_strfreev( items );

    for (i = 1; lines[i] != NULL && lines[i][0] != '\0'; i++ ) {
	key = lines[i];
	val = strchr(key, ':');
	if (val != NULL) {
	    /* Separate the key from the value */
	    *val = '\0';

	    /* Normalize key -- lowercase every after 1st char */
	    for (p = key + 1; *p != '\0'; p++)
		*p = tolower(*p);

	    /* Strip ": " plus leading and trailing space from val */
	    g_strchomp( val += 2 ); // ": "

	    //if ( strcmp(key, "Referer" )== 0) {
	    //    if (CONFd("Verbosity") >= 8) g_message("http_parse_header: Referer: %s", url_decode(val) );
	    //} 
            //else {
	        if (CONFd("Verbosity") >= 8) {
                    g_snprintf(prefix, 50, "http_parse_header: %s: ", key);
                    syslog_message(prefix, url_decode(val), strlen(url_decode(val)) );
                }
	        g_hash_set( head, key, val );
	    //}
	}
    }

    g_strfreev( lines );
    h->header = head;
    return head;
}
示例#2
0
文件: http.c 项目: AllardJ/Tomato
GHashTable *parse_query_string( gchar *query ) {
    GHashTable *data = g_hash_new();
    gchar **items, *key, *val, prefix[50];
    guint i;

    if (!query)
	return data;

    items = g_strsplit( query, "&", 0 );
    for ( i = 0; items[i] != NULL; i++ ) {
	key = items[i];
	if (key == NULL)
	    break;

	val = strchr( key, '=' );
	if (val != NULL)
	    *(val++) = '\0';
	else
	    val = "1";

	key = url_decode( key );	
	val = url_decode( val );	
	/* Irving - fix from Yurgi - check to see if the key is already in the
	   hash table.  This deals with keys that are set twice by web sites */
	if(g_hash_table_lookup_extended( data, key, NULL, NULL ) == FALSE ) {
		g_hash_set( data, key, val );
		if(CONFd("Verbosity") >= 8) {
                     g_snprintf(prefix, 50, "parse_query_string: %s=", key);
                     syslog_message(prefix, val, strlen(val));
                }
	}
	else
		if(CONFd("Verbosity") >= 8) g_message("parse_query_string: DUPLICATE key %s=%s, discarded.", key, val);

	g_free( key );
	g_free( val );
    }
    g_strfreev(items);

    return data;
}
示例#3
0
static void domark(int sig)
{
	syslog_message(LOG_SYSLOG | LOG_INFO, "-- MARK --");
	alarm(markinterval);
}
示例#4
0
文件: main.c 项目: Prince781/libgtop
void
handle_parent_connection (int s)
{
    glibtop *server = glibtop_global_server;
    glibtop_response _resp, *resp = &_resp;
    glibtop_command _cmnd, *cmnd = &_cmnd;
    glibtop_mountentry *mount_list;
    char parameter [BUFSIZ];
    unsigned short device;
    gint64 *param_ptr;
    int all_fs;
    pid_t pid;
    void *ptr;

    glibtop_send_version (glibtop_global_server, s);

    if (verbose_output)
	syslog_message (LOG_INFO, "Parent features = %lu",
			glibtop_server_features);

    if (enable_debug)
	syslog_message (LOG_DEBUG, "SIZEOF: %u - %u - %u - %u - %u - %u",
			sizeof (glibtop_command), sizeof (glibtop_response),
			sizeof (glibtop_mountentry), sizeof (glibtop_union),
			sizeof (glibtop_sysdeps),
			sizeof (glibtop_response_union));

    while (do_read (s, cmnd, sizeof (glibtop_command))) {
	if (enable_debug)
	    syslog_message (LOG_DEBUG,
			    "Parent (%d) received command %llu from client.",
			    getpid (), cmnd->command);

	if (cmnd->data_size >= BUFSIZ) {
	    syslog_message (LOG_WARNING,
			    "Client sent %llu bytes, but buffer is %lu",
			    cmnd->data_size, (unsigned long)BUFSIZ);
	    return;
	}

	memset (resp, 0, sizeof (glibtop_response));

	memset (parameter, 0, sizeof (parameter));

	if (cmnd->data_size) {
	    if (enable_debug)
		syslog_message (LOG_DEBUG, "Client has %llu bytes of data.",
				cmnd->data_size);

	    do_read (s, parameter, cmnd->data_size);

	} else if (cmnd->size) {
	    memcpy (parameter, cmnd->parameter, cmnd->size);
	}

	switch (cmnd->command) {
	case GLIBTOP_CMND_QUIT:
	    do_output (s, resp, 0, 0, NULL);
	    return;
	case GLIBTOP_CMND_SYSDEPS:
	    memcpy (&resp->u.sysdeps, &server->sysdeps,
		    sizeof (glibtop_sysdeps));
	    resp->u.sysdeps.features = GLIBTOP_SYSDEPS_ALL;
	    do_output (s, resp, _offset_union (sysdeps), 0, NULL);
	    break;
	case GLIBTOP_CMND_CPU:
	    glibtop_get_cpu_l (server, &resp->u.data.cpu);
	    do_output (s, resp, _offset_data (cpu), 0, NULL);
	    break;
	case GLIBTOP_CMND_MEM:
	    glibtop_get_mem_l (server, &resp->u.data.mem);
	    do_output (s, resp, _offset_data (mem), 0, NULL);
	    break;
	case GLIBTOP_CMND_SWAP:
	    glibtop_get_swap_l (server, &resp->u.data.swap);
	    do_output (s, resp, _offset_data (swap), 0, NULL);
	    break;
	case GLIBTOP_CMND_UPTIME:
	    glibtop_get_uptime_l (server, &resp->u.data.uptime);
	    do_output (s, resp, _offset_data (uptime), 0, NULL);
	    break;
	case GLIBTOP_CMND_LOADAVG:
	    glibtop_get_loadavg_l (server, &resp->u.data.loadavg);
	    do_output (s, resp, _offset_data (loadavg), 0, NULL);
	    break;
	case GLIBTOP_CMND_SHM_LIMITS:
	    glibtop_get_shm_limits_l
		(server, &resp->u.data.shm_limits);
	    do_output (s, resp, _offset_data (shm_limits), 0, NULL);
	    break;
	case GLIBTOP_CMND_MSG_LIMITS:
	    glibtop_get_msg_limits_l
		(server, &resp->u.data.msg_limits);
	    do_output (s, resp, _offset_data (msg_limits), 0, NULL);
	    break;
	case GLIBTOP_CMND_SEM_LIMITS:
	    glibtop_get_sem_limits_l
		(server, &resp->u.data.sem_limits);
	    do_output (s, resp, _offset_data (sem_limits), 0, NULL);
	    break;
	case GLIBTOP_CMND_PROCLIST:
	    param_ptr = (gint64 *) parameter;
	    ptr = glibtop_get_proclist_l (server,
					  &resp->u.data.proclist,
					  param_ptr [0],
					  param_ptr [1]);
	    do_output (s, resp, _offset_data (proclist),
		       resp->u.data.proclist.total, ptr);
	    g_free (ptr);
	    break;
	case GLIBTOP_CMND_PROC_MAP:
	    memcpy (&pid, parameter, sizeof (pid_t));
	    ptr = glibtop_get_proc_map_l (server,
					  &resp->u.data.proc_map,
					  pid);
	    do_output (s, resp, _offset_data (proc_map),
		       resp->u.data.proc_map.total, ptr);
	    g_free (ptr);
	    break;

	case GLIBTOP_CMND_PROC_WD:
		/* FIXME */
	    break;

	case GLIBTOP_CMND_NETLIST:
		/* FIXME */
	    break;

	case GLIBTOP_CMND_PROC_ARGS:
	    memcpy (&pid, parameter, sizeof (pid_t));
	    ptr = glibtop_get_proc_args_l (server,
					   &resp->u.data.proc_args,
					   pid, 0);
	    do_output (s, resp, _offset_data (proc_args),
		       ptr ? resp->u.data.proc_args.size+1 : 0, ptr);
	    g_free (ptr);
	    break;
	case GLIBTOP_CMND_PROC_STATE:
	    memcpy (&pid, parameter, sizeof (pid_t));
	    glibtop_get_proc_state_l
		(server, &resp->u.data.proc_state, pid);
	    do_output (s, resp, _offset_data (proc_state), 0, NULL);
	    break;
	case GLIBTOP_CMND_PROC_UID:
	    memcpy (&pid, parameter, sizeof (pid_t));
	    glibtop_get_proc_uid_l
		(server, &resp->u.data.proc_uid, pid);
	    do_output (s, resp, _offset_data (proc_uid), 0, NULL);
	    break;
	case GLIBTOP_CMND_PROC_MEM:
	    memcpy (&pid, parameter, sizeof (pid_t));
	    glibtop_get_proc_mem_l
		(server, &resp->u.data.proc_mem, pid);
	    do_output (s, resp, _offset_data (proc_mem), 0, NULL);
	    break;
	case GLIBTOP_CMND_PROC_TIME:
	    memcpy (&pid, parameter, sizeof (pid_t));
	    glibtop_get_proc_time_l
		(server, &resp->u.data.proc_time, pid);
	    do_output (s, resp, _offset_data (proc_time), 0, NULL);
	    break;
	case GLIBTOP_CMND_PROC_SIGNAL:
	    memcpy (&pid, parameter, sizeof (pid_t));
	    glibtop_get_proc_signal_l
		(server, &resp->u.data.proc_signal, pid);
	    do_output (s, resp, _offset_data (proc_signal), 0, NULL);
	    break;
	case GLIBTOP_CMND_PROC_KERNEL:
	    memcpy (&pid, parameter, sizeof (pid_t));
	    glibtop_get_proc_kernel_l
		(server, &resp->u.data.proc_kernel, pid);
	    do_output (s, resp, _offset_data (proc_kernel), 0, NULL);
	    break;
	case GLIBTOP_CMND_PROC_SEGMENT:
	    memcpy (&pid, parameter, sizeof (pid_t));
	    glibtop_get_proc_segment_l
		(server, &resp->u.data.proc_segment, pid);
	    do_output (s, resp, _offset_data (proc_segment), 0, NULL);
	    break;
	case GLIBTOP_CMND_MOUNTLIST:
	    memcpy (&all_fs, parameter, sizeof (all_fs));
	    mount_list = glibtop_get_mountlist_l
		(server, &resp->u.data.mountlist, all_fs);
	    do_output (s, resp, _offset_data (mountlist),
		       resp->u.data.mountlist.total, mount_list);
	    g_free (mount_list);
	    break;
	case GLIBTOP_CMND_FSUSAGE:
	    glibtop_get_fsusage_l
		(server, &resp->u.data.fsusage, parameter);
	    do_output (s, resp, _offset_data (fsusage),
		       0, NULL);
	    break;
	case GLIBTOP_CMND_PPP:
	    memcpy (&device, parameter, sizeof (device));
	    glibtop_get_ppp_l
		(server, &resp->u.data.ppp, device);
	    do_output (s, resp, _offset_data (ppp), 0, NULL);
	    break;
	case GLIBTOP_CMND_NETLOAD:
	    glibtop_get_netload_l
		(server, &resp->u.data.netload, parameter);
	    do_output (s, resp, _offset_data (netload),
		       0, NULL);
	    break;
	default:
	    syslog_message (LOG_ERR, "Parent received unknown command %llu.",
			    cmnd->command);
	    break;
	}
    }
}
示例#5
0
文件: http.c 项目: AllardJ/Tomato
guint http_request_read (http_request *h) {
    gchar *buf = g_new( gchar, BUFSIZ + 1 );
/*
    GIOStatus r;
    GError *err = NULL;
*/
    GIOError r;
    guint s, times, n = 0, t = 0;
    gchar *c_len_hdr = NULL;
    guint hdr_len = 0, c_len = 0, tot_req_size = 0;
    struct timeval tv;
    fd_set fdset;

    FD_ZERO(&fdset);
    FD_SET(g_io_channel_unix_get_fd(h->sock), &fdset);
    tv.tv_sec = 0;
    buf[0] = '\0';
    buf[BUFSIZ] = '\0';

    //    for (t = 0, n = BUF_SIZ; n == BUF_SIZ &&
    //      h->buffer->len < MAX_REQUEST_SIZE; t += n ) {
    // BPsmythe: The above (original) loop will never execute
    // more than once unless the size of the buffer read in (n)
    // is equal to the constant BUF_SIZE.  What is desired is
    // to keep looping until there is nothing left to read.
    // The for was changed to look for the end of the headers.
    // FIXME: We should use the newer g_io_channel_read_char
    //
    // TJaqua: Added buffer overflow checking, content read loop from 0.93pre2, and fixed up the timeouts, logging and error exits

    if (CONFd("Verbosity") >= 7) g_message("http_request_read: READING request from peer %s (on %s, fd: %d)", h->peer_ip, h->sock_ip, g_io_channel_unix_get_fd(h->sock));
    if (CONFd("Verbosity") >= 9) g_message("http_request_read: entering HEADER read loop (BUFSIZE=%u)", BUFSIZ);
    for (times=MAX_REQ_TIMEOUTS; !hdr_len && (times > 0); t += n ) {
	n=0;
/*
	r = g_io_channel_read_chars( h->sock, buf, BUFSIZ, &n, &err );
	if (r == G_IO_STATUS_ERROR || err != NULL) {
	    g_message( "http_request_read: Socket IO ERROR: %s, exiting!", err->message );
	    g_error_free(err);
*/
	r = g_io_channel_read( h->sock, buf, BUFSIZ, &n);
	if (r != G_IO_ERROR_NONE) {
	    g_warning( "http_request_read: Socket IO ERROR: %m, exiting!" );
	    g_free(buf);
	    return 0;
	}

	if (CONFd("Verbosity") >= 9) g_message("http_request_read: HEADER loop read %u bytes", n);
	buf[n] = '\0';
	if (n && CONFd("Verbosity") >= 11) syslog_message("RAW_HDR_BUF: ", buf, n);

	if(strlen(buf) < n-1) g_warning("http_request_read: Trailing data past string in buffer was DICARDED!");
	if (h->buffer->len == MAX_REQUEST_SIZE)
	    g_warning("http_request_read: header buffer full (%u bytes, %u bytes discarded!)", MAX_REQUEST_SIZE, n);
	else if (n <= (MAX_REQUEST_SIZE - h->buffer->len)) {
	    if(CONFd("Verbosity") >= 11) g_message("http_request_read: APPENDING buffer to HEADER.");
	    if(n) g_string_append(h->buffer, buf);
	    else if (CONFd("Verbosity") >= 6) g_message("http_request_read: No data in buffer.");
	    //if(CONFd("Verbosity") >= 11) g_message("http_request_read: Partial HEADER (%u bytes) is: %s", h->buffer->len, h->buffer->str);
	}
	else {
	    if(CONFd("Verbosity") >= 6) g_warning("http_request_read: header buffer full (%u bytes, %u bytes discarded!)", 
                                                  MAX_REQUEST_SIZE, n - (MAX_REQUEST_SIZE - h->buffer->len));
	    buf[MAX_REQUEST_SIZE - h->buffer->len] = '\0';
	    g_string_append(h->buffer, buf);
	}
        times--;

        // BPsmythe: Check for the end of the headers.
	if (hdr_len = http_get_hdr_len(h->buffer->str)) {
	        if (CONFd("Verbosity") >= 6) g_message("http_request_read: HEADER END found, length: %u", hdr_len );
        }
	else {
	    if(!times) { 
                if(CONFd("Verbosity") >= 6) {
                    g_message("http_request_read: ERROR: HEADER END not found after %d tries, exiting!", MAX_REQ_TIMEOUTS);
	            if (!t) g_message("http_request_read: Empty HTTP-request header.");
	            else g_message("http_request_read: Invalid HTTP-request header, %u bytes read.", t+n);
	        }
		//Should I send a FIN packet to shutdown the socket?
                g_free(buf);
	        return 0;
            }
	    if(CONFd("Verbosity") >= 11) g_message("http_request_read: Waiting for next I/O on socket, (%d more tries).", times);
            tv.tv_usec = REQ_TIMEOUT;
	    while(times && !(s = select (g_io_channel_unix_get_fd(h->sock)+1, &fdset, NULL, NULL, &tv))) {
                times--;
	        if (CONFd("Verbosity") >= 7)  g_message("http_request_read: HEADER select timeout, %d more tries", times);
                tv.tv_usec = REQ_TIMEOUT;
            }
	    if(s<0) {
	        g_warning("http_request_read: ERROR in select, exiting!");
		g_free(buf);
		return 0;
	    }
	    else if(!times) { 
                if(CONFd("Verbosity") >= 6) {
                    g_message("http_request_read: ERROR: Too many TIMEOUTS waiting for HEADER end!");
	            if (!t) g_message("http_request_read: Empty HTTP-request header.");
	            else g_message("http_request_read: Invalid HTTP-request header, %u bytes read.", t+n);
	        }
		//Should I send a FIN packet to shutdown the socket?
                g_free(buf);
	        return 0;
            }
            else if(CONFd("Verbosity") >= 11) g_message("http_request_read: Recieved I/O on socket.");
	}
    }

    if (CONFd("Verbosity") >= 10) syslog_message("RAW_HEADER: ", h->buffer->str, h->buffer->len);
    
    // Read the content length from the header
    http_parse_header( h, h->buffer->str );

    if( (HEADER("Content-length")) && (c_len = atoi(HEADER("Content-length"))) ) {
        if (CONFd("Verbosity") >= 9) g_message("http_request_read: entering CONTENT read loop to read %u bytes.", c_len);
        tot_req_size = hdr_len + c_len;
        for (times=MAX_REQ_TIMEOUTS; (t < tot_req_size) && (times > 0); t += n ) {
	    if (CONFd("Verbosity") >= 9) g_message("http_request_read: %u bytes of %u total.", t, tot_req_size );
	    n=0;
/*
	    r = g_io_channel_read_chars( h->sock, buf, BUFSIZ, &n, &err );
	    if (r == G_IO_STATUS_ERROR || err != NULL) {
	        g_message( "http_request_read: Socket-IO ERROR: %s, exiting!", err->message );
	        g_error_free(err);
*/
	    r = g_io_channel_read( h->sock, buf, BUFSIZ, &n);
	    if (r != G_IO_ERROR_NONE) {
	        g_warning( "http_request_read: Socket-IO ERROR: %m, exiting!" );
	        g_free(buf);
	        return 0;
	    }

	    if (CONFd("Verbosity") >= 9) g_message("http_request_read: CONTENT loop read %d bytes", n );
	    buf[n] = '\0';
	    if (n && CONFd("Verbosity") >= 11) syslog_message("RAW_CON_BUF: ", buf, n); 

	    if (h->buffer->len == MAX_REQUEST_SIZE) {
	        if(CONFd("Verbosity") >= 6) g_warning("http_request_read: Maximum request length EXCEEDED (%u bytes discarded! Continuing to read out content.)", n);
            }
	    else if (h->buffer->len == tot_req_size) {
	        if(CONFd("Verbosity") >= 6) g_warning("http_request_read: Content length EXCEEDED (%u bytes discarded! Shouldn't happen!)", n);
            }
            else if (h->buffer->len + n >= MAX_REQUEST_SIZE) {
	        if(CONFd("Verbosity") >= 6) g_warning("http_request_read: Max buffer length EXCEEDED (%u bytes discarded! Continuing to read out content.)", 
                                                       n - (MAX_REQUEST_SIZE - h->buffer->len));
                buf[MAX_REQUEST_SIZE - h->buffer->len] = '\0';
	        g_string_append(h->buffer, buf);
            }
	    else if (n <= (tot_req_size - h->buffer->len)) {
	        if(CONFd("Verbosity") >= 11) g_message("http_request_read: APPENDING buffer to CONTENT.");
	        if(n) g_string_append(h->buffer, buf);
	        else if (CONFd("Verbosity") >= 6) g_message("http_request_read: No data in buffer.");
	    }
	    else {
	        if(CONFd("Verbosity") >= 6) g_warning("http_request_read: Content length EXCEEDED (%u bytes added, %u bytes discarded!)", 
                                                       tot_req_size - h->buffer->len, n - (tot_req_size - h->buffer->len));
	        buf[tot_req_size - h->buffer->len] = '\0';
	        g_string_append(h->buffer, buf);
	    }
            times--;

            // TJaqua: Check for the end of the content.
	    if ((t+n) >= tot_req_size) {
                if (CONFd("Verbosity") >= 6) g_message("http_request_read: CONTENT end reached, length: %u", tot_req_size);
            }
	    else {
                if (!times) {
                    if(CONFd("Verbosity") >= 6) {
                        g_message("http_request_read: ERROR: CONTENT END not found after %d tries, exiting!", MAX_REQ_TIMEOUTS);
	                if (t == hdr_len) g_message("http_request_read: Empty CONTENT, socket may have stalled.");
	                else g_message("http_request_read: CONTENT unfinished, %u bytes read.", t+n);
	            }
                    //Should I send a FIN packet to shutdown the socket?
                    g_free(buf);
                    //We still got the header, though, so return it.
                    g_string_truncate(h->buffer, hdr_len);
	            return hdr_len;
                }
	        if(CONFd("Verbosity") >= 11) g_message("http_request_read: Waiting for next I/O on socket.");
                tv.tv_usec = REQ_TIMEOUT;
	        while (times && !(s = select (g_io_channel_unix_get_fd(h->sock)+1, &fdset, NULL, NULL, &tv))) {
                    times--;
	            if (CONFd("Verbosity") >= 7)  g_message("http_request_read: CONTENT select timeout, %d more tries", times);
                    tv.tv_usec = REQ_TIMEOUT;
                }
	        if(s<0) {
	            g_warning("http_request_read: ERROR in select, exiting!");
		    g_free(buf);
                    //We still got the header, though, so return it.
                    g_string_truncate(h->buffer, hdr_len);
	            return hdr_len;
	        }
                else if (!times) {
                    if(CONFd("Verbosity") >= 6) {
                        g_message("http_request_read: ERROR: Too many TIMEOUTS waiting for CONTENT end!");
	                if (t == hdr_len) g_message("http_request_read: Empty CONTENT, socket may have stalled.");
	                else g_message("http_request_read: Invalid HTTP-request header, %u bytes read.", t+n);
	            }
                    //Should I send a FIN packet to shutdown the socket?
                    g_free(buf);
                    //We still got the header, though, so return it.
                    g_string_truncate(h->buffer, hdr_len);
	            return hdr_len;
                }
                else if (CONFd("Verbosity") >= 11) g_message("http_request_read: Received I/O on socket.");
	    }
        }
        if (CONFd("Verbosity") >= 10) syslog_message("RAW_CONTENT: ", &(h->buffer->str[hdr_len]), h->buffer->len - hdr_len); 
        if (t<tot_req_size) 
	    g_message("http_request_read: CONTENT unfinished - should not happen!");
    }

    if (CONFd("Verbosity") >= 6) g_message("http_request_read: FINISHED read (%u bytes total), exiting.", t);
    g_free(buf);
    return t;
}