Exemple #1
0
//Returns how much data was removed
uint16_t httpd_process_buffer(struct HttpdConnectionSlot *slot) {
	uint16_t processed = 0, oldprocessed,endline,startline;
	do {
		oldprocessed = processed;
		switch (slot->state) {
		case HTTPD_STATE_RESPONDING:
			return 0; //Don't bother doing anything else, buffer now contains an error message, socket should be closed ASAP.
		case HTTPD_STATE_PARSEVERB:
		case HTTPD_STATE_PARSEHDRS:
			for (endline=processed; endline < slot->bufferLen && slot->buffer[endline] != '\n'; endline++);
			if (endline != slot->bufferLen) {
				//Remember the line starting point
				startline = processed;
				//Mark as processed
				processed = endline+1;
				//If the final character is a linefeed, ignore it.
				if (endline>startline && slot->buffer[endline-1]=='\r') endline--;
				//Overwrite newline or linefeed with \0 so we can use string functions inside header parsing.
				slot->buffer[endline]='\0';
				//Process verb or header
				if (slot->state == HTTPD_STATE_PARSEVERB)
					httpd_process_verb(slot, &slot->buffer[startline], endline-startline);
				else
					httpd_process_header(slot, &slot->buffer[startline], endline-startline);
			}
			break;
		case HTTPD_STATE_WAITPOST:
			//Do we have enough data for the post request?
			if (slot->bufferLen >= slot->contentLen) {
				//If so, signal that we are ready to handle this request.
				slot->state = HTTPD_STATE_READY;
			}
			break;
		}
	} while (processed != oldprocessed);
	//Discard all processed data
	if (processed > 0) {
		slot->bufferLen -= processed;
		memcpy(slot->buffer, &slot->buffer[processed], slot->bufferLen);
	}
	return processed;
}
Exemple #2
0
/**
 * 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;
GWBUF		*buf = NULL;
char		*ptr, *sol;
HTTPD_session	*client_data = NULL;
int 		n;

	// Read all the available data
	if ((n = dcb_read(dcb, &buf)) != -1)
	{
		client_data = dcb->data;

		if (client_data->saved)
		{
			buf = gwbuf_append(client_data->saved, buf);
			client_data->saved = NULL;
		}
		buf = gwbuf_make_contiguous(buf);

		ptr = GWBUF_DATA(buf);

		if (strncasecmp(ptr, "POST", 4))
		{
			client_data->method = METHOD_POST;
			gwbuf_add_property(buf, "Method", "POST");
			ptr = ptr + 4;
		}
		else if (strncasecmp(ptr, "PUT", 3))
		{
			client_data->method = METHOD_PUT;
			gwbuf_add_property(buf, "Method", "PUT");
			ptr = ptr + 3;
		}
		else if (strncasecmp(ptr, "GET", 3))
		{
			client_data->method = METHOD_GET;
			gwbuf_add_property(buf, "Method", "GET");
			ptr = ptr + 3;
		}
		else if (strncasecmp(ptr, "HEAD", 4))
		{
			client_data->method = METHOD_HEAD;
			gwbuf_add_property(buf, "Method", "HEAD");
			ptr = ptr + 4;
		}
		while (ptr < (char *)(buf->end) && isspace(*ptr))
			ptr++;
		sol = ptr;
		while (ptr < (char *)(buf->end) && isspace(*ptr) == 0)
			ptr++;
		client_data->url = strndup(sol, ptr - sol);
		gwbuf_add_property(buf, "URL", client_data->url);
		while ((sol = httpd_nextline(buf, ptr)) != NULL && 
				*sol != '\n' && *sol != '\r')
		{
			httpd_process_header(buf, sol, client_data);
			ptr = sol;
		}

		/*
		 * We have read all the headers, or run out of data to 
		 * examine.
		 */
		if (sol == NULL)
		{
			client_data->saved = buf;
			return 0;
		}
		else
		{
			if (((char *)(buf->end) - sol)
					< client_data->request_len)
			{
				client_data->saved = buf;
			}
			else
			{
				LOGIF(LT, (skygw_log_write(
		                           LOGFILE_TRACE,
               		            "HTTPD: request %s.\n", client_data->url)));
				SESSION_ROUTE_QUERY(session, buf);
				if (client_data->url)
				{
					free(client_data->url);
					client_data->url = NULL;
				}
			}
		}



	}
	return 0;
}