this is called once per transaction when the client sends a req header
| 25 | |
| 26 | // this is called once per transaction when the client sends a req header |
| 27 | bool |
| 28 | handle_client_req(TSCont contp, TSEvent event, Data *const data) |
| 29 | { |
| 30 | switch (event) { |
| 31 | case TS_EVENT_VCONN_READ_READY: |
| 32 | case TS_EVENT_VCONN_READ_COMPLETE: { |
| 33 | if (nullptr == data->m_http_parser) { |
| 34 | data->m_http_parser = TSHttpParserCreate(); |
| 35 | } |
| 36 | |
| 37 | // Read the header from the buffer |
| 38 | int64_t consumed = 0; |
| 39 | if (TS_PARSE_DONE != |
| 40 | data->m_req_hdrmgr.populateFrom(data->m_http_parser, data->m_dnstream.m_read.m_reader, TSHttpHdrParseReq, &consumed)) { |
| 41 | return false; |
| 42 | } |
| 43 | |
| 44 | // update the VIO |
| 45 | TSVIO const input_vio = data->m_dnstream.m_read.m_vio; |
| 46 | TSVIONDoneSet(input_vio, TSVIONDoneGet(input_vio) + consumed); |
| 47 | |
| 48 | // make the header manipulator |
| 49 | HttpHeader header(data->m_req_hdrmgr.m_buffer, data->m_req_hdrmgr.m_lochdr); |
| 50 | |
| 51 | // set the request url back to pristine in case of plugin stacking |
| 52 | header.setUrl(data->m_urlbuf, data->m_urlloc); |
| 53 | |
| 54 | header.setKeyVal(TS_MIME_FIELD_HOST, TS_MIME_LEN_HOST, data->m_hostname, data->m_hostlen); |
| 55 | |
| 56 | // default: whole file (unknown, wait for first server response) |
| 57 | Range rangebe; |
| 58 | |
| 59 | char rangestr[1024]; |
| 60 | int rangelen = sizeof(rangestr); |
| 61 | bool const hasRange = header.valueForKey(TS_MIME_FIELD_RANGE, TS_MIME_LEN_RANGE, rangestr, &rangelen, |
| 62 | 0); // <-- first range only |
| 63 | Config const *const conf = data->m_config; |
| 64 | if (hasRange) { |
| 65 | // write parsed header into slicer meta tag |
| 66 | header.setKeyVal(conf->m_skip_header.c_str(), conf->m_skip_header.size(), rangestr, rangelen); |
| 67 | bool const isRangeGood = rangebe.fromStringClosed(rangestr); |
| 68 | |
| 69 | if (isRangeGood) { |
| 70 | DEBUG_LOG("%p Partial content request", data); |
| 71 | data->m_statustype = TS_HTTP_STATUS_PARTIAL_CONTENT; |
| 72 | } else // signal a 416 needs to be formed and sent |
| 73 | { |
| 74 | DEBUG_LOG("%p Ill formed/unhandled range: %s", data, rangestr); |
| 75 | data->m_statustype = TS_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE; |
| 76 | |
| 77 | // First block will give Content-Length |
| 78 | rangebe = Range(0, conf->m_blockbytes); |
| 79 | } |
| 80 | } else { |
| 81 | DEBUG_LOG("%p Full content request", data); |
| 82 | static char const *const valstr = "-"; |
| 83 | static size_t const vallen = strlen(valstr); |
| 84 | header.setKeyVal(conf->m_skip_header.data(), conf->m_skip_header.size(), valstr, vallen); |
no test coverage detected