Пример #1
0
int
datastream_init (datastream_t *datastream, void *context, uint32_t size, datastream_feed_func feed_func)
{
	int error;
	
	if (unlikely(datastream == NULL))
		LOG_ERROR_AND_RETURN(-1, "null datasttream_t");
	
	if (unlikely(NULL == (datastream->data = malloc(size))))
		LOG_ERROR_AND_RETURN(-101, "failed to malloc(%u), %s", size, strerror(errno));
	
	if (unlikely(0 != (error = flist_init(&datastream->queue, 100, NULL))))
		LOG_ERROR_AND_RETURN(-102, "failed to flist_init, %d", error);
	
	if (unlikely(0 != (error = thread_init(&datastream->thread, "datastream-thread", (thread_start_func)__datastream_thread, datastream, NULL))))
		LOG_ERROR_AND_RETURN(-103, "failed to thread_init, %d", error);
	
	datastream->size = size;
	datastream->stop = 0;
	datastream->context = context;
	datastream->feed = feed_func;
	
	memset(datastream->data, 0, size);
	
	if (unlikely(0 != (error = thread_start(&datastream->thread))))
		LOG_ERROR_AND_RETURN(-103, "failed to thread_start, %d", error);
	
	return 0;
}
Пример #2
0
int
driver_connect (driver_t *driver, device_desc_t *desc, connection_t *connection)
{
	int error;
	
	if (unlikely(driver == NULL))
		LOG_ERROR_AND_RETURN(-1, "null driver_t");
	
	if (unlikely(driver->connect == NULL))
		LOG_ERROR_AND_RETURN(-101, "[%s] null connect function pointer", driver->desc.name);
	
	if (unlikely(0 != (error = (*driver->connect)(driver, desc))))
		LOG_ERROR_AND_RETURN(-102, "[%s] failed to driver->connection, %d", driver->desc.name, error);
	
	connection->context1 = driver;
	connection->context2 = desc;
	connection->send = __driver_send;
	connection->recv = __driver_recv;
	connection->available = __driver_available;
	connection->endian = driver->endian;
	
	if (unlikely(0 != (error = connection_open(connection))))
		LOG_ERROR_AND_RETURN(-103, "[%s] failed to connection_open(0, %d", driver->desc.name, error);
	
	return 0;
}
Пример #3
0
int
sdriq_init (sdriq_t *sdriq, device_desc_t *desc)
{
	int error;
	
	if (unlikely(sdriq == NULL))
		LOG_ERROR_AND_RETURN(-1, "null sdriq_t");
	
	if (unlikely(desc == NULL))
		LOG_ERROR_AND_RETURN(-2, "null device_desc_t");
	
	if (unlikely(0 != (error = ascp_init(&sdriq->ascp))))
		LOG_ERROR_AND_RETURN(-101, "failed to ascp_init, %d", error);
	
	if (unlikely(0 != (error = device_init((device_t*)sdriq, desc))))
		LOG_ERROR_AND_RETURN(-102, "failed to device_init, %d", error);
	
	sdriq->device.__message_read = (device_message_read_func)__sdriq_message_read;
	sdriq->device.__data_beg = (device_data_beg_func)__sdriq_data_beg;
	sdriq->device.__data_end = (device_data_end_func)__sdriq_data_end;
	sdriq->device.__frequency_set = (device_frequency_set_func)__sdriq_frequency_set;
	sdriq->device.__frequency_get = (device_frequency_get_func)__sdriq_frequency_get;
	sdriq->device.__gain_set = (device_gain_set_func)__sdriq_gain_set;
	sdriq->device.__span_set = (device_span_set_func)__sdriq_span_set;
	sdriq->device.__connect = (device_connect_func)__sdriq_connect;
	sdriq->device.__disconnect = (device_disconnect_func)__sdriq_disconnect;
	sdriq->device.__program = (device_program_func)__sdriq_program;
	
	return 0;
}
Пример #4
0
int
driver_connected (driver_t *driver, device_desc_t *desc)
{
	if (unlikely(driver == NULL))
		LOG_ERROR_AND_RETURN(-1, "null driver_t");
	
	if (unlikely(driver->connected == NULL))
		LOG_ERROR_AND_RETURN(-101, "[%s] null connected function pointer", driver->desc.name);
	
	return (*driver->connected)(driver, desc);
}
Пример #5
0
static int
handle_txn_start(INKCont contp, INKHttpTxn txnp)
{
  LOG_SET_FUNCTION_NAME("handle_txn_start");

  if (INKHttpTxnHookAdd(txnp, INK_HTTP_READ_CACHE_HDR_HOOK, contp) == INK_ERROR)
    LOG_ERROR_AND_RETURN("INKHttpTxnHookAdd");
  if (INKHttpTxnHookAdd(txnp, INK_HTTP_READ_RESPONSE_HDR_HOOK, contp) == INK_ERROR)
    LOG_ERROR_AND_RETURN("INKHttpTxnHookAdd");

  return 0;
}
Пример #6
0
int
sdriq_destroy (sdriq_t *sdriq)
{
	int error;
	
	if (unlikely(sdriq == NULL))
		LOG_ERROR_AND_RETURN(-1, "null sdriq_t");
	
	if (unlikely(0 != (error = ascp_destroy(&sdriq->ascp))))
		LOG_ERROR_AND_RETURN(-101, "failed to ascp_destroy, %d", error);
	
	if (unlikely(0 != (error = device_destroy((device_t*)sdriq))))
		LOG_ERROR_AND_RETURN(-102, "failed to device_destroy, %d", error);
	
	return 0;
}
Пример #7
0
int
driver_disconnect (driver_t *driver, device_desc_t *desc)
{
	int error;
	
	if (unlikely(driver == NULL))
		LOG_ERROR_AND_RETURN(-1, "null driver_t");
	
	if (unlikely(driver->disconnect == NULL))
		LOG_ERROR_AND_RETURN(-101, "[%s] null disconnect function pointer", driver->desc.name);
	
	if (unlikely(0 != (error = (*driver->disconnect)(driver, desc))))
		LOG_ERROR_AND_RETURN(-102, "[%s] failed to driver->disconnect, %d", driver->desc.name, error);
	
	return 0;
}
Пример #8
0
int
rwfqueue_init (rwfqueue_t *rwfqueue, uint32_t size, rwfqueue_mode rmode, rwfqueue_mode wmode)
{
    memset(rwfqueue, 0, sizeof(struct rwfqueue));

    if (unlikely(NULL == (rwfqueue->data = (rwfqueue_item_t *)malloc(sizeof(struct rwfqueue_item) * size))))
        LOG_ERROR_AND_RETURN(-1, "failed to malloc, %s", strerror(errno));

    rwfqueue->size = (int32_t)size;
    rwfqueue->count = 0;
    rwfqueue->rmode = rmode;
    rwfqueue->wmode = wmode;
    rwfqueue->head = rwfqueue->data;
    rwfqueue->tail = rwfqueue->data;
    rwfqueue->last = rwfqueue->data + (size-1);
    rwfqueue->stop = 0;

    memset(rwfqueue->data, 0, sizeof(struct rwfqueue_item) * size);

    if (0 != pthread_mutex_init(&rwfqueue->lock, NULL)) {
        LOG1("failed to pthread_mutex_init");
        rwfqueue_destroy(rwfqueue);
        return -2;
    }

    if (0 != pthread_cond_init(&rwfqueue->cond, NULL)) {
        LOG1("failed to pthread_cond_init");
        rwfqueue_destroy(rwfqueue);
        return -3;
    }

    return 0;
}
Пример #9
0
/**
 * Waits for data objects to be pushed onto the incoming data queue. Pops a data object off the
 * queue and passes it to the 'feed' callback. Sleeps until more data is available. Repeat.
 *
 */
void*
__datastream_thread (datastream_t *datastream)
{
	int error;
	dataobject_t *dataobject;
	flist_t *queue;
	void *context;
	void *data;
	uint32_t size;
	
	if (unlikely(datastream == NULL))
		LOG_ERROR_AND_RETURN(NULL, "null datastream_t");
	
	dataobject = NULL;
	data = datastream->data;
	context = datastream->context;
	queue = &datastream->queue;
	
	while (!datastream->stop) {
		if (unlikely(0 != (error = flist_pop(queue, (cobject_t**)&dataobject)))) {
			LOG_ERROR_AND_RETURN(NULL, " failed to flist_pop(), %d", error);
		}
		else if (dataobject == NULL) {
			usleep(10000);
			continue;
		}
		
		memcpy(data, dataobject->data, (size = MIN(datastream->size,dataobject->size)));
		
		dataobject_release(dataobject);
		dataobject = NULL;
		
		if (likely(datastream->feed != NULL))
			if (unlikely(0 != (error = (*datastream->feed)(context, size, data))))
				LOG3("failed to datastream->feed, %d", error);
	}
	
	// release any data objects in our queue
	while (0 == (error = flist_pop(queue, (cobject_t**)&dataobject)) && dataobject != NULL) {
		dataobject_release(dataobject);
		dataobject = NULL;
	}
	
	return datastream;
}
Пример #10
0
static int
__sdriq_data_end (sdriq_t *sdriq)
{
	int error;
	ascp_message_data_t *message;
	
	if (unlikely(0 != (error = core_ascp_message_data(&message))))
		LOG_ERROR_AND_RETURN(-101, "failed to core_ascp_message_data, %d", error);
	
	if (unlikely(message == NULL))
		LOG_ERROR_AND_RETURN(-102, "null ascp_message_data_t");
	
	sdriq->device.data_on = 0;
	
	ascp_data_get(message, ASCP_DATA_END, ASCP_DATA_CON, 0);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)message, &sdriq->device.connection);
	
	return 0;
}
Пример #11
0
static int
__sdriq_connect (sdriq_t *sdriq)
{
	if (unlikely(sdriq == NULL))
		LOG_ERROR_AND_RETURN(-1, "null sdriq_t");
	
	LOG3("[%s]", sdriq->device.desc.name);
	
	return 0;
}
Пример #12
0
/**
 * Pushes the data chunk onto the incoming data chunk queue. The datastream receive thread will see
 * the new data chunk, pop it off, make a copy, and pass it to the "feed" callback.
 */
int
datastream_feed (datastream_t *datastream, dataobject_t *dataobject)
{
	int error;
	
	if (unlikely(datastream == NULL))
		LOG_ERROR_AND_RETURN(-1, "null datastream_t");
	
	if (unlikely(dataobject == NULL))
		LOG_ERROR_AND_RETURN(-2, "null dataobject_t");
	
	// don't accept data for a stopped stream
	if (datastream->stop)
		LOG_ERROR_AND_RETURN(-101, "datastream is stopped. no more data, please");
	
	if (unlikely(0 != (error = flist_push(&datastream->queue, (cobject_t*)dataobject))))
		LOG_ERROR_AND_RETURN(-102, "failed to flist_push(), %d", error);
	
	return 0;
}
Пример #13
0
int
sdriq_isme (device_desc_t *desc)
{
	if (unlikely(desc == NULL))
		LOG_ERROR_AND_RETURN(-1, "null device_desc_t");
	
	if (0 == strcmp(desc->name, "SDR-IQ"))
		return 1;
	
	return 0;
}
Пример #14
0
int
datastream_stop (datastream_t *datastream)
{
	if (unlikely(datastream == NULL))
		LOG_ERROR_AND_RETURN(-1, "null datastream_t");
	
	datastream->stop = 1;
	
	sleep(2);
	
	return 0;
}
Пример #15
0
int
driver_init (driver_t *driver, char *name)
{
	int error;
	size_t name_l;
	
	if (unlikely(driver == NULL))
		LOG_ERROR_AND_RETURN(-1, "[%s] null driver_t", (name==NULL?"null":name));
	
	if (unlikely(name == NULL || (name_l = strlen(name)) == 0))
		LOG_ERROR_AND_RETURN(-2, "[null] null or zero-length name");
	
	if (unlikely(0 != (error = mutex_init(&driver->mutex, LOCK_TYPE_SPIN))))
		LOG_ERROR_AND_RETURN(-101, "[%s] failed to mutex_init, %d", name, error);
	
	if (name_l >= sizeof(driver->desc.name))
		name_l = sizeof(driver->desc.name) - 1;
	
	memcpy(driver->desc.name, name, name_l);
	
	return 0;
}
Пример #16
0
static int
__sdriq_frequency_get (sdriq_t *sdriq)
{
	ascp_message_freq_t message;
	
	if (unlikely(sdriq == NULL))
		LOG_ERROR_AND_RETURN(-1, "null sdriq_t");
	
	ascp_frequency_get(&message);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	
	return 0;
}
Пример #17
0
static int
__sdriq_span_set (sdriq_t *sdriq, uint32_t span)
{
	if (unlikely(sdriq == NULL))
		LOG_ERROR_AND_RETURN(-1, "null sdriq_t");
	
	int error;
	ad6620_t ad6620;
	
	sdriq->device.span = span;
	
	ad6620_init(&ad6620, NULL);
	
	if (unlikely(0 != (error = ad6620_stdcoeffs(&ad6620, span))))
		LOG_ERROR_AND_RETURN(-101, "failed to ad6620_stdcoeffs, %d", error);
	
	if (0 != (error = device_program((device_t*)sdriq, ad6620_chip(&ad6620))))
		LOG_ERROR_AND_RETURN(-102, "failed to device_program, %d", error);
	
	ad6620_destroy(&ad6620);
	
	return 0;
}
Пример #18
0
int
sdriq_alloc (sdriq_t **sdriq, device_desc_t *desc)
{
	int error;
	
	if (unlikely(sdriq == NULL))
		LOG_ERROR_AND_RETURN(-1, "null sdriq_t");
	
	if (unlikely(desc == NULL))
		LOG_ERROR_AND_RETURN(-2, "null device_desc_t");
	
	*sdriq = NULL;
	
	if (unlikely(NULL == (*sdriq = (sdriq_t*)malloc( sizeof(sdriq_t) ))))
		LOG_ERROR_AND_RETURN(-101, "failed to malloc, %s", strerror(errno));
	
	memset(*sdriq, 0, sizeof(sdriq_t));
	
	if (unlikely(0 != (error = sdriq_init(*sdriq, desc))))
		LOG_ERROR_AND_RETURN(-102, "failed to sdriq_init, %d", error);
	
	return 0;
}
Пример #19
0
static int
__sdriq_gain_set (sdriq_t *sdriq, int32_t gain)
{
	ascp_message_gain_t message;
	
	if (unlikely(sdriq == NULL))
		LOG_ERROR_AND_RETURN(-1, "null sdriq_t");
	
	sdriq->device.gain = (int8_t)gain;
	
	ascp_gain_set(&message, 1, (int8_t)gain);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	
	return 0;
}
Пример #20
0
int
datastream_destroy (datastream_t *datastream)
{
	int error;
	
	if (unlikely(datastream == NULL))
		LOG_ERROR_AND_RETURN(-1, "null datasttream_t");
	
	if (datastream->queue.count != 0)
		LOG3("queue is not empty! [count=%llu]", datastream->queue.count);
	
	if (unlikely(0 != (error = flist_destroy(&datastream->queue))))
		LOG_ERROR_AND_RETURN(-101, "failed to flist_destroy, %d", error);
	
	if (datastream->data != NULL) {
		free(datastream->data);
		datastream->data = NULL;
	}
	
	if (unlikely(0 != (error = thread_destroy(&datastream->thread))))
		LOG_ERROR_AND_RETURN(-101, "failed to thread_destroy, %d", error);
	
	return 0;
}
Пример #21
0
static int
__sdriq_message_read (sdriq_t *sdriq)
{
	int error = 0;
	uint32_t count, j, k;
	ascp_message_t *message = NULL;
	
	if (unlikely(sdriq == NULL))
		LOG_ERROR_AND_RETURN(-1, "null sdriq_t");
	
	if (unlikely(0 != (error = ascp_message_read(&sdriq->ascp, &message, &sdriq->device.connection))))
		LOG_ERROR_AND_RETURN(-101, "failed to ascp_message_read(), %d", error);
	
	// unsupported message types result in a null message
	if (message == NULL)
		return 0;
	
	switch (message->code) {
		case ASCP_CODE_DATA:
			{
				ascp_message_data_t *m = (ascp_message_data_t*)message;
				dataobject_t *dataobject = NULL;
				
				// grab a new dataobject_t instance, convert the read data into doubles and place them in
				// the data object. then, for each data stream, hand it the data object. finally, release
				// the data object so that it can be re-used.
				if (m->data[0] != 0) {
					sdriq->device.samples += 1;
					
					if (0 == sdriq->device.samples % 1000)
						LOG3("sdriq->device.samples = %llu", sdriq->device.samples);
					
					if (unlikely(0 != (error = core_dataobject(&dataobject)) || dataobject == NULL))
						LOG_ERROR_AND_GOTO(-102, done, "failed to core_dataobject(), %d", error);
					
					memcpy(dataobject->data, m->data, MIN(sizeof(dataobject->data),sizeof(m->data)));
					dataobject->size = MIN(sizeof(dataobject->data),sizeof(m->data));
					
					count = sizeof(sdriq->device.datastreams) / sizeof(void*);
					
					for (k=0, j=0; k < count && j < sdriq->device.datastreamcnt; ++k) {
						if (sdriq->device.datastreams[k] != NULL) {
							datastream_feed(sdriq->device.datastreams[k], dataobject);
							j++;
						}
					}
					
					dataobject_release(dataobject);
					dataobject = NULL;
				}
				
				break;
			}
		case ASCP_CODE_FREQ:
			{
				eventnumber_t *event = NULL;
				ascp_message_freq_t *m = (ascp_message_freq_t*)message;
				
				LOG3("[%s] got a frequency message!", sdriq->device.desc.name);
				
				sdriq->device.frequency = m->frequency;
				
				if (unlikely(0 == (error = core_misc_eventnumber(&event, sdriq, EVENT_DEVICE_FREQ)) && event != NULL)) {
					event->val.uint32val = m->frequency;
					
					if (unlikely(0 != (error = eventmngr_event_post(core_eventmngr(), (event_t*)event))))
						LOG3("[%s] failed to eventmngr_event_post(EVENT_DEVICE_FREQ), %d", sdriq->device.desc.name, error);
					
					eventnumber_release(event);
					event = NULL;
				}
				else
					LOG3("[%s] failed to core_misc_eventnumber(), %d", sdriq->device.desc.name, error);
				
				break;
			}
		case ASCP_CODE_DACK:
			{
				// programming ack
				break;
			}
		default:
			LOG3("[%s] unsupported message type, 0x%04X", sdriq->device.desc.name, message->code);
			break;
	};
	
done:
	if (message != NULL)
		ascp_message_release(message);
	
	return error;
}
Пример #22
0
static int
__sdriq_program (sdriq_t *sdriq, chip_t *chip)
{
	ad6620_t *ad6620 = (ad6620_t*)chip;
	ascp_message_6620_t message;
	useconds_t time = 4000;
	
	if (unlikely(sdriq == NULL))
		LOG_ERROR_AND_RETURN(-1, "null sdriq_t");
	
	if (unlikely(chip == NULL))
		LOG_ERROR_AND_RETURN(-2, "null chip_t");
	
	if (unlikely(CHIP_AD6620 != chip->type))
		LOG_ERROR_AND_RETURN(-3, "unsupported chip, 0x%04X", (int)chip->type);
	
	memset(&message, 0, sizeof(ascp_message_6620_t));
	
	// mode control register
	ascp_ad6620_set(&message, 0x300, 0x1);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(10000);
	
	// rcf coefficients
	for (uint16_t i = 0; i < 256; ++i) {
		ascp_ad6620_set(&message, i, ad6620->params.coef[i]);
		ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
		usleep(time);
	}
	
	// nco control register
	ascp_ad6620_set(&message, 0x301, 0x0);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// nco sync control register
	ascp_ad6620_set(&message, 0x302, -1);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// nco frequency (NCO_FREQ)
	ascp_ad6620_set(&message, 0x303, 0x0);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// nco phase offset (PHASE_OFFSET)
	ascp_ad6620_set(&message, 0x304, 0x0);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// input/cic2 scale register
	ascp_ad6620_set(&message, 0x305, ad6620->params.scic2);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// mcic2 - 1 ... decimation minus one
	ascp_ad6620_set(&message, 0x306, ad6620->params.mcic2-1);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// scic5 scale register
	ascp_ad6620_set(&message, 0x307, ad6620->params.scic5);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// mcic5 - 1 ... decimation minus one
	ascp_ad6620_set(&message, 0x308, ad6620->params.mcic5-1);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// output / rcf control register
	ascp_ad6620_set(&message, 0x309, ad6620->params.sout);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// mrcf - 1 ... decimation minus one
	ascp_ad6620_set(&message, 0x30A, ad6620->params.mrcf-1);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// rcf address offset register
	ascp_ad6620_set(&message, 0x30B, 0x0);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// taps - 1 ... number of taps minus one
	ascp_ad6620_set(&message, 0x30C, 0xFF);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// reserved
	ascp_ad6620_set(&message, 0x30D, 0x0);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(time);
	
	// update the device's decimation and samplerate values
	sdriq->device.decimation = ad6620->params.scic2 * ad6620->params.scic5 * ad6620->params.mrcf;
	sdriq->device.samplerate = 66666666. / sdriq->device.decimation;
	
	// frequency
	// http://tf.nist.gov/stations/wwv.html
	device_frequency_set((device_t*)sdriq, sdriq->device.frequency);
	usleep(time);
	
	// gain
	device_gain_set((device_t*)sdriq, sdriq->device.gain);
	usleep(time);
	
	// mode control register
	ascp_ad6620_set(&message, 0x300, 0x0);
	ascp_message_send(&sdriq->ascp, (ascp_message_t*)&message, &sdriq->device.connection);
	usleep(100000);
	
	return 0;
}
Пример #23
0
/******************************************************************** 
 * When the client sends the same request the second time, get the
 * header field MY_HDR from the caches response header, print it out
 * and save it in a text file.
 ********************************************************************/
static int
handle_cache_hdr(INKHttpTxn txnp)
{
  LOG_SET_FUNCTION_NAME("handle_cache_hdr");

  INKMBuffer cache_bufp;
  INKMLoc cache_loc = NULL, field_loc = NULL;
  const char *my_hdr;
  int value_count, i, length;
  char output_file[1024], output_str[1024];
  INKFile file;

  output_str[0] = '\0';

  /* get the cached response header */
  if (!INKHttpTxnCachedRespGet(txnp, &cache_bufp, &cache_loc))
    LOG_ERROR_AND_RETURN("INKHttpTxnCachedRespGet");

  /* get the MY_HDR field in the header */
  if ((field_loc = INKMimeHdrFieldFind(cache_bufp, cache_loc, MY_HDR, strlen(MY_HDR))) == INK_ERROR_PTR ||
      field_loc == NULL)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldFind");

  if ((value_count = INKMimeHdrFieldValuesCount(cache_bufp, cache_loc, field_loc)) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldValuesCount");
  for (i = 0; i <= value_count - 1; i++) {
    if (INKMimeHdrFieldValueStringGet(cache_bufp, cache_loc, field_loc, i, &my_hdr, &length) == INK_ERROR)
      LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldValueStringGet");

    /* concatenate the field to output_str */
    if (my_hdr) {
      snprintf(output_str, 1024, "%s MY_HDR(%d): %.*s \n", output_str, i, length, my_hdr);
      INKHandleStringRelease(cache_bufp, field_loc, my_hdr);
    }
  }

  snprintf(output_file, 1024, "%s/write_server_ip.txt", plugin_dir);
  INKDebug(DEBUG_TAG, "Writing record\n%s\nto file %s", output_str, output_file);

  /* append to the text file */
  if (INKMutexLock(file_mutex) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMutexLock");

  if ((file = INKfopen(output_file, "w")) == NULL)
    LOG_ERROR_AND_CLEANUP("INKfopen");
  INKfwrite(file, output_str, strlen(output_str));
  INKfflush(file);
  INKfclose(file);

  if (INKMutexUnlock(file_mutex) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMutexUnlock");

  /* cleanup */
Lcleanup:
  /* release mlocs */
  if (VALID_POINTER(field_loc))
    INKHandleMLocRelease(cache_bufp, cache_loc, field_loc);
  if (VALID_POINTER(cache_loc))
    INKHandleMLocRelease(cache_bufp, INK_NULL_MLOC, cache_loc);

  return 0;
}
Пример #24
0
int
get_client_req(INKHttpTxn txnp, char **p_url_line, char **p_client_req, int *neg_test_val, int *pin_val)
{
  INKMBuffer bufp;
  INKReturnCode ret_code;
  INKMLoc hdr_loc;
  INKMLoc url_loc;
  INKMLoc neg_loc;
  INKMLoc pin_loc;

  INKIOBuffer output_buffer;
  INKIOBufferReader reader;
  int total_avail;

  INKIOBufferBlock block;
  const char *block_start;
  int block_avail;

  char *output_string;
  char *url_str;
  int url_len;
  int output_len;

  LOG_SET_FUNCTION_NAME("get_client_req");

  *p_url_line = NULL;
  *p_client_req = NULL;
  *neg_test_val = 0;
  *pin_val = 0;

#ifdef DEBUG
  if (INKHttpTxnClientReqGet(NULL, &bufp, &hdr_loc) != 0) {
    LOG_ERROR_NEG("INKHttpTxnClientReqGet(null, buf, hdr_loc)");
  }

  if (INKHttpTxnClientReqGet(txnp, NULL, &hdr_loc) != 0) {
    LOG_ERROR_NEG("INKHttpTxnClientReqGet(txnp, null, hdr_loc)");
  }

  if (INKHttpTxnClientReqGet(txnp, &bufp, NULL) != 0) {
    LOG_ERROR_NEG("INKHttpTxnClientReqGet(txnp, buf, null)");
  }
#endif

  if (!INKHttpTxnClientReqGet(txnp, &bufp, &hdr_loc)) {
    LOG_ERROR_AND_RETURN("INKHttpTxnClientReqGet");
  }

  if ((url_loc = INKHttpHdrUrlGet(bufp, hdr_loc)) == INK_ERROR_PTR) {
    INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
    LOG_ERROR_AND_RETURN("INKHttpHdrUrlGet");
  }
#ifdef DEBUG
  if (INKUrlStringGet(NULL, url_loc, &url_len) != INK_ERROR_PTR) {
    LOG_ERROR_NEG("INKUrlStringGet(NULL, url_loc, &int)");
  }

  if (INKUrlStringGet(bufp, NULL, &url_len) != INK_ERROR_PTR) {
    LOG_ERROR_NEG("INKUrlStringGet(bufp, NULL, &int)");
  }
#endif

  if ((url_str = INKUrlStringGet(bufp, url_loc, &url_len)) == INK_ERROR_PTR) {
    INKHandleMLocRelease(bufp, hdr_loc, url_loc);
    INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
    LOG_ERROR_AND_RETURN("INKUrlStringGet");
  }

  if (INKHandleMLocRelease(bufp, hdr_loc, url_loc) == INK_ERROR) {
    INKfree(url_str);
    INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
    LOG_ERROR_AND_RETURN("INKHandleMLocRelease");
  }

  url_str[url_len] = '\0';
  *p_url_line = url_str;

  if ((output_buffer = INKIOBufferCreate()) == INK_ERROR_PTR) {
    INKfree(url_str);
    INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
    LOG_ERROR_AND_RETURN("INKIOBufferCreate");
  }
#ifdef DEBUG
  if (INKIOBufferReaderAlloc(NULL) != INK_ERROR_PTR) {
    LOG_ERROR_NEG("INKIOBufferReaderAlloc(NULL)");
  }
#endif

  if ((reader = INKIOBufferReaderAlloc(output_buffer)) == INK_ERROR_PTR) {
    INKfree(url_str);
    INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
    INKIOBufferDestroy(output_buffer);
    LOG_ERROR_AND_RETURN("INKIOBufferReaderAlloc");
  }

  /* This will print  just MIMEFields and not
     the http request line */
  if (INKMimeHdrPrint(bufp, hdr_loc, output_buffer) == INK_ERROR) {
    INKfree(url_str);
    INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
    INKIOBufferDestroy(output_buffer);
    LOG_ERROR_AND_RETURN("INKMimeHdrPrint");
  }

  if ((neg_loc = INKMimeHdrFieldFind(bufp, hdr_loc, "CacheTester-HostNameSet", -1)) == INK_ERROR_PTR) {
    INKfree(url_str);
    INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
    INKIOBufferDestroy(output_buffer);
    LOG_ERROR_AND_RETURN("INKMimeHdrFieldFind");
  }

  if (neg_loc != NULL) {

    ret_code = INKMimeHdrFieldValueIntGet(bufp, hdr_loc, neg_loc, 0, neg_test_val);
    if (ret_code == INK_ERROR) {
      INKfree(url_str);
      INKHandleMLocRelease(bufp, hdr_loc, neg_loc);
      INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
      INKIOBufferDestroy(output_buffer);
      LOG_ERROR_AND_RETURN("INKMimeHdrFieldValueIntGet");
    }

    if (INKHandleMLocRelease(bufp, hdr_loc, neg_loc) == INK_ERROR) {
      INKfree(url_str);
      INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
      INKIOBufferDestroy(output_buffer);
      LOG_ERROR_AND_RETURN("INKHandleMLocRelease");
    }
  }

  if ((pin_loc = INKMimeHdrFieldFind(bufp, hdr_loc, "CacheTester-Pin", -1)) == INK_ERROR_PTR) {
    INKfree(url_str);
    INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
    INKIOBufferDestroy(output_buffer);
    LOG_ERROR_AND_RETURN("INKMimeHdrFieldFind");
  }

  if (pin_loc != NULL) {

    ret_code = INKMimeHdrFieldValueIntGet(bufp, hdr_loc, pin_loc, 0, pin_val);
    if (ret_code == INK_ERROR) {
      INKfree(url_str);
      INKHandleMLocRelease(bufp, hdr_loc, pin_loc);
      INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
      INKIOBufferDestroy(output_buffer);
      LOG_ERROR_AND_RETURN("INKMimeHdrFieldValueIntGet");
    }

    if (INKHandleMLocRelease(bufp, hdr_loc, pin_loc) == INK_ERROR) {
      INKfree(url_str);
      INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc);
      INKIOBufferDestroy(output_buffer);
      LOG_ERROR_AND_RETURN("INKHandleMLocRelease");
    }
  }

  if (INKHandleMLocRelease(bufp, INK_NULL_MLOC, hdr_loc) == INK_ERROR) {
    INKfree(url_str);
    INKIOBufferDestroy(output_buffer);
    LOG_ERROR_AND_RETURN("INKHandleMLocRelease");
  }

  /* Find out how the big the complete header is by
     seeing the total bytes in the buffer.  We need to
     look at the buffer rather than the first block to
     see the size of the entire header */
  if ((total_avail = INKIOBufferReaderAvail(reader)) == INK_ERROR) {
    INKfree(url_str);
    INKIOBufferDestroy(output_buffer);
    LOG_ERROR_AND_RETURN("INKIOBufferReaderAvail");
  }
#ifdef DEBUG
  if (INKIOBufferReaderAvail(NULL) != INK_ERROR) {
    LOG_ERROR_NEG("INKIOBufferReaderAvail(NULL)");
  }
#endif

  /* Allocate the string with an extra byte for the string
     terminator */
  output_string = (char *) INKmalloc(total_avail + 1);
  output_len = 0;

  /* We need to loop over all the buffer blocks to make
     sure we get the complete header since the header can
     be in multiple blocks */
  block = INKIOBufferReaderStart(reader);

  if (block == INK_ERROR_PTR) {
    INKfree(url_str);
    INKfree(output_string);
    LOG_ERROR_AND_RETURN("INKIOBufferReaderStart");
  }
#ifdef DEBUG
  if (INKIOBufferReaderStart(NULL) != INK_ERROR_PTR) {
    LOG_ERROR_NEG("INKIOBufferReaderStart(NULL)");
  }

  if (INKIOBufferBlockReadStart(NULL, reader, &block_avail) != INK_ERROR_PTR) {
    LOG_ERROR_NEG("INKIOBufferBlockReadStart(null, reader, &int)");
  }

  if (INKIOBufferBlockReadStart(block, NULL, &block_avail) != INK_ERROR_PTR) {
    LOG_ERROR_NEG("INKIOBufferBlockReadStart(block, null, &int)");
  }
#endif

  while (block) {

    block_start = INKIOBufferBlockReadStart(block, reader, &block_avail);

    if (block_start == INK_ERROR_PTR) {
      INKfree(url_str);
      INKfree(output_string);
      LOG_ERROR_AND_RETURN("INKIOBufferBlockReadStart");
    }

    /* FC paranoia: make sure we don't copy more bytes than buffer size can handle */
    if ((output_len + block_avail) > total_avail) {
      INKfree(url_str);
      INKfree(output_string);
      LOG_ERROR_AND_RETURN("More bytes than expected in IOBuffer");
    }

    /* We'll get a block pointer back even if there is no data
       left to read so check for this condition and break out of
       the loop. A block with no data to read means we've exhausted
       buffer of data since if there was more data on a later 
       block in the chain, this block would have been skipped over */
    if (block_avail == 0) {
      break;
    }

    memcpy(output_string + output_len, block_start, block_avail);
    output_len += block_avail;

    /* Consume the data so that we get to the next block */
    if (INKIOBufferReaderConsume(reader, block_avail) == INK_ERROR) {
      INKfree(url_str);
      INKfree(output_string);
      LOG_ERROR_AND_RETURN("INKIOBufferReaderConsume");
    }
#ifdef DEBUG
    if (INKIOBufferReaderConsume(NULL, block_avail) != INK_ERROR) {
      LOG_ERROR_NEG("INKIOBufferReaderConsume(null, int)");
    }

    if (INKIOBufferReaderConsume(reader, -1) != INK_ERROR) {
      LOG_ERROR_NEG("INKIOBufferReaderConsume(reader, -1)");
    }
#endif

    /* Get the next block now that we've consumed the
       data off the last block */
    if ((block = INKIOBufferReaderStart(reader)) == INK_ERROR_PTR) {
      INKfree(url_str);
      INKfree(output_string);
      LOG_ERROR_AND_RETURN("INKIOBufferReaderStart");
    }
  }

  /* Terminate the string */
  output_string[output_len] = '\0';
  /*output_len++; */

  /* Free up the INKIOBuffer that we used to print out the header */
  if (INKIOBufferReaderFree(reader) == INK_ERROR) {
    INKfree(url_str);
    INKfree(output_string);
    LOG_ERROR_AND_RETURN("INKIOBufferReaderFree");
  }
#ifdef DEBUG
  if (INKIOBufferReaderFree(NULL) != INK_ERROR) {
    LOG_ERROR_NEG("INKIOBufferReaderFree(NULL)");
  }
#endif

  if (INKIOBufferDestroy(output_buffer) == INK_ERROR) {
    INKfree(url_str);
    INKfree(output_string);
    LOG_ERROR_AND_RETURN("INKIOBufferDestroy");
  }

  *p_client_req = output_string;
  return 1;
}
Пример #25
0
/***********************************************************************
 * Get the server ip and request method in the client request. Get the 
 * next hop ip from the server response. 
 * Create a new http header field MY_HDR in the server response and 
 * insert server ip, request method and next hop ip into the field as
 * field values.
 ***********************************************************************/
static int
handle_response_hdr(INKCont contp, INKHttpTxn txnp)
{
  LOG_SET_FUNCTION_NAME("handle_response_hdr");

  INKMBuffer resp_bufp;
  INKMLoc resp_loc = NULL;
  INKMLoc field_loc = NULL;
  unsigned int next_hop_ip = 0;
  unsigned int server_ip = 0;
  const char *request_method = NULL;
  char *r_method = NULL;
  int length;
  INKMBuffer req_bufp;
  INKMLoc req_loc = NULL;
  int incoming_port = 0, port = 0;
  char *hostname = NULL;
  int ret_value = -1;

  /* negative test */
#ifdef DEBUG
  if (INKHttpTxnServerIPGet(NULL) != 0)
    LOG_ERROR_NEG("INKHttpTxnServerIPGet");
  if (INKHttpTxnNextHopIPGet(NULL) != 0)
    LOG_ERROR_NEG("INKHttpTxnNextHopIPGet");
  if (INKHttpTxnParentProxyGet(NULL, &hostname, &port) != INK_ERROR)
    LOG_ERROR_NEG("INKHttpTxnParentProxyGet");
#endif

  /* get the server ip */
  if ((server_ip = INKHttpTxnServerIPGet(txnp)) == 0)
    LOG_ERROR_AND_RETURN("INKHttpTxnServerIPGet");

  /* get the request method */
  if (!INKHttpTxnServerReqGet(txnp, &req_bufp, &req_loc))
    LOG_ERROR_AND_RETURN("INKHttpTxnServerReqGet");

  if ((request_method = INKHttpHdrMethodGet(req_bufp, req_loc, &length)) == INK_ERROR_PTR || request_method == NULL)
    LOG_ERROR_AND_CLEANUP("INKHttpHdrMethodGet");

  r_method = INKstrndup(request_method, length);


  /* get the next hop ip */
  if ((next_hop_ip = INKHttpTxnNextHopIPGet(txnp)) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKHttpTxnNextHopIPGet");


  /* get the client incoming port */
  if ((incoming_port = INKHttpTxnClientIncomingPortGet(txnp)) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKHttpTxnClientIncomingPortGet");


  /* get the parent proxy */
  if (INKHttpTxnParentProxyGet(txnp, &hostname, &port) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKHttpTxnParentProxyGet");
  /* If no parent defined in records.config, set hostname to NULL and port to -1 */
  if (hostname == NULL) {
    hostname = "NULL";
    port = -1;
  }

  /* retrieve the server response header */
  if (!INKHttpTxnServerRespGet(txnp, &resp_bufp, &resp_loc))
    LOG_ERROR_AND_CLEANUP("INKHttpTxnServerRespGet");


  /* create and insert into hdr a new mime header field */
  if ((field_loc = INKMimeHdrFieldCreate(resp_bufp, resp_loc)) == INK_ERROR_PTR || field_loc == NULL)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldCreate");
  if (INKMimeHdrFieldAppend(resp_bufp, resp_loc, field_loc) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldAppend");
  if (INKMimeHdrFieldNameSet(resp_bufp, resp_loc, field_loc, MY_HDR, strlen(MY_HDR)) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldNameSet");

  /* Add value to the new mime header field */
  if (INKMimeHdrFieldValueStringInsert(resp_bufp, resp_loc, field_loc, -1, r_method, strlen(r_method)) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldValueStringInsert");
  if (INKMimeHdrFieldValueUintInsert(resp_bufp, resp_loc, field_loc, -1, server_ip) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldValueUintInsert");
  if (INKMimeHdrFieldValueUintInsert(resp_bufp, resp_loc, field_loc, -1, next_hop_ip) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldValueUintInsert");
  if (INKMimeHdrFieldValueIntInsert(resp_bufp, resp_loc, field_loc, -1, incoming_port) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldValueIntInsert");
  if (INKMimeHdrFieldValueIntInsert(resp_bufp, resp_loc, field_loc, -1, port) == INK_ERROR)
    LOG_ERROR_AND_CLEANUP("INKMimeHdrFieldValueIntInsert");

  /* success */
  ret_value = 0;

Lcleanup:
  if (VALID_POINTER(r_method))
    INKfree(r_method);

  /* negative test for INKHandleStringRelease */
#ifdef DEBUG
  if (INKHandleStringRelease(NULL, req_loc, request_method) != INK_ERROR) {
    LOG_ERROR_NEG("INKHandleStringRelease");
  }
#endif

  /* release the buffer handles */
  if (VALID_POINTER(request_method))
    INKHandleStringRelease(req_bufp, req_loc, request_method);
  if (VALID_POINTER(req_loc))
    INKHandleMLocRelease(req_bufp, INK_NULL_MLOC, req_loc);

  /* free the handles and continuation data */
  if (VALID_POINTER(field_loc))
    INKHandleMLocRelease(resp_bufp, resp_loc, field_loc);
  if (VALID_POINTER(resp_loc))
    INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc);

  return ret_value;
}
Пример #26
0
static int
handle_cache_events(INKCont contp, INKEvent event, void *edata)
{
  CACHE_URL_DATA *url_data;
  INKVConn connp = (INKVConn) edata;
  char tempstr[32];

  LOG_SET_FUNCTION_NAME("handle_cache_events");

  url_data = (CACHE_URL_DATA *) INKContDataGet(contp);
  if (url_data == INK_ERROR_PTR) {
    LOG_ERROR_AND_RETURN("INKContDataGet");
  }

  if (event != INK_EVENT_HTTP_TXN_CLOSE) {
    INKReleaseAssert(url_data->magic == MAGIC_ALIVE);
  } else {
    INKReleaseAssert((url_data == NULL) || (url_data->magic == MAGIC_ALIVE));
  }

  switch (event) {
  case INK_EVENT_CACHE_OPEN_READ:
    /*handle_cache_read(); */
    INKDebug(DEBUG_TAG, "INK_EVENT_CACHE_OPEN_READ\n");

    if (url_data->pin_time != 0) {
      sprintf(tempstr, "PIN%d", url_data->pin_time);
    } else {
      sprintf(tempstr, "HIT");
    }
    insert_in_response(url_data->txnp, tempstr);

    if (url_data->pin_time != 0) {

      url_data->write_again_after_remove = 1;

      if (INKCacheRemove(contp, url_data->key) == INK_ERROR_PTR) {
        LOG_ERROR("INKCacheRemove");
        INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
        return -1;
      }
#ifdef DEBUG
      if (INKCacheRemove(NULL, url_data->key) != INK_ERROR_PTR) {
        LOG_ERROR_NEG("INKCacheRemove(NULL, cache_key)");
      }

      if (INKCacheRemove(contp, NULL) != INK_ERROR_PTR) {
        LOG_ERROR_NEG("INKCacheRemove(contp, NULL)");
      }
#endif
      return 0;
    }
#ifdef DEBUG
    if (INKVConnRead(NULL, contp, url_data->bufp, url_data->url_len) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKVConnRead(NULL, contp, bufp, url_len)");
    }

    if (INKVConnRead(connp, NULL, url_data->bufp, url_data->url_len) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKVConnRead(connp, NULL, bufp, url_len)");
    }

    if (INKVConnRead(connp, contp, NULL, url_data->url_len) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKVConnRead(connp, contp, NULL, url_len)");
    }

    if (INKVConnRead(connp, contp, url_data->bufp, -1) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKVConnRead(connp, contp, bufp, -1)");
    }
#endif

    if (INKVConnRead(connp, contp, url_data->bufp, url_data->url_len) == INK_ERROR_PTR) {
      LOG_ERROR("INKVConnRead");
      INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
      return -1;
    }

    break;

  case INK_EVENT_CACHE_OPEN_READ_FAILED:
    /*handle_cache_read_fail(); */
    INKDebug(DEBUG_TAG, "INK_EVENT_CACHE_OPEN_READ_FAILED(%d)\n", edata);

    if (url_data->pin_time != 0) {
      sprintf(tempstr, "PIN%d", url_data->pin_time);
    } else {
      sprintf(tempstr, "MISS");
    }
    insert_in_response(url_data->txnp, tempstr);

    if (url_data->pin_time != 0) {
      INKDebug(DEBUG_TAG, "url Pinned in cache for %d secs", url_data->pin_time);
      if (INKCacheKeyPinnedSet(url_data->key, url_data->pin_time) == INK_ERROR) {
        LOG_ERROR("INKCacheKeyPinnedSet");
        INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
        return -1;
      }
#ifdef DEBUG
      if (INKCacheKeyPinnedSet(NULL, url_data->pin_time) != INK_ERROR) {
        LOG_ERROR_NEG("INKCacheKeyPinnedSet(NULL, pin_time)");
      }

      if (INKCacheKeyPinnedSet(url_data->key, -1) != INK_ERROR) {
        LOG_ERROR_NEG("INKCacheKeyPinnedSet(cache_key, -1)");
      }
#endif
    }

    if (INKCacheWrite(contp, url_data->key) == INK_ERROR_PTR) {
      LOG_ERROR("INKCacheWrite");
      INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
      return -1;
    }
#ifdef DEBUG
    if (INKCacheWrite(contp, NULL) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKCacheWrite(contp, NULL)");
    }

    if (INKCacheWrite(NULL, url_data->key) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKCacheWrite(NULL, url_data->key)");
    }
#endif

    break;

  case INK_EVENT_CACHE_OPEN_WRITE:
    /*handle_cache_write(); */
    INKDebug(DEBUG_TAG, "INK_EVENT_CACHE_OPEN_WRITE\n");

    if (INKIOBufferWrite(url_data->bufp, url_data->url, url_data->url_len) == INK_ERROR) {
      LOG_ERROR("INKIOBufferWrite");
      INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
      return -1;
    }

    url_data->bufp_reader = INKIOBufferReaderAlloc(url_data->bufp);
    if (url_data->bufp_reader == INK_ERROR_PTR) {
      LOG_ERROR("INKIOBufferReaderAlloc");
      INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
      return -1;
    }
#ifdef DEBUG
    if (INKVConnWrite(NULL, contp, url_data->bufp_reader, url_data->url_len) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKVConnWrite(NULL, contp, bufp_reader, url_len");
    }

    if (INKVConnWrite(connp, NULL, url_data->bufp_reader, url_data->url_len) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKVConnWrite(connp, NULL, bufp_reader, url_len");
    }

    if (INKVConnWrite(connp, contp, NULL, url_data->url_len) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKVConnWrite(connp, contp, NULL, url_len");
    }

    if (INKVConnWrite(connp, contp, url_data->bufp_reader, -1) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKVConnWrite(connp, contp, bufp_reader, -1");
    }
#endif

    if (INKVConnWrite(connp, contp, url_data->bufp_reader, url_data->url_len) == INK_ERROR_PTR) {
      LOG_ERROR("INKVConnWrite");
      INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
      return -1;
    }

    break;

  case INK_EVENT_CACHE_OPEN_WRITE_FAILED:
    /*handle_cache_write_fail(); */
    INKDebug(DEBUG_TAG, "INK_EVENT_CACHE_OPEN_WRITE_FAILED(%d)\n", edata);
    INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);

    break;

  case INK_EVENT_CACHE_REMOVE:
    /*handle_cache_remove(); */
    INKDebug(DEBUG_TAG, "INK_EVENT_CACHE_REMOVE\n");

    if (url_data->write_again_after_remove != 0) {

      INKDebug(DEBUG_TAG, "url Pinned in cache for %d secs", url_data->pin_time);
      if (url_data->pin_time != 0) {
        if (INKCacheKeyPinnedSet(url_data->key, url_data->pin_time) == INK_ERROR) {
          LOG_ERROR("INKCacheKeyPinnedSet");
          INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
          return -1;
        }
      }

      if (INKCacheWrite(contp, url_data->key) == INK_ERROR_PTR) {
        LOG_ERROR("INKCacheWrite");
        INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
        return -1;
      }
    } else {
      INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
    }

    break;

  case INK_EVENT_CACHE_REMOVE_FAILED:
    /*handle_cache_remove_fail(); */
    INKDebug(DEBUG_TAG, "INK_EVENT_CACHE_REMOVE_FAILED(%d)\n", edata);
    INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
    break;

  case INK_EVENT_VCONN_READ_READY:
    INKDebug(DEBUG_TAG, "INK_EVENT_VCONN_READ_READY\n");

    if (INKVIOReenable(edata) == INK_ERROR) {
      LOG_ERROR("INKVIOReenable");
    }
#ifdef DEBUG
    if (INKVIOReenable(NULL) != INK_ERROR) {
      LOG_ERROR_NEG("INKVIOReenable");
    }
#endif

    break;

  case INK_EVENT_VCONN_WRITE_READY:
    INKDebug(DEBUG_TAG, "INK_EVENT_VCONN_WRITE_READY\n");

    if (INKVIOReenable(edata) == INK_ERROR) {
      LOG_ERROR("INKVIOReenable");
    }
#ifdef DEBUG
    if (INKVIOReenable(NULL) != INK_ERROR) {
      LOG_ERROR_NEG("INKVIOReenable");
    }
#endif

    break;

  case INK_EVENT_VCONN_READ_COMPLETE:
    INKDebug(DEBUG_TAG, "INK_EVENT_VCONN_READ_COMPLETE\n");
    {
      INKIOBufferBlock blk;
      char *src;
      char dst[MAX_URL_LEN];
      int avail;
      int url_len_from_cache;

      if ((connp = INKVIOVConnGet(edata)) == INK_ERROR_PTR) {
        LOG_ERROR("INKVIOVConnGet");
        INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
        return -1;
      }
#ifdef DEBUG
      if (INKVConnCacheObjectSizeGet(NULL, &url_len_from_cache) != INK_ERROR) {
        LOG_ERROR_NEG("INKVConnCacheObjectSizeGet(NULL, &size)");
      }

      if (INKVConnCacheObjectSizeGet(connp, NULL) != INK_ERROR) {
        LOG_ERROR_NEG("INKVConnCacheObjectSizeGet(inkvconn, NULL)");
      }
#endif

      if (INKVConnCacheObjectSizeGet(connp, &url_len_from_cache) == INK_ERROR) {
        LOG_ERROR("INKVConnCacheObjectSizeGet");
        INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
        return -1;
      }

      if (url_len_from_cache != url_data->url_len) {
        LOG_ERROR("INKVConnCacheObjectSizeGet-mismatch");
        INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
        return -1;
      }

      if ((connp = INKVIOVConnGet(edata)) == INK_ERROR_PTR) {
        LOG_ERROR("INKVIOVConnGet");
        INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
        return -1;
      }
#ifdef DEBUG
      if (INKVIOVConnGet(NULL) != INK_ERROR_PTR) {
        LOG_ERROR_NEG("INKVIOVConnGet(null)");
      }

      if (INKVConnClose(NULL) != INK_ERROR) {
        LOG_ERROR_NEG("INKVConnClose(NULL)");
      }
#endif

      if (INKVConnClose(connp) == INK_ERROR) {
        LOG_ERROR("INKVConnClose");
        INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
        return -1;
      }

      url_data = (CACHE_URL_DATA *) INKContDataGet(contp);
      INKReleaseAssert(url_data->magic == MAGIC_ALIVE);

      url_data->bufp_reader = INKIOBufferReaderAlloc(url_data->bufp);
      blk = INKIOBufferReaderStart(url_data->bufp_reader);
      if (blk == INK_ERROR_PTR) {
        LOG_ERROR("INKIOBufferReaderStart");
        INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
        return -1;
      }

      src = (char *) INKIOBufferBlockReadStart(blk, url_data->bufp_reader, &avail);
      /* FC: make sure we do not copy more than MAX_URL_LEN-1 bytes into dst */
      if (avail < 0) {
        avail = 0;
      }
      avail = (avail < MAX_URL_LEN - 1) ? avail : (MAX_URL_LEN - 1);
      strncpy(dst, src, avail);
      dst[avail] = '\0';

      if (strcmp(dst, url_data->url) != 0) {
        INKDebug(DEBUG_TAG, "URL in cache NO_MATCH\ndst=[%s]\nurl=[%s]\n", dst, url_data->url);
      }
    }
    INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);

    break;

  case INK_EVENT_VCONN_WRITE_COMPLETE:
    INKDebug(DEBUG_TAG, "INK_EVENT_VCONN_WRITE_COMPLETE\n");

    if ((connp = INKVIOVConnGet(edata)) == INK_ERROR_PTR) {
      LOG_ERROR("INKVIOVConnGet");
      INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
      return -1;
    }
#ifdef DEBUG
    if (INKVIOVConnGet(NULL) != INK_ERROR_PTR) {
      LOG_ERROR_NEG("INKVIOVConnGet(null)");
    }

    if (INKVConnClose(NULL) != INK_ERROR) {
      LOG_ERROR_NEG("INKVConnClose(NULL)");
    }
#endif

    if (INKVConnClose(connp) == INK_ERROR) {
      LOG_ERROR("INKVConnClose");
      INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
      return -1;
    }

    INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
    break;

  case INK_EVENT_VCONN_EOS:
    INKDebug(DEBUG_TAG, "INK_EVENT_VCONN_EOS\n");
    break;

  case INK_EVENT_ERROR:
    INKDebug(DEBUG_TAG, "INK_EVENT_ERROR\n");
    INKHttpTxnReenable(url_data->txnp, INK_EVENT_HTTP_CONTINUE);
    break;

  case INK_EVENT_HTTP_TXN_CLOSE:
    INKDebug(DEBUG_TAG, "INK_EVENT_HTTP_TXN_CLOSE\n");

    if (url_data == NULL) {
      INKHttpTxnReenable(edata, INK_EVENT_HTTP_CONTINUE);
      break;
    }

    if (url_data->url != NULL) {
      INKfree(url_data->url);
    }

    if (INKCacheKeyDestroy(url_data->key) == INK_ERROR) {
      LOG_ERROR("INKCacheKeyDestroy");
    }
#ifdef DEBUG
    if (INKCacheKeyDestroy(NULL) != INK_ERROR) {
      LOG_ERROR_NEG("INKCacheKeyDestroy(NULL)");
    }

    if (INKIOBufferDestroy(NULL) != INK_ERROR) {
      LOG_ERROR_NEG("INKIOBufferDestroy(NULL)");
    }
#endif

    if (INKIOBufferDestroy(url_data->bufp) == INK_ERROR) {
      LOG_ERROR("INKIOBufferDestroy");
    }

    url_data->magic = MAGIC_DEAD;
    INKfree(url_data);
    INKContDestroy(contp);
    INKHttpTxnReenable(edata, INK_EVENT_HTTP_CONTINUE);

    break;

  default:
    ;
  }
  return 0;
}
Пример #27
0
int
insert_in_response(INKHttpTxn txnp, char *result_val)
{
  INKMBuffer resp_bufp;
  INKMLoc resp_loc;
  INKMLoc field_loc;

  LOG_SET_FUNCTION_NAME("insert_in_response");

#ifdef DEBUG
  if (INKHttpTxnClientRespGet(NULL, &resp_bufp, &resp_loc) != 0) {
    LOG_ERROR_NEG("INKHttpTxnClientRespGet(null, buf, hdr_loc)");
  }

  if (INKHttpTxnClientRespGet(txnp, NULL, &resp_loc) != 0) {
    LOG_ERROR_NEG("INKHttpTxnClientRespGet(txnp, null, hdr_loc)");
  }

  if (INKHttpTxnClientRespGet(txnp, &resp_bufp, NULL) != 0) {
    LOG_ERROR_NEG("INKHttpTxnClientRespGet(txnp, buf, null)");
  }
#endif

  if (!INKHttpTxnClientRespGet(txnp, &resp_bufp, &resp_loc)) {
    LOG_ERROR_AND_RETURN("INKHttpTxnClientRespGet");
  }

  /* create a new field in the response header */
  if ((field_loc = INKMimeHdrFieldCreate(resp_bufp, resp_loc)) == INK_ERROR_PTR) {
    INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc);
    LOG_ERROR_AND_RETURN("INKMimeHdrFieldCreate");
  }

  /* set its name */
  if (INKMimeHdrFieldNameSet(resp_bufp, resp_loc, field_loc, "CacheTester-Result", 18) == INK_ERROR) {
    INKHandleMLocRelease(resp_bufp, resp_loc, field_loc);
    INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc);
    LOG_ERROR_AND_RETURN("INKMimeHdrFieldNameSet");
  }

  /* set its value */
  if (INKMimeHdrFieldValueStringInsert(resp_bufp, resp_loc, field_loc, -1, result_val, strlen(result_val)) == INK_ERROR) {
    INKHandleMLocRelease(resp_bufp, resp_loc, field_loc);
    INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc);
    LOG_ERROR_AND_RETURN("INKMimeHdrFieldValueIntInsert");
  }

  /* insert it into the header */
  if (INKMimeHdrFieldAppend(resp_bufp, resp_loc, field_loc) == INK_ERROR) {
    INKHandleMLocRelease(resp_bufp, resp_loc, field_loc);
    INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc);
    LOG_ERROR_AND_RETURN("INKMimeHdrFieldAppend");
  }

  if (INKHandleMLocRelease(resp_bufp, resp_loc, field_loc) == INK_ERROR) {
    INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc);
    LOG_ERROR_AND_RETURN("INKHandleMLocRelease");
  }

  if (INKHandleMLocRelease(resp_bufp, INK_NULL_MLOC, resp_loc) == INK_ERROR) {
    LOG_ERROR_AND_RETURN("INKHandleMLocRelease");
  }

  return 1;
}
Пример #28
0
int
main (int argc, char **argv)
{
	int error;
	device_t *device;
	
	iqoffset = calc_offset_iq();
	
	signal(SIGINT, sighandler);
	
	if (0 != (error = memlock_setup()))
		LOG_ERROR_AND_RETURN(EXIT_FAILURE, "failed to memlock_init(), %d", error);
	
	if (0 != (error = core_init()))
		LOG_ERROR_AND_RETURN(EXIT_FAILURE, "failed to core_init(), %d", error);
	
	sleep(1);
	
	if (NULL == (gDevice = device = core_device_get(0)))
		LOG_ERROR_AND_RETURN(EXIT_FAILURE, "failed to core_device_get(0)");
	
	if (0 != (error = device_connect(device)))
		LOG_ERROR_AND_RETURN(EXIT_FAILURE, "failed to device_connect(), %d", error);
	
	device->span = 190;
	device->gain = -10;
	device->frequency = 1040000;
	
	//
	// planar graph
	//
	{
		graphplanar_t *graphplanar = NULL;
		dspchain_t *dspchain = NULL;
		hamming_t *hamming = NULL;
		ooura4_t *ooura4 = NULL;
		average_t *average = NULL;
		cpx2pwr_t *cpx2pwr = NULL;
		smooth_t *smooth = NULL;
		invert_t *invert = NULL;
		datastream_t *datastream = NULL;
		
		if (0 != (error = core_graph_planar(&graphplanar, "Planar") || graphplanar == NULL))
			LOG_ERROR_AND_RETURN(EXIT_FAILURE, "failed to core_graph_planar(), %d", error);
		
		graph_set_axis(graphplanar_graph(graphplanar), GRAPH_AXIS_X, "Frequency", GRAPH_SCALE_LIN, 0., 0., 1024);
		graph_set_axis(graphplanar_graph(graphplanar), GRAPH_AXIS_Y, "Amplitude", GRAPH_SCALE_LIN, 100., 0., 250);
		graph_ready(graphplanar_graph(graphplanar));
		graph_datastream(graphplanar_graph(graphplanar), &datastream);
		graph_dspchain(graphplanar_graph(graphplanar), &dspchain);
		device_datastream_add(device, datastream);
		
		core_dsp_window_hamming(&hamming, ASCP_IQ_COUNT, iqoffset);
		core_dsp_fft_ooura4(&ooura4, ASCP_IQ_COUNT, FFT_DIR_FORWARD);
		core_dsp_other_cpx2pwr(&cpx2pwr, 0., -100.);
		core_dsp_other_average(&average, ASCP_IQ_COUNT/4, 100);
		core_dsp_other_invert(&invert, INVERT_REAL);
		core_dsp_other_smooth(&smooth, 3);
		
		dspchain_add(dspchain, (dsp_t*)hamming, -1);
		dspchain_add(dspchain, (dsp_t*)ooura4, -1);
		dspchain_add(dspchain, (dsp_t*)cpx2pwr, -1);
		dspchain_add(dspchain, (dsp_t*)average, -1);
		dspchain_add(dspchain, (dsp_t*)invert, -1);
		dspchain_add(dspchain, (dsp_t*)smooth, -1);
		
		graph_set_redraw_fp(graphplanar_graph(graphplanar), (graph_redraw_fp_func)graph_redraw, graphplanar);
		graph_set_draw_path_fp(graphplanar_graph(graphplanar), (graph_draw_path_fp_func)graph_draw_path);
		graph_set_draw_line_fp(graphplanar_graph(graphplanar), (graph_draw_line_fp_func)graph_draw_line);
	}
	
	//
	// history graph
	//
	{
		graphhistory_t *graphhistory = NULL;
		dspchain_t *dspchain = NULL;
		hamming_t *hamming = NULL;
		ooura4_t *ooura4 = NULL;
		average_t *average = NULL;
		cpx2pwr_t *cpx2pwr = NULL;
		invert_t *invert = NULL;
		datastream_t *datastream = NULL;
		
		if (0 != (error = core_graph_history(&graphhistory, "History") || graphhistory == NULL))
			LOG_ERROR_AND_RETURN(EXIT_FAILURE, "failed to core_graph_history(), %d", error);
		
		graph_set_axis(graphhistory_graph(graphhistory), GRAPH_AXIS_X, "Frequency", GRAPH_SCALE_LIN, 0., 0., 1024);
		graph_set_axis(graphhistory_graph(graphhistory), GRAPH_AXIS_Y, "Time", GRAPH_SCALE_LIN, 15., 0., 250);
		graph_ready(graphhistory_graph(graphhistory));
		graph_datastream(graphhistory_graph(graphhistory), &datastream);
		graph_dspchain(graphhistory_graph(graphhistory), &dspchain);
		device_datastream_add(device, datastream);
		
		core_dsp_window_hamming(&hamming, ASCP_IQ_COUNT, iqoffset);
		core_dsp_fft_ooura4(&ooura4, ASCP_IQ_COUNT, FFT_DIR_FORWARD);
		core_dsp_other_cpx2pwr(&cpx2pwr, 0., -100.);
		core_dsp_other_invert(&invert, INVERT_REAL);
		core_dsp_other_average(&average, ASCP_IQ_COUNT/4, 100);
		
		dspchain_add(dspchain, (dsp_t*)hamming, -1);
		dspchain_add(dspchain, (dsp_t*)ooura4, -1);
		dspchain_add(dspchain, (dsp_t*)cpx2pwr, -1);
		dspchain_add(dspchain, (dsp_t*)invert, -1);
		dspchain_add(dspchain, (dsp_t*)average, -1);
		
		graph_set_redraw_fp(graphhistory_graph(graphhistory), (graph_redraw_fp_func)graph_redraw, graphhistory);
		graph_set_draw_hist_fp(graphhistory_graph(graphhistory), (graph_draw_hist_fp_func)graph_draw_hist);
		graph_set_draw_path_fp(graphhistory_graph(graphhistory), (graph_draw_path_fp_func)graph_draw_path);
		graph_set_draw_line_fp(graphhistory_graph(graphhistory), (graph_draw_line_fp_func)graph_draw_line);
	}
	
	sleep(1);
	
	if (0 != (error = device_span_set(device, device->span)))
		LOG_ERROR_AND_RETURN(EXIT_FAILURE, "failed to device_span_set(), %d", error);
	
	sleep(1);
	
	if (0 != (error = device_data_start(device)))
		LOG_ERROR_AND_RETURN(EXIT_FAILURE, "failed to device_data_start(), %d", error);
	
	while (1)
		sleep(1);
	
	return EXIT_SUCCESS;
}
Пример #29
0
PassRefPtr<ParsedCookie> CookieManager::parseOneCookie(const URL& url, const String& cookie)
{
    unsigned start = 0;
    unsigned end = cookie.length();

    double curTime = currentTime();
    RefPtr<ParsedCookie> res = ParsedCookie::create(curTime);

    res->setProtocol(url.protocol());

    unsigned tokenEnd = start; // Token end contains the position of the '=' or the end of a token
    unsigned pairEnd = start; // Pair end contains always the position of the ';'

    // Find the first ';' which is not double-quoted and the '=' (if they exist).
    bool foundEqual = false;
    while (pairEnd < end && cookie[pairEnd] != ';') {
        if (cookie[pairEnd] == '=') {
            if (tokenEnd == start) {
                tokenEnd = pairEnd;
                foundEqual = true;
            }
        } else if (cookie[pairEnd] == '"') {
            size_t secondQuotePosition = cookie.find('"', pairEnd + 1);
            if (secondQuotePosition != notFound && secondQuotePosition <= end) {
                pairEnd = secondQuotePosition + 1;
                continue;
            }
        }
        pairEnd++;
    }

    unsigned tokenStart = start;

    bool hasName = false; // This is a hack to avoid changing too much in this brutally brittle code.
    if (tokenEnd != start) {
        // There is a '=' so parse the NAME
        unsigned nameEnd = tokenEnd;

        // The tokenEnd is the position of the '=' so the nameEnd is one less
        nameEnd--;

        // Remove lightweight spaces.
        while (nameEnd && isLightweightSpace(cookie[nameEnd]))
            nameEnd--;

        while (tokenStart < nameEnd && isLightweightSpace(cookie[tokenStart]))
            tokenStart++;

        if (nameEnd + 1 <= tokenStart)
            LOG_ERROR_AND_RETURN("Empty name. Rejecting the cookie");

        String name = cookie.substring(tokenStart, nameEnd + 1 - start);
        res->setName(name);
        hasName = true;
    }

    // Now parse the VALUE
    tokenStart = tokenEnd + 1;
    if (!hasName)
        --tokenStart;

    // Skip lightweight spaces in our token
    while (tokenStart < pairEnd && isLightweightSpace(cookie[tokenStart]))
        tokenStart++;

    tokenEnd = pairEnd;
    while (tokenEnd > tokenStart && isLightweightSpace(cookie[tokenEnd - 1]))
        tokenEnd--;

    String value;
    if (tokenEnd == tokenStart) {
        // Firefox accepts empty value so we will do the same
        value = String();
    } else
        value = cookie.substring(tokenStart, tokenEnd - tokenStart);

    if (hasName)
        res->setValue(value);
    else if (foundEqual)
        return ParsedCookie::create(curTime);
    else
        res->setName(value); // No NAME=VALUE, only NAME

    while (pairEnd < end) {
        // Switch to the next pair as pairEnd is on the ';' and fast-forward any lightweight spaces.
        pairEnd++;
        while (pairEnd < end && isLightweightSpace(cookie[pairEnd]))
            pairEnd++;

        tokenStart = pairEnd;
        tokenEnd = tokenStart; // initialize token end to catch first '='

        while (pairEnd < end && cookie[pairEnd] != ';') {
            if (tokenEnd == tokenStart && cookie[pairEnd] == '=')
                tokenEnd = pairEnd;
            pairEnd++;
        }

        // FIXME : should we skip lightweight spaces here ?

        unsigned length = tokenEnd - tokenStart;
        unsigned tokenStartSvg = tokenStart;

        String parsedValue;
        if (tokenStart != tokenEnd) {
            // There is an equal sign so remove lightweight spaces in VALUE
            tokenStart = tokenEnd + 1;
            while (tokenStart < pairEnd && isLightweightSpace(cookie[tokenStart]))
                tokenStart++;

            tokenEnd = pairEnd;
            while (tokenEnd > tokenStart && isLightweightSpace(cookie[tokenEnd - 1]))
                tokenEnd--;

            parsedValue = cookie.substring(tokenStart, tokenEnd - tokenStart);
        } else {
            // If the parsedValue is empty, initialise it in case we need it
            parsedValue = String();
            // Handle a token without value.
            length = pairEnd - tokenStart;
        }

        // Detect which "cookie-av" is parsed
        // Look at the first char then parse the whole for performance issue
        switch (cookie[tokenStartSvg]) {
        case 'P':
        case 'p' : {
            if (length >= 4 && ((cookie.find("ath", tokenStartSvg + 1, false) - tokenStartSvg) == 1)) {
                // We need the path to be decoded to match those returned from URL::path().
                // The path attribute may or may not include percent-encoded characters. Fortunately
                // if there are no percent-encoded characters, decoding the url is a no-op.
                res->setPath(curl_unescape(parsedValue.utf8().data(), parsedValue.length()));

                // We have to disable the following check because sites like Facebook and
                // Gmail currently do not follow the spec.

                // Check if path attribute is a prefix of the request URI.
                if (!url.path().startsWith(res->path()))
                    LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (path): it does not math the URL", cookie.ascii().data());
            } else
                LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (path)", cookie.ascii().data());
            break;
        }

        case 'D':
        case 'd' : {
            if (length >= 6 && ((cookie.find("omain", tokenStartSvg + 1, false) - tokenStartSvg) == 1)) {
                if (parsedValue.length() > 1 && parsedValue[0] == '"' && parsedValue[parsedValue.length() - 1] == '"')
                    parsedValue = parsedValue.substring(1, parsedValue.length() - 2);

                String host = url.host();

                // Check if the domain contains an embedded dot.
                size_t dotPosition = parsedValue.find(".", 1);
                if (dotPosition == notFound || dotPosition == parsedValue.length())
                    LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (domain): it does not contain an embedded dot", cookie.ascii().data());

                if (isValidIPAddress(host)) {
                    if (parsedValue != host)
                        LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (domain)", cookie.ascii().data());

                } else {
                    // If the domain does not start with a dot, add one for security checks and to distinguish it from host-only domains
                    // For example: ab.c.com dose not domain match b.c.com;
                    if (parsedValue[0] != '.')
                        parsedValue = "." + parsedValue;

                    host = "." + host;

                    if (!host.endsWith(parsedValue, false))
                        LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (domain): it does not domain match the host (%s)", cookie.ascii().data(), host.ascii().data());
                }

                res->setDomain(parsedValue);
            } else
                LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (domain)", cookie.ascii().data());
            break;
        }

        case 'E' :
        case 'e' : {
            if (length >= 7 && ((cookie.find("xpires", tokenStartSvg + 1, false) - tokenStartSvg) == 1))
                res->setExpiry(parsedValue);
            else
                LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (expires)", cookie.ascii().data());
            break;
        }

        case 'M' :
        case 'm' : {
            if (length >= 7 && ((cookie.find("ax-age", tokenStartSvg + 1, false) - tokenStartSvg) == 1))
                res->setMaxAge(parsedValue);
            else
                LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (max-age)", cookie.ascii().data());
            break;
        }

        case 'C' :
        case 'c' : {
            if (length >= 7 && ((cookie.find("omment", tokenStartSvg + 1, false) - tokenStartSvg) == 1))
                // We do not have room for the comment part (and so do Mozilla) so just log the comment.
                LOG(Network, "Comment %s for ParsedCookie : %s\n", parsedValue.ascii().data(), cookie.ascii().data());
            else
                LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (comment)", cookie.ascii().data());
            break;
        }

        case 'V' :
        case 'v' : {
            if (length >= 7 && ((cookie.find("ersion", tokenStartSvg + 1, false) - tokenStartSvg) == 1)) {
                // Although the out-of-dated Cookie Spec(RFC2965, http://tools.ietf.org/html/rfc2965) defined
                // the value of version can only contain DIGIT, some random sites, e.g. https://devforums.apple.com
                // would use double quotation marks to quote the digit. So we need to get rid of them for compliance.
                if (parsedValue.length() > 1 && parsedValue[0] == '"' && parsedValue[parsedValue.length() - 1] == '"')
                    parsedValue = parsedValue.substring(1, parsedValue.length() - 2);

                if (parsedValue.toInt() != 1)
                    LOG_ERROR_AND_RETURN("ParsedCookie version %d not supported (only support version=1)", parsedValue.toInt());
            } else
                LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (version)", cookie.ascii().data());
            break;
        }

        case 'S' :
        case 's' : {
            // Secure is a standalone token ("Secure;")
            if (length >= 6 && ((cookie.find("ecure", tokenStartSvg + 1, false) - tokenStartSvg) == 1))
                res->setSecureFlag(true);
            else
                LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (secure)", cookie.ascii().data());
            break;
        }
        case 'H':
        case 'h': {
            // HttpOnly is a standalone token ("HttpOnly;")
            if (length >= 8 && ((cookie.find("ttpOnly", tokenStartSvg + 1, false) - tokenStartSvg) == 1))
                res->setIsHttpOnly(true);
            else
                LOG_ERROR_AND_RETURN("Invalid cookie attribute %s (HttpOnly)", cookie.ascii().data());
            break;
        }

        default : {
            // If length == 0, we should be at the end of the cookie (case : ";\r") so ignore it
            if (length)
                LOG_ERROR_AND_RETURN("Invalid token for cookie %s", cookie.ascii().data());
            break;
        }
        }
    }

    // Check if the cookie is valid with respect to the size limit.
    if (res->isOverSizeLimit())
        LOG_ERROR_AND_RETURN("ParsedCookie %s is above the 4kb in length : REJECTED", cookie.ascii().data());

    // If no domain was provided, set it to the host
    if (!res->domain())
        res->setDomain(url.host());

    // According to the Cookie Specificaiton (RFC6265, section 4.1.2.4 and 5.2.4, http://tools.ietf.org/html/rfc6265),
    // If no path was provided or the first character of the path value is not '/', set it to the host's path
    //
    // REFERENCE
    // 4.1.2.4. The Path Attribute
    //
    // The scope of each cookie is limited to a set of paths, controlled by
    // the Path attribute. If the server omits the Path attribute, the user
    // agent will use the "directory" of the request-uri's path component as
    // the default value. (See Section 5.1.4 for more details.)
    // ...........
    // 5.2.4. The Path Attribute
    //
    // If the attribute-name case-insensitively matches the string "Path",
    // the user agent MUST process the cookie-av as follows.
    //
    // If the attribute-value is empty or if the first character of the
    // attribute-value is not %x2F ("/"):
    //
    // Let cookie-path be the default-path.
    //
    // Otherwise:
    //
    // Let cookie-path be the attribute-value.
    //
    // Append an attribute to the cookie-attribute-list with an attribute-
    // name of Path and an attribute-value of cookie-path.
    if (!res->path() || !res->path().length() || !res->path().startsWith("/", false)) {
        String path = url.string().substring(url.pathStart(), url.pathAfterLastSlash() - url.pathStart() - 1);
        if (path.isEmpty())
            path = "/";
        // Since this is reading the raw url string, it could contain percent-encoded sequences. We
        // want it to be comparable to the return value of url.path(), which is not percent-encoded,
        // so we must remove the escape sequences.
        res->setPath(curl_unescape(path.utf8().data(), path.length()));
    }

    return res;
}