bool Twitter::query_time(void) { EthernetClient http; if (!http.connect(ip, port)) { println(PSTR("query_time: could not connect to server")); return false; } http_print(&http, PSTR("HEAD ")); if (proxy) { http_print(&http, PSTR("http://")); http_print(&http, server); } http_println(&http, PSTR("/ HTTP/1.1")); http_print(&http, PSTR("Host: ")); http_print(&http, server); http_newline(&http); http_println(&http, PSTR("Connection: close")); http_newline(&http); while (http.connected()) { if (!read_line(&http, buffer, buffer_len)) break; if (buffer[0] == '\0') break; if (process_date_header(buffer)) break; } http.stop(); return basetime != 0L; }
int http_range_complex(TCP_NODE * n, char *filename, size_t filesize, const char *mimetype, char *p_range, size_t * content_length, char *boundary) { char *p_start = NULL; char *p_stop = NULL; char range[BUF_SIZE]; RESPONSE *r_head = NULL, *r_file = NULL, *r_bottom = NULL; /* Boundary head */ if ((r_head = resp_put(n->response, RESPONSE_FROM_MEMORY)) == NULL) { return FALSE; } /* File */ if ((r_file = resp_put(n->response, RESPONSE_FROM_FILE)) == NULL) { return FALSE; } /* Boundary bottom */ if ((r_bottom = resp_put(n->response, RESPONSE_FROM_MEMORY)) == NULL) { return FALSE; } /* Copy range */ memset(range, '\0', BUF_SIZE); strncpy(range, p_range, BUF_OFF1); p_start = range; /* Find separator */ if ((p_stop = strchr(p_start, ',')) != NULL) { *p_stop = '\0'; } /* Parse range. Create file meta data. */ if (!http_range_simple (n, r_file, filename, filesize, p_start, content_length)) { return FALSE; } /* Create boundary header */ http_206_boundary_head(r_head, r_file, filename, filesize, mimetype, boundary, content_length); /* Create boundary bottom */ http_newline(r_bottom, content_length); /* There is more to check */ if (p_stop != NULL) { p_start = p_stop + 1; return http_range_complex(n, filename, filesize, mimetype, p_start, content_length, boundary); } return TRUE; }
void Twitter::http_println(Client *client, const prog_char str[]) { http_print(client, str); http_newline(client); }
bool Twitter::post_status(const char *message) { char *cp; int i; timestamp = get_time(); create_nonce(); compute_authorization(message); /* Post message to twitter. */ EthernetClient http; if (!http.connect(ip, port)) { println(PSTR("Could not connect to server")); return false; } http_print(&http, PSTR("POST ")); if (proxy) { http_print(&http, PSTR("http://")); http_print(&http, server); } http_print(&http, uri); http_println(&http, PSTR(" HTTP/1.1")); http_print(&http, PSTR("Host: ")); http_print(&http, server); http_newline(&http); http_println(&http, PSTR("Content-Type: application/x-www-form-urlencoded")); http_println(&http, PSTR("Connection: close")); /* Authorization header. */ http_print(&http, PSTR("Authorization: OAuth oauth_consumer_key=\"")); url_encode_pgm(buffer, consumer_key); http.write(buffer); http_print(&http, PSTR("\",oauth_signature_method=\"HMAC-SHA1")); http_print(&http, PSTR("\",oauth_timestamp=\"")); sprintf(buffer, "%ld", timestamp); http.write(buffer); http_print(&http, PSTR("\",oauth_nonce=\"")); hex_encode(buffer, nonce, sizeof(nonce)); http.write(buffer); http_print(&http, PSTR("\",oauth_version=\"1.0\",oauth_token=\"")); if (access_token_pgm) url_encode_pgm(buffer, access_token.pgm); else url_encode_eeprom(buffer, access_token.eeprom); http.write(buffer); http_print(&http, PSTR("\",oauth_signature=\"")); cp = base64_encode(buffer, signature, HASH_LENGTH); url_encode(cp + 1, buffer); http.write(cp + 1); http_println(&http, PSTR("\"")); /* Encode content. */ cp = url_encode(buffer, "status"); *cp++ = '='; cp = url_encode(cp, message); int content_length = cp - buffer; sprintf(cp + 1, "%d", content_length); http_print(&http, PSTR("Content-Length: ")); http.write(cp + 1); http_newline(&http); /* Header-body separator. */ http_newline(&http); /* And finally content. */ http.write(buffer); /* Read response status line. */ if (!read_line(&http, buffer, buffer_len) || buffer[0] == '\0') { http.stop(); return false; } int response_code; /* HTTP/1.1 200 Success */ for (i = 0; buffer[i] && buffer[i] != ' '; i++) ; if (buffer[i]) response_code = atoi(buffer + i + 1); else response_code = 0; bool success = (200 <= response_code && response_code < 300); if (!success) Serial.println(buffer); /* Skip header. */ while (true) { if (!read_line(&http, buffer, buffer_len)) { http.stop(); return false; } if (buffer[0] == '\0') break; /* Update our system basetime from the response `Date' header. */ process_date_header(buffer); } /* Handle content. */ while (http.connected()) { while (http.available() > 0) { uint8_t byte = http.read(); if (!success) Serial.write(byte); } delay(100); } http.stop(); if (!success) println(PSTR("")); return success; }
void http_read(TCP_NODE * n, char *p_cmd, char *p_url, char *p_proto, HASH * p_head) { int code = 0; char lastmodified[DATE_SIZE]; char resource[BUF_SIZE]; char filename[BUF_SIZE]; char range[BUF_SIZE]; char *p_range = range; size_t filesize = 0; size_t content_length = 0; char keepalive[BUF_SIZE]; const char *mimetype = NULL; /* Get protocol */ if (!http_proto(n, p_proto)) { node_status(n, NODE_SHUTDOWN); goto END; } /* Get action */ if (!http_action(n, p_cmd)) { node_status(n, NODE_SHUTDOWN); goto END; } /* Get resource */ if (!http_resource(n, p_url, resource)) { node_status(n, NODE_SHUTDOWN); goto END; } /* Check Keep-Alive */ n->keepalive = http_keepalive(p_head, keepalive); /* Compute filename */ if (!http_filename(resource, filename)) { http_404(n, keepalive); info(_log, &n->c_addr, "404 %s", resource); goto END; } /* Compute file size */ filesize = http_size_simple(filename); /* Compute mime type */ mimetype = mime_find(filename); /* Last-Modified. */ if (!http_resource_modified(filename, p_head, lastmodified)) { http_304(n, keepalive); info(_log, &n->c_addr, "304 %s", resource); goto END; } /* Range request? */ if (http_range_detected(p_head, range)) { code = 206; } else { code = 200; } /* Normal 200-er request */ if (code == 200) { info(_log, &n->c_addr, "200 %s", resource); http_200(n, lastmodified, filename, filesize, keepalive, mimetype); http_body(n, filename, filesize); goto END; } /* Check for 'bytes=' in range. Fallback to 200 if necessary. */ if (!http_range_prepare(&p_range)) { info(_log, &n->c_addr, "200 %s", resource); http_200(n, lastmodified, filename, filesize, keepalive, mimetype); http_body(n, filename, filesize); goto END; } /* multipart/byteranges */ if (!http_range_multipart(p_range)) { RESPONSE *r_head = NULL, *r_file = NULL; /* Header */ if ((r_head = resp_put(n->response, RESPONSE_FROM_MEMORY)) == NULL) { node_status(n, NODE_SHUTDOWN); goto END; } /* File */ if ((r_file = resp_put(n->response, RESPONSE_FROM_FILE)) == NULL) { node_status(n, NODE_SHUTDOWN); goto END; } /* Parse range. */ if (!http_range_simple(n, r_file, filename, filesize, p_range, &content_length)) { node_status(n, NODE_SHUTDOWN); goto END; } /* Header with known content_length */ http_206_simple(n, r_head, r_file, lastmodified, filename, filesize, content_length, keepalive, mimetype); info(_log, &n->c_addr, "206 %s [%s]", resource, range); goto END; } else { RESPONSE *r_head = NULL, *r_bottom = NULL, *r_zsyncbug = NULL; char boundary[12]; /* Create boundary string */ http_random(boundary, 12); /* Header */ if ((r_head = resp_put(n->response, RESPONSE_FROM_MEMORY)) == NULL) { node_status(n, NODE_SHUTDOWN); goto END; } /* zsync bug? One more \r\n between header and body. */ if ((r_zsyncbug = resp_put(n->response, RESPONSE_FROM_MEMORY)) == NULL) { node_status(n, NODE_SHUTDOWN); goto END; } /* Parse range. */ if (!http_range_complex (n, filename, filesize, mimetype, p_range, &content_length, boundary)) { node_status(n, NODE_SHUTDOWN); goto END; } /* Bottom */ if ((r_bottom = resp_put(n->response, RESPONSE_FROM_MEMORY)) == NULL) { node_status(n, NODE_SHUTDOWN); goto END; } http_206_boundary_finish(r_bottom, &content_length, boundary); /* Header with known content_length */ http_206_complex(n, r_head, lastmodified, filename, filesize, content_length, boundary, keepalive); /* zsync bug? One more \r\n between header and body. */ http_newline(r_zsyncbug, &content_length); info(_log, &n->c_addr, "206 %s [%s]", resource, range); goto END; } info(_log, &n->c_addr, "FIXME: HTTP parser end reached without result"); node_status(n, NODE_SHUTDOWN); END: /* HTTP Pipeline: There is at least one more request to parse. * Recursive request! Limited by the input buffer. */ if (n->pipeline != NODE_SHUTDOWN && n->recv_size > 0) { http_buf(n); } }