The lib with which to make LPC1768 a simple HTTP server. This have not yet implemented. fopen() DOESN'T WORK after EthernetInterface::connect() is called as using mbed-os 5.4~. See also https://os.mbed.com/questions/80658/HardFault-occurs-when-fopen-is-called-af/ or https://github.com/ARMmbed/mbed-os/issues/6578 and https://github.com/ARMmbed/mbed-os/issues/6624

Fork of HTTP_SERVER by Akifumi Takahashi

Committer:
aktk
Date:
Sat Nov 26 18:06:53 2016 +0000
Revision:
2:33714d7c0f45
Parent:
1:3a1fe94c6e42
Child:
3:59884bc0a238
attempting to notice the request to upgrade it to websocket.

Who changed what in which revision?

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