Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
void
Twitter::http_println(Client *client, const prog_char str[])
{
  http_print(client, str);
  http_newline(client);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
	}
}