示例#1
0
int call_callback(struct fd_state *state, const char *path, char *sparams, char *scookies) {
    assert(state && path);
    struct callback_elem *elem = callback_head;
    while (elem) {
        if (strcmp(path, elem->path) == 0) {
            struct lh_response response;
            response.header[0] = 0;
            response.header_len = 0;
			response.body[0] = 0;
			response.body_len = 0;
            
            struct lh_kv_elem *params = parse_url_params(sparams);
            struct lh_kv_elem *cookies = parse_cookies(scookies);
            elem->callback(params, cookies, &response);
            free_kvs(params);
            free_kvs(cookies);
            
            write_response_header(state, "application/json", response.body_len, response.header);
			if (response.header_len > 0)
				write_to_buf(state, response.header, response.header_len);
            if (response.body_len > 0)
                write_to_buf(state, response.body, response.body_len);
            return 1;
        }
        elem = elem->next;
    }
    return 0;
}
示例#2
0
int proxyServerLoadRequest(ProxyServer *p, const char *uniqueId,
        RequestRecord *rec) {

	reset_request_record(rec);

	char file_name[512];
	struct stat stat_buf;
	snprintf(file_name, sizeof(file_name), "%s/%s.req",
		stringAsCString(p->persistenceFolder), uniqueId);

	rec->fd = open(file_name, O_RDONLY);
	DIE(p, rec->fd, "Failed to open request file.");

	int status = fstat(rec->fd, &stat_buf);
	DIE(p, status, "Failed to get request file size.");

	rec->map.length = stat_buf.st_size; //Save the size

	//If file size is 0 then just return
	if (rec->map.length == 0) {
		return 0;
	}

	rec->map.buffer = mmap(NULL, stat_buf.st_size, PROT_READ,
		MAP_SHARED, rec->fd, 0);
	if (rec->map.buffer == MAP_FAILED) {
		DIE(p, -1, "Failed to map request file.");
	}

	//We are good to go. Start parsing.
	String *str = newString();
	int state = PARSE_METHOD;
	for (size_t i = 0; i < rec->map.length; ++i) {
		char ch = rec->map.buffer[i];

		//printf("[%c %d]", ch, state);
		if (ch == '\r') {
			continue; //Ignored
		}
		if (state == PARSE_METHOD) {
			if (ch == ' ') {
				if (strcmp("CONNECT", 
					stringAsCString(rec->method)) == 0) {
					state = PARSE_CONNECT_ADDRESS;
				} else {
					state = PARSE_PATH;
				}
				continue;
			}
			stringAppendChar(rec->method, ch);
			continue;
		}
		if (state == PARSE_PATH) {
			if (ch == '?') {
				state = PARSE_QUERY_STRING;
				continue;
			}
			if (ch == ' ') {
				state = PARSE_PROTOCOL_VERSION;
				continue;
			}
			stringAppendChar(rec->path, ch);
			continue;
		}
		if (state == PARSE_QUERY_STRING) {
			if (ch == ' ') {
				state = PARSE_PROTOCOL_VERSION;
				continue;
			}
			stringAppendChar(rec->queryString, ch);
			continue;
		}
		if (state == PARSE_PROTOCOL_VERSION) {
			if (ch == '\n') {
				state = PARSE_HEADER_NAME;
				continue;
			}
			//Don't store version
			continue;
		}
		if (state == PARSE_CONNECT_ADDRESS) {
			if (ch == ' ') {
				state = PARSE_PROTOCOL_VERSION;
				continue;
			}
			//Don't store address
			continue;
		}
		if (state == PARSE_HEADER_NAME) {
			if (ch == ':') {
				arrayAdd(rec->headerNames, 
					newStringWithString(str));
				str->length = 0;
				state = PARSE_HEADER_VALUE;
				continue;
			}
			if (ch == '\n') {
				//End of request headers
				rec->headerBuffer.buffer = 
					rec->map.buffer;
				rec->headerBuffer.length = i + 1;

				rec->bodyBuffer.buffer =
					rec->map.buffer + i + 1;
				rec->bodyBuffer.length = 
					rec->map.length - 
					rec->headerBuffer.length;
				
				//End parsing for now
				break;
			}
			stringAppendChar(str, ch);
			continue;
		}
		if (state == PARSE_HEADER_VALUE) {
			if (ch == '\n') {
				arrayAdd(rec->headerValues, 
					newStringWithString(str));
				str->length = 0;
				state = PARSE_HEADER_NAME;
				continue;
			}
			if ((str->length == 0) && ch == ' ') {
				//Skip leading space.
				continue;
			}
			stringAppendChar(str, ch);
			continue;
		}
	}
	
	deleteString(str);

	//Parse URL parameters
	parse_url_params(rec->queryString->buffer, rec->queryString->length, 
		rec->parameterNames, rec->parameterValues);

	//If form post then parse request body for parameters
	String *contentType = get_header_value(CONTENT_TYPE, rec);
	if (contentType != NULL && 
	    stringEqualsCString(contentType, FORM_ENC) &&
	    rec->bodyBuffer.length > 0) {
		parse_url_params(rec->bodyBuffer.buffer, 
			rec->bodyBuffer.length, 
			rec->parameterNames, 
			rec->parameterValues);
	}

	//It is safe to close the file now. It will 
	//closed anyway by reset method. 
	close(rec->fd);
	rec->fd = -1;

	return 0;
}