The library with which to configure a Web Socket Server on a Mbed. This lib was coded by a day at least one year before when this description is written. It will be updated adopting mbed os 5.

Dependencies:   mbedTLSLibrary

Dependents:   SIMPLE_WSS

Committer:
aktk
Date:
Sat Mar 03 19:01:29 2018 +0000
Revision:
2:ccaae77f91b8
Put out the HTTP_SERVER lib and copy&pasted just the handler directory from the lib to this.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aktk 2:ccaae77f91b8 1 #include "ResponseMessenger.h"
aktk 2:ccaae77f91b8 2
aktk 2:ccaae77f91b8 3 const char ResponseMessenger::http_ver[9] = "HTTP/1.1";
aktk 2:ccaae77f91b8 4 ResponseMessenger::ResponseMessenger()
aktk 2:ccaae77f91b8 5 {
aktk 2:ccaae77f91b8 6 // Status-Line
aktk 2:ccaae77f91b8 7 status_code = 0;
aktk 2:ccaae77f91b8 8 reason_phrase[0] = '\0';
aktk 2:ccaae77f91b8 9 header_field_buffer[0]='\0';
aktk 2:ccaae77f91b8 10 // Response Header
aktk 2:ccaae77f91b8 11 }
aktk 2:ccaae77f91b8 12 ResponseMessenger::~ResponseMessenger()
aktk 2:ccaae77f91b8 13 {
aktk 2:ccaae77f91b8 14 }
aktk 2:ccaae77f91b8 15 int ResponseMessenger::resetHeader()
aktk 2:ccaae77f91b8 16 {
aktk 2:ccaae77f91b8 17 // Status-Line
aktk 2:ccaae77f91b8 18 status_code = 0;
aktk 2:ccaae77f91b8 19 reason_phrase[0] = '\0';
aktk 2:ccaae77f91b8 20 // Response Header
aktk 2:ccaae77f91b8 21 header_field_buffer[0]='\0';
aktk 2:ccaae77f91b8 22 return 0;
aktk 2:ccaae77f91b8 23 }
aktk 2:ccaae77f91b8 24 int ResponseMessenger::setStatusLine(
aktk 2:ccaae77f91b8 25 int arg_status_code,
aktk 2:ccaae77f91b8 26 const char* arg_reason_phrase
aktk 2:ccaae77f91b8 27 )
aktk 2:ccaae77f91b8 28 {
aktk 2:ccaae77f91b8 29 status_code = arg_status_code;
aktk 2:ccaae77f91b8 30 strcpy(reason_phrase, arg_reason_phrase);
aktk 2:ccaae77f91b8 31
aktk 2:ccaae77f91b8 32 // To be safe on the sage side
aktk 2:ccaae77f91b8 33 reason_phrase[REASON_PHRASE_SIZE - 1] = '\0';
aktk 2:ccaae77f91b8 34 // Send 0 if arg str size is too big, else -1.
aktk 2:ccaae77f91b8 35 if (strlen(arg_reason_phrase) < REASON_PHRASE_SIZE)
aktk 2:ccaae77f91b8 36 return 0;
aktk 2:ccaae77f91b8 37 else
aktk 2:ccaae77f91b8 38 return -1;
aktk 2:ccaae77f91b8 39 }
aktk 2:ccaae77f91b8 40
aktk 2:ccaae77f91b8 41 int ResponseMessenger::setHeaderField(
aktk 2:ccaae77f91b8 42 const char* arg_field_name, const char* arg_field_val)
aktk 2:ccaae77f91b8 43 {
aktk 2:ccaae77f91b8 44 const int nField = 7;
aktk 2:ccaae77f91b8 45 char registered_field_name[nField][32]= {
aktk 2:ccaae77f91b8 46 "Connection",
aktk 2:ccaae77f91b8 47 "Location",
aktk 2:ccaae77f91b8 48 "Keep-Alive",
aktk 2:ccaae77f91b8 49 "Content-Type",
aktk 2:ccaae77f91b8 50 "Upgrade",
aktk 2:ccaae77f91b8 51 "Sec-WebSocket-Accept",
aktk 2:ccaae77f91b8 52 "Access-Control-Allow-Origin"
aktk 2:ccaae77f91b8 53 };
aktk 2:ccaae77f91b8 54 bool flag = false;
aktk 2:ccaae77f91b8 55 char header_field_line_buffer[128];
aktk 2:ccaae77f91b8 56 int buffer_size = strlen(header_field_buffer);
aktk 2:ccaae77f91b8 57
aktk 2:ccaae77f91b8 58 for (int i = 0; i < nField; i++) {
aktk 2:ccaae77f91b8 59 if(strcmp(arg_field_name, registered_field_name[i]) == 0)
aktk 2:ccaae77f91b8 60 flag = true;
aktk 2:ccaae77f91b8 61 }
aktk 2:ccaae77f91b8 62 if(flag) {
aktk 2:ccaae77f91b8 63 sprintf(header_field_line_buffer, "%s: %s\r\n", arg_field_name, arg_field_val);
aktk 2:ccaae77f91b8 64 strcat(header_field_buffer, header_field_line_buffer);
aktk 2:ccaae77f91b8 65 //printf("(RM) header field: \r\n%s\r\n", header_field_buffer);
aktk 2:ccaae77f91b8 66 }
aktk 2:ccaae77f91b8 67 // To be safe on the sage side
aktk 2:ccaae77f91b8 68 header_field_buffer[HEADER_FIELDS_SIZE - 1] = '\0';
aktk 2:ccaae77f91b8 69 // Send 0 if arg str size is too big, else -1.
aktk 2:ccaae77f91b8 70 if (buffer_size + strlen(arg_field_name) + strlen(arg_field_val) < HEADER_FIELDS_SIZE + 1)
aktk 2:ccaae77f91b8 71 return 0;
aktk 2:ccaae77f91b8 72 else
aktk 2:ccaae77f91b8 73 return -1;
aktk 2:ccaae77f91b8 74 }
aktk 2:ccaae77f91b8 75
aktk 2:ccaae77f91b8 76 int ResponseMessenger::setHeaderField(
aktk 2:ccaae77f91b8 77 const char* arg_field_name, int arg_field_val)
aktk 2:ccaae77f91b8 78 {
aktk 2:ccaae77f91b8 79 const int nField = 1;
aktk 2:ccaae77f91b8 80 char registered_field_name[nField][32]= {
aktk 2:ccaae77f91b8 81 "Content-Length"
aktk 2:ccaae77f91b8 82 };
aktk 2:ccaae77f91b8 83 bool flag = false;
aktk 2:ccaae77f91b8 84 char header_field_line_buffer[128];
aktk 2:ccaae77f91b8 85 int buffer_size = strlen(header_field_buffer);
aktk 2:ccaae77f91b8 86
aktk 2:ccaae77f91b8 87 for (int i = 0; i < nField; i++) {
aktk 2:ccaae77f91b8 88 if(strcmp(arg_field_name, registered_field_name[i]) == 0)
aktk 2:ccaae77f91b8 89 flag = true;
aktk 2:ccaae77f91b8 90 }
aktk 2:ccaae77f91b8 91 if(flag) {
aktk 2:ccaae77f91b8 92 sprintf(header_field_line_buffer, "%s: %d\r\n", arg_field_name, arg_field_val);
aktk 2:ccaae77f91b8 93 strcat(header_field_buffer, header_field_line_buffer);
aktk 2:ccaae77f91b8 94 //printf("(RM) header field: \r\n%s\r\n", header_field_buffer);
aktk 2:ccaae77f91b8 95 }
aktk 2:ccaae77f91b8 96 // To be safe on the sage side
aktk 2:ccaae77f91b8 97 header_field_buffer[HEADER_FIELDS_SIZE - 1] = '\0';
aktk 2:ccaae77f91b8 98 // Send 0 if arg str size is too big, else -1.
aktk 2:ccaae77f91b8 99 if (buffer_size + strlen(arg_field_name) + 10 < HEADER_FIELDS_SIZE + 1)
aktk 2:ccaae77f91b8 100 return 0;
aktk 2:ccaae77f91b8 101 else
aktk 2:ccaae77f91b8 102 return -1;
aktk 2:ccaae77f91b8 103 }
aktk 2:ccaae77f91b8 104
aktk 2:ccaae77f91b8 105 int ResponseMessenger::rmHeaderField(
aktk 2:ccaae77f91b8 106 const char* arg_field_name)
aktk 2:ccaae77f91b8 107 {
aktk 2:ccaae77f91b8 108 char* removedLineHead;
aktk 2:ccaae77f91b8 109 char* removedLineEnd;
aktk 2:ccaae77f91b8 110 int buffer_size;
aktk 2:ccaae77f91b8 111
aktk 2:ccaae77f91b8 112 // Look for the head of the line to want to remove
aktk 2:ccaae77f91b8 113 removedLineHead = strstr(header_field_buffer, arg_field_name);
aktk 2:ccaae77f91b8 114 if(removedLineHead == NULL) return -1;
aktk 2:ccaae77f91b8 115 // Look for the first "\r\n" which is the end of the line
aktk 2:ccaae77f91b8 116 removedLineEnd = strstr(removedLineHead, "\r\n");
aktk 2:ccaae77f91b8 117 removedLineEnd += 3; //pointing next line head or '\0' if the line of the last one.
aktk 2:ccaae77f91b8 118 buffer_size = strlen(removedLineEnd);
aktk 2:ccaae77f91b8 119
aktk 2:ccaae77f91b8 120 for(int i = 0; i < buffer_size + 1; i++)
aktk 2:ccaae77f91b8 121 removedLineHead[i] = removedLineEnd[i];
aktk 2:ccaae77f91b8 122
aktk 2:ccaae77f91b8 123 return 0;
aktk 2:ccaae77f91b8 124 }
aktk 2:ccaae77f91b8 125
aktk 2:ccaae77f91b8 126 int ResponseMessenger::getStatusCode()
aktk 2:ccaae77f91b8 127 {
aktk 2:ccaae77f91b8 128 return status_code;
aktk 2:ccaae77f91b8 129 }
aktk 2:ccaae77f91b8 130
aktk 2:ccaae77f91b8 131 char ResponseMessenger::sendHTTPResponse(
aktk 2:ccaae77f91b8 132 TCPSocketConnection &arg_connection)
aktk 2:ccaae77f91b8 133 {
aktk 2:ccaae77f91b8 134 int err_log = 0;
aktk 2:ccaae77f91b8 135 int err_code = 0;
aktk 2:ccaae77f91b8 136 enum {
aktk 2:ccaae77f91b8 137 MAX_BUFFER_SIZE = 1024
aktk 2:ccaae77f91b8 138 };
aktk 2:ccaae77f91b8 139 char buffer[MAX_BUFFER_SIZE] = "\0";
aktk 2:ccaae77f91b8 140
aktk 2:ccaae77f91b8 141 //
aktk 2:ccaae77f91b8 142 // Header
aktk 2:ccaae77f91b8 143 //
aktk 2:ccaae77f91b8 144 printf("(RM) [send]Header\r\n");
aktk 2:ccaae77f91b8 145 // Status Line
aktk 2:ccaae77f91b8 146 sprintf(buffer, "%s %d %s\r\n", http_ver, status_code, reason_phrase);
aktk 2:ccaae77f91b8 147 buffer[MAX_BUFFER_SIZE - 1] = '\0';
aktk 2:ccaae77f91b8 148 err_log = arg_connection.send_all(buffer, strlen(buffer));
aktk 2:ccaae77f91b8 149 if(err_log < 0) err_code = ((err_code << 1) | 1);
aktk 2:ccaae77f91b8 150 // Response Header
aktk 2:ccaae77f91b8 151 err_log = arg_connection.send_all(header_field_buffer, strlen(header_field_buffer));
aktk 2:ccaae77f91b8 152 if(err_log < 0) err_code = ((err_code << 1) | 1);
aktk 2:ccaae77f91b8 153 // Blank line
aktk 2:ccaae77f91b8 154 err_log = arg_connection.send_all("\r\n", strlen("\r\n"));
aktk 2:ccaae77f91b8 155 if(err_log < 0) err_code = ((err_code << 1) | 1);
aktk 2:ccaae77f91b8 156 printf("(RM) [Header has sent]\r\n");
aktk 2:ccaae77f91b8 157 //return error code
aktk 2:ccaae77f91b8 158 return err_code << 2;
aktk 2:ccaae77f91b8 159
aktk 2:ccaae77f91b8 160 }
aktk 2:ccaae77f91b8 161
aktk 2:ccaae77f91b8 162 char ResponseMessenger::sendHTTPResponse(
aktk 2:ccaae77f91b8 163 TCPSocketConnection &arg_connection,
aktk 2:ccaae77f91b8 164 FileHandler &arg_file)
aktk 2:ccaae77f91b8 165 {
aktk 2:ccaae77f91b8 166 int err_log = 0;
aktk 2:ccaae77f91b8 167 int err_code = 0;
aktk 2:ccaae77f91b8 168 enum {
aktk 2:ccaae77f91b8 169 MAX_BUFFER_SIZE = 1024
aktk 2:ccaae77f91b8 170 };
aktk 2:ccaae77f91b8 171 signed char buffer[MAX_BUFFER_SIZE];
aktk 2:ccaae77f91b8 172
aktk 2:ccaae77f91b8 173 //
aktk 2:ccaae77f91b8 174 // Header
aktk 2:ccaae77f91b8 175 //
aktk 2:ccaae77f91b8 176 err_code = sendHTTPResponse(arg_connection);
aktk 2:ccaae77f91b8 177 //
aktk 2:ccaae77f91b8 178 // Body
aktk 2:ccaae77f91b8 179 //
aktk 2:ccaae77f91b8 180 if (arg_file.arrival() && status_code == 200) {
aktk 2:ccaae77f91b8 181 printf("(RM) [send]Body\r\n");
aktk 2:ccaae77f91b8 182 do {
aktk 2:ccaae77f91b8 183 int i = 0;
aktk 2:ccaae77f91b8 184 do {
aktk 2:ccaae77f91b8 185 buffer[i++] = arg_file.getc();//return a byte from file ponter, or -1 if EOF or ERROR
aktk 2:ccaae77f91b8 186 } while ((i < MAX_BUFFER_SIZE - 1) && (buffer[i - 1] != EOF));
aktk 2:ccaae77f91b8 187 if(buffer[i - 1] == EOF)buffer[i - 1] = '\0';
aktk 2:ccaae77f91b8 188 buffer[i] = '\0';
aktk 2:ccaae77f91b8 189 if (!arg_file.hasError()) {
aktk 2:ccaae77f91b8 190 err_log = arg_connection.send_all((char*)buffer, i);
aktk 2:ccaae77f91b8 191 //printf("(RM) buffer log: %s", buffer);
aktk 2:ccaae77f91b8 192 }
aktk 2:ccaae77f91b8 193 if (arg_file.hasError()) printf("(RM)---[ERR]---\r\n");
aktk 2:ccaae77f91b8 194 if (arg_file.atEOF()) printf("(RM)---[EOF]---\r\n");
aktk 2:ccaae77f91b8 195 } while (!arg_file.atEOF() && !arg_file.hasError());
aktk 2:ccaae77f91b8 196 printf("(RM) [Body has sent]\r\n");
aktk 2:ccaae77f91b8 197
aktk 2:ccaae77f91b8 198 if (err_log < 0) err_code = ((err_code) | 2);
aktk 2:ccaae77f91b8 199 if (!arg_file.hasError())err_code = ((err_code) | 1);
aktk 2:ccaae77f91b8 200 } else {
aktk 2:ccaae77f91b8 201 printf("(RM) [No Body]\r\n");
aktk 2:ccaae77f91b8 202 }
aktk 2:ccaae77f91b8 203 return (char)err_code;
aktk 2:ccaae77f91b8 204 }