I am formally a PHP/C# developer and I am new to C. I need you to help to correct my coding with C.
I have a kind of following pieces of HTTP user data string.
char *userData = "=GET /ad26908aa2e811e3855e0a22f2d2d906_8.jpg HTTP/1.1..Host: distilleryimage10.ak.instagram.com..Connection: keep-alive..Accept-Encoding: gzip, deflate..User-Agent: Instagram 4.2.7 (iPhone6,2; iPhone OS 7_0_6; en_US; en) AppleWebKit/420+..Accept-Language: en;q=1, fr;q=0.9, de;q=0.8, ja;q=0.7, nl;q=0.6, it;q=0.5..Accept: */*....";
I need to capture/slice Host
, Query String
and httpmethod
from the above char string.
My function is below.
int diggForUrl(char *userData, HttpData *httpData)
{
const char str_GET[] = "GET";
const char str_POST[] = "POST";
const char str_DELETE[] = "DELETE";
const char str_PUT[] = "PUT";
const char str_HTTP[] = "HTTP";
const char str_HOST[] = "Host:";
char httpMethod[10] = {'\0'};
char *qString = (void *) 0;
char *host = (void *) 0;
char *ptr_SRV_CMD = (void *) 0;
if (ptr_SRV_CMD = strstr (userData, str_GET)) {
strncpy(httpMethod, str_GET, strlen(str_GET));
}
else if (ptr_SRV_CMD = strstr (userData, str_POST)) {
strncpy(httpMethod, str_POST, strlen(str_POST));
}
else if (ptr_SRV_CMD = strstr (userData, str_DELETE)) {
strncpy(httpMethod, str_DELETE, strlen(str_DELETE));
}
else if (ptr_SRV_CMD = strstr (userData, str_PUT)) {
strncpy(httpMethod, str_PUT, strlen(str_PUT));
}
if (ptr_SRV_CMD == NULL)
return -1;
char *ptr_HTTP = strstr(userData, str_HTTP);
if (ptr_HTTP && ptr_SRV_CMD) {
char *ptr_qs_start = ptr_SRV_CMD + strlen(httpMethod) + 1;
// Compare the HTTP position and METHOD position
if (ptr_HTTP > ptr_qs_start) {
// Create query string size
int qsSize = ptr_HTTP - ptr_qs_start;
qString = malloc(qsSize + 1);
memset(qString, '\0', (qsSize + 1));
strncpy(qString, ptr_qs_start, qsSize);
}
}
char *ptr_HOST = strstr(userData, str_HOST);
if (ptr_HOST){
char *ptr_HOST_END = strstr(ptr_HOST, "..");
if (ptr_HOST_END) {
int hostSize = ptr_HOST_END - (ptr_HOST + (strlen(str_HOST) + 1));
host = malloc(hostSize + 1);
memset(host, '\0', hostSize + 1);
strncpy(host, (ptr_HOST + strlen(str_HOST) + 1), hostSize);
}
}
// copy final value of httpMethod char array to char string
httpData->httpMethod = malloc(sizeof(httpMethod) + 1);
memset(httpData->httpMethod, '\0', sizeof(httpMethod) + 1);
strncpy(httpData->httpMethod, httpMethod, sizeof(httpMethod) + 1);
httpData->host = host;
httpData->qString = qString;
return 0;
}
and struct which I am capturing the data into is
typedef struct {
char *httpMethod;
char *host;
char *qString;
} HttpData;
This code runs and give me expected result. Still I feel the coding is not neat and it can be improved. Also, if I run this with valgrind
I am getting the message that there are leaks.
==16470== Memcheck, a memory error detector
==16470== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==16470== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==16470== Command: ./http_data_digg
==16470==
GET
distilleryimage10.ak.instagram.com
/ad26908aa2e811e3855e0a22f2d2d906_8.jpg
==16470==
==16470== HEAP SUMMARY:
==16470== in use at exit: 87 bytes in 3 blocks
==16470== total heap usage: 3 allocs, 0 frees, 87 bytes allocated
==16470==
==16470== LEAK SUMMARY:
==16470== definitely lost: 87 bytes in 3 blocks // <<======= LOST HERE
==16470== indirectly lost: 0 bytes in 0 blocks
==16470== possibly lost: 0 bytes in 0 blocks
==16470== still reachable: 0 bytes in 0 blocks
==16470== suppressed: 0 bytes in 0 blocks
==16470== Rerun with --leak-check=full to see details of leaked memory
==16470==
==16470== For counts of detected and suppressed errors, rerun with: -v
==16470== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 8)
malloc
twice but neverfree
anything. \$\endgroup\$host
andqString
before thereturn
, are you? because then you'd have undefined behaviour on your hands: the memory the struct members point to, then, would be freed... \$\endgroup\$