// The mother- generic request method. // int RestClient::request(const char* method, String path, String body){ HTTP_DEBUG_PRINT("HTTP: connect\n"); if(client->connect(host, port)){ HTTP_DEBUG_PRINT("HTTP: connected\n"); HTTP_DEBUG_PRINT("REQUEST: \n"); // Make a HTTP request line: String requestString = method; requestString += " "; requestString += path; requestString += " HTTP/1.1"; requestString += "\r\n"; for(int i=0; i<num_headers; i++){ requestString += headers[i]; requestString += "\r\n"; } requestString += "Host: "; requestString += host; requestString += "\r\n"; requestString += "Connection: close"; requestString += "\r\n"; //TODO: deal with binary content if(body != ""){ requestString += "Content-Length: "; requestString += body.length(); requestString += "\r\n"; requestString += "Content-Type: "; requestString += contentType; requestString += "\r\n\r\n"; requestString += body; } requestString += "\r\n\r\n"; client->print(requestString); HTTP_DEBUG_PRINT(requestString); // make sure you've sent all bytes. Ugly hack. // TODO: check output buffer instead? delay(50); HTTP_DEBUG_PRINT("HTTP: call getResponse\n"); int statusCode = getResponse(); HTTP_DEBUG_PRINT("HTTP: return getResponse\n"); //cleanup // only stop if server disconnected. Otherwise you can // get in an infinite loop in getResponse: if (!client->connected()) { HTTP_DEBUG_PRINT("HTTP: stop client\n"); num_headers = 0; //client->stop(); HTTP_DEBUG_PRINT("HTTP: client stopped\n"); } return statusCode; }else{ HTTP_DEBUG_PRINT("HTTP Connection failed\n"); return 0; } }
// The mother- generic request method. // int RestClient::request(const char* method, const char* path, const char* body, String* response){ HTTP_DEBUG_PRINT("HTTP: connect\n"); if(client.connect(host, port)){ HTTP_DEBUG_PRINT("HTTP: connected\n"); HTTP_DEBUG_PRINT("REQUEST: \n"); // Make a HTTP request line: write(method); write(" "); write(path); write(" HTTP/1.1\r\n"); for(int i=0; i<num_headers; i++){ write(headers[i]); write("\r\n"); } write("Host: "); write(host); write("\r\n"); write("Connection: close\r\n"); if(body != NULL){ char contentLength[30]; sprintf(contentLength, "Content-Length: %d\r\n", strlen(body)); write(contentLength); if(!contentTypeSet){ write("Content-Type: application/x-www-form-urlencoded\r\n"); } } write("\r\n"); if(body != NULL){ write(body); write("\r\n"); write("\r\n"); } //make sure you write all those bytes. delay(100); HTTP_DEBUG_PRINT("HTTP: call readResponse\n"); int statusCode = readResponse(response); HTTP_DEBUG_PRINT("HTTP: return readResponse\n"); //cleanup HTTP_DEBUG_PRINT("HTTP: stop client\n"); num_headers = 0; client.stop(); delay(50); HTTP_DEBUG_PRINT("HTTP: client stopped\n"); return statusCode; }else{ HTTP_DEBUG_PRINT("HTTP Connection failed\n"); return 0; } }
void RestClient::write(const char* string){ HTTP_DEBUG_PRINT(string); client.print(string); }
int RestClient::readResponse(String* response) { // an http request ends with a blank line boolean currentLineIsBlank = true; boolean httpBody = false; boolean inStatus = false; char statusCode[4]; int i = 0; int code = 0; if(response == NULL){ HTTP_DEBUG_PRINT("HTTP: NULL RESPONSE POINTER: \n"); }else{ HTTP_DEBUG_PRINT("HTTP: NON-NULL RESPONSE POINTER: \n"); } HTTP_DEBUG_PRINT("HTTP: RESPONSE: \n"); while (client.connected()) { HTTP_DEBUG_PRINT("."); if (client.available()) { HTTP_DEBUG_PRINT(","); char c = client.read(); HTTP_DEBUG_PRINT(c); if(c == ' ' && !inStatus){ inStatus = true; } if(inStatus && i < 3 && c != ' '){ statusCode[i] = c; i++; } if(i == 3){ statusCode[i] = '\0'; code = atoi(statusCode); } //only write response if its not null if(httpBody){ if(response != NULL) response->concat(c); } if (c == '\n' && httpBody){ HTTP_DEBUG_PRINT("HTTP: return readResponse2\n"); return code; } if (c == '\n' && currentLineIsBlank) { httpBody = true; } if (c == '\n') { // you're starting a new lineu currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } HTTP_DEBUG_PRINT("HTTP: return readResponse3\n"); return code; }
int RestClient::getResponse() { this->requestStart = millis(); // an http request ends with a blank line boolean currentLineIsBlank = true; boolean httpBody = false; boolean inStatus = false; // clear response string: this->responseBody = ""; char statusCode[4]; int i = 0; int code = 0; HTTP_DEBUG_PRINT("HTTP: RESPONSE: \n"); while (client->connected()) { // HTTP_DEBUG_PRINT("."); if (client->available()) { // HTTP_DEBUG_PRINT(","); char c = client->read(); HTTP_DEBUG_PRINT(c); if(c == ' ' && !inStatus){ inStatus = true; } if(inStatus && i < 3 && c != ' '){ statusCode[i] = c; i++; } if(i == 3){ statusCode[i] = '\0'; code = atoi(statusCode); } if(httpBody){ // add this char tot the responseBody this->responseBody += c; } else { if (c == '\n' && currentLineIsBlank) { httpBody = true; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } else { // there is a condition where client connects // and available() always <= 0. So timeout is here to catch that: if (millis() - this->requestStart > this->timeout) return 0; } } HTTP_DEBUG_PRINT("HTTP: return getResponse3\n"); return code; }