void cg_http_packet_read_headers(CgHttpPacket *httpPkt, CgSocket *sock, char *lineBuf, size_t lineBufSize) { CgStringTokenizer *strTok; CgHttpHeader *header; ssize_t readLen; char *name, *value; cg_log_debug_l4("Entering...\n"); while (1) { readLen = cg_socket_readline(sock, lineBuf, lineBufSize); if (readLen <= 2) break; name = NULL; value = NULL; strTok = cg_string_tokenizer_new(lineBuf, CG_HTTP_HEADERLINE_DELIM); if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE) name = cg_string_tokenizer_nexttoken(strTok); if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE) { value = cg_string_tokenizer_nextalltoken(strTok); cg_strrtrim(value, CG_HTTP_HEADERLINE_DELIM, cg_strlen(CG_HTTP_HEADERLINE_DELIM)); } if (0 < cg_strlen(name)) { if (cg_strlen(value) == 0) value = ""; header = cg_http_header_new(); cg_http_header_setname(header, name); cg_http_header_setvalue(header, value); cg_http_packet_addheader(httpPkt, header); } cg_string_tokenizer_delete(strTok); } cg_log_debug_l4("Leaving...\n"); }
size_t cg_http_packet_read_chunk(CgHttpPacket *httpPkt, CgSocket *sock, char *lineBuf, size_t lineBufSize) { ssize_t readLen = 0; ssize_t conLen = 0; int tries = 0; char *content = NULL; cg_log_debug_l4("Entering...\n"); /* Read chunk header */ readLen = cg_socket_readline(sock, lineBuf, lineBufSize); conLen = cg_strhex2long(lineBuf); if (conLen < 1) return 0; content = (char *)malloc(conLen+1); if (content == NULL) { cg_log_debug_s("Memory allocation problem!\n"); return 0; } content[conLen] = 0; readLen = 0; /* Read content until conLen is reached, or tired of trying */ while (readLen < conLen && tries < 20) { readLen += cg_socket_read(sock, (content+readLen), (conLen-readLen)); tries++; } /* Append content to packet */ cg_http_packet_appendncontent(httpPkt, content, readLen); free(content); content = NULL; if (readLen == conLen) { /* Read CRLF bytes */ cg_socket_readline(sock, lineBuf, lineBufSize); } cg_log_debug_l4("Leaving...\n"); return readLen; }
BOOL cg_http_request_read(CgHttpRequest *httpReq, CgSocket *sock) { char lineBuf[CG_HTTP_READLINE_BUFSIZE]; CgStringTokenizer *strTok; int readLen; CgNetURI *uri = NULL; BOOL failed = FALSE; cg_log_debug_l4("Entering...\n"); cg_http_request_clear(httpReq); /* If first character(s) is \n or \r\n we ignore it(them) and read second line. */ do { readLen = cg_socket_readline(sock, lineBuf, sizeof(lineBuf)); } while (readLen >= 1 && readLen <=2); if (readLen <= 0) return FALSE; strTok = cg_string_tokenizer_new(lineBuf, CG_HTTP_STATUSLINE_DELIM); if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE) cg_http_request_setmethod(httpReq, cg_string_tokenizer_nexttoken(strTok)); else failed = TRUE; if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE) cg_http_request_seturi(httpReq, cg_string_tokenizer_nexttoken(strTok)); else failed = TRUE; if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE) cg_http_request_setversion(httpReq, cg_string_tokenizer_nexttoken(strTok)); else failed = TRUE; cg_string_tokenizer_delete(strTok); if (failed == TRUE) return FALSE; /* We could do some further validation for the HTTP-request? */ /* Change URI to be relative (absolute not needed anymore) */ uri = cg_net_uri_new(); if (uri != NULL) { cg_net_uri_set(uri, cg_http_request_geturi(httpReq)); if (cg_net_uri_isabsolute(uri) == TRUE && cg_net_uri_getrequest(uri) != NULL) { cg_http_request_seturi(httpReq, cg_net_uri_getrequest(uri)); } cg_net_uri_delete(uri); uri = NULL; } /* Read headers */ cg_http_packet_clear((CgHttpPacket *)httpReq); cg_http_packet_read_headers((CgHttpPacket *)httpReq, sock, lineBuf, sizeof(lineBuf)); /* HTTP-request must have Content-Length or Transfer-Encoding header in order to have body */ if (cg_http_packet_hasheader((CgHttpPacket *)httpReq, CG_HTTP_CONTENT_LENGTH) || cg_http_packet_hasheader((CgHttpPacket *)httpReq, CG_HTTP_TRANSFER_ENCODING)) cg_http_packet_read_body((CgHttpPacket *)httpReq, sock, lineBuf, sizeof(lineBuf)); cg_log_debug_l4("Leaving...\n"); return TRUE; }