1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #pragma once 20 21 #include "fcgi_protocol.h" 22 #include <atscppapi/noncopyable.h> 23 #include <iterator> 24 #include <map> 25 #include <string> 26 #include <ts/ts.h> 27 #include <cstring> //for memcpy 28 29 #define BUF_SIZE 5000 30 31 /* Bytes from LSB to MSB 0..3 */ 32 33 #define BYTE_0(x) ((x)&0xff) 34 #define BYTE_1(x) ((x) >> 8 & 0xff) 35 #define BYTE_2(x) ((x) >> 16 & 0xff) 36 #define BYTE_3(x) ((x) >> 24 | 0x80) 37 38 typedef unsigned char uchar; 39 40 #define PRINT_OPAQUE_STRUCT(p) print_mem((p), sizeof(*(p))) 41 42 #define FCGI_PROCESS_AGAIN 1 43 #define FCGI_PROCESS_DONE 2 44 #define FCGI_PROCESS_ERR 3 45 46 namespace ats_plugin 47 { 48 using namespace atscppapi; 49 50 typedef enum { 51 fcgi_state_version = 0, 52 fcgi_state_type, 53 fcgi_state_request_id_hi, 54 fcgi_state_request_id_lo, 55 fcgi_state_content_len_hi, 56 fcgi_state_content_len_lo, 57 fcgi_state_padding_len, 58 fcgi_state_reserved, 59 fcgi_state_content_begin, 60 fcgi_state_content_proc, 61 fcgi_state_padding, 62 fcgi_state_done 63 } FCGI_State; 64 65 struct FCGIClientState; 66 67 struct FCGIRecordList { 68 FCGI_Header *header; 69 FCGI_EndRequestBody *endBody; 70 uchar *content; 71 FCGI_State state; 72 73 size_t length, offset; 74 FCGIRecordListFCGIRecordList75 FCGIRecordList() : content(nullptr), state(FCGI_State::fcgi_state_version), length(0), offset(0) 76 { 77 header = (FCGI_Header *)TSmalloc(sizeof(FCGI_Header)); 78 memset(header, 0, sizeof(FCGI_Header)); 79 endBody = (FCGI_EndRequestBody *)TSmalloc(sizeof(FCGI_EndRequestBody)); 80 memset(endBody, 0, sizeof(FCGI_EndRequestBody)); 81 }; 82 ~FCGIRecordListFCGIRecordList83 ~FCGIRecordList() 84 { 85 TSfree(header); 86 TSfree(content); 87 } 88 }; 89 90 class FCGIClientRequest 91 { 92 public: 93 std::string postData; 94 FCGIClientRequest(int request_id, TSHttpTxn txn); 95 ~FCGIClientRequest(); 96 97 std::map<std::string, std::string> GenerateFcgiRequestHeaders(); 98 void printFCGIRequestHeaders(); 99 100 // Request Creation 101 FCGI_BeginRequest *createBeginRequest(); 102 FCGI_Header *createHeader(unsigned char type); 103 void postBodyChunk(); 104 void emptyParam(); 105 106 void serialize(uchar *buffer, void *st, size_t size); 107 void fcgiHeaderSetRequestId(FCGI_Header *h, int request_id); 108 void fcgiHeaderSetContentLen(FCGI_Header *h, uint16_t len); 109 uint32_t fcgiHeaderGetContentLen(FCGI_Header *h); 110 uint32_t serializeNameValue(uchar *buffer, const std::pair<std::string, std::string> &it); 111 unsigned char *addClientRequest(int &); 112 113 // Response Decoding member functions 114 bool fcgiProcessBuffer(uchar *beg_buf, uchar *end_buf, std::ostringstream &output); 115 FCGIRecordList *fcgiRecordCreate(); 116 int fcgiProcessHeader(uchar ch, FCGIRecordList *rec); 117 int fcgiProcessContent(uchar **beg_buf, uchar *end_buf, FCGIRecordList *rec); 118 int fcgiProcessRecord(uchar **beg_buf, uchar *end_buf, FCGIRecordList *rec); 119 120 bool fcgiDecodeRecordChunk(uchar *beg_buf, size_t remain, std::ostringstream &output); 121 122 void print_bytes(uchar *buf, int n); 123 124 protected: 125 struct FCGIClientState *state_; 126 127 private: 128 bool first_chunk; 129 FCGIRecordList *_headerRecord; 130 }; 131 } // namespace ats_plugin 132