Skip to content

Commit

Permalink
Spike towards server-controlled immediate printing.
Browse files Browse the repository at this point in the history
This relates to #8, and explores using a single encoded header to
simplify parsing of more complex parameters from the server.
  • Loading branch information
lazyatom committed Mar 8, 2013
1 parent 7381e7f commit 63ce11e
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 7 deletions.
2 changes: 2 additions & 0 deletions config.ru
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Sass::Plugin.options[:template_location] = 'public/stylesheets'
use Sass::Plugin::Rack

use Rack::MethodOverride
use Printer::BackendServer::EncodedStatusHeaderMiddleare
use Rack::ContentLength

if ENV["RESQUE_SERVER"]
require 'resque/server'
Expand Down
3 changes: 3 additions & 0 deletions lib/printer/backend_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ module Printer::BackendServer
autoload :Settings, "printer/backend_server/settings"
autoload :Archive, "printer/backend_server/archive"

autoload :EncodedStatusHeaderMiddleware,
"printer/backend_server/encoded_status_header_middleware"

App = Rack::Builder.new do
map("/printer") { run Printer::BackendServer::Polling }
map("/preview") { run Printer::BackendServer::Preview }
Expand Down
21 changes: 21 additions & 0 deletions lib/printer/backend_server/encoded_status_header_middleware.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Printer::BackendServer::EncodedStatusHeaderMiddleware
def initialize(app)
@app = app
end

def call(env)
status, headers, body = @app.call(env)
headers.merge!("X-Printer-Encoded-Status" => encoded_status(status, headers))
[status, headers, body]
end

private

def encoded_status(status, headers)
[status, headers["Content-length"], encoded_presence(headers["X-Printer-PrintImmediately"])].compact.join("|")
end

def encoded_presence(header)
header ? 1 : 0
end
end
21 changes: 14 additions & 7 deletions printer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ boolean downloadWaiting = false;
char cacheFilename[] = "TMP";
unsigned long content_length = 0;
boolean statusOk = false;
boolean printImmediately = false;

void checkForDownload() {
unsigned long length = 0;
Expand Down Expand Up @@ -183,19 +184,25 @@ void checkForDownload() {
client.println();
boolean parsingHeader = true;

char header[2000];

while(client.connected()) {
while(client.available()) {
if (parsingHeader) {
client.find((char*)"HTTP/1.1 ");
char statusCode[] = "xxx";
client.readBytes(statusCode, 3);
statusOk = (strcmp(statusCode, "200") == 0);
client.find((char*)"Content-Length: ");
client.find((char*)"X-Printer-Encoded-Status: ");
char *buffer = "xxxxxxxxxx";
client.readBytesUntil('|', buffer, 100);
statusOk = (strcmp(buffer, "200") == 0);
client.readBytesUntil('|', buffer, 100);
char c;
while (isdigit(c = client.read())) {
content_length = content_length*10 + (c - '0');
}
debug2("Content length: ", content_length);
debug2("Content-length: ", content_length);
if (client.readBytesUntil('\n', buffer, 5)) {
printImmediately = (buffer[0] == '1');
}
debug2("Print immediately: ", printImmediately);
client.find((char*)"\n\r\n"); // the first \r may already have been read above
parsingHeader = false;
} else {
Expand Down Expand Up @@ -285,7 +292,7 @@ Bounce bouncer = Bounce(buttonPin, 5); // 5 millisecond debounce
void loop() {
if (downloadWaiting) {
bouncer.update();
if (bouncer.read() == HIGH) {
if (bouncer.read() == HIGH || printImmediately) {
printFromDownload();
}
} else {
Expand Down
45 changes: 45 additions & 0 deletions test/backend_server/encoded_status_header_middleware_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require "test_helper"
require "rack/test"
require "printer/backend_server"

ENV['RACK_ENV'] = 'test'

describe Printer::BackendServer::EncodedStatusHeaderMiddleware do
include Rack::Test::Methods

def app
Rack::Builder.new do
use Printer::BackendServer::EncodedStatusHeaderMiddleware
use Rack::ContentLength
run lambda { |env|
headers = env["PATH_INFO"] == "/print-now" ? {"X-Printer-PrintImmediately" => true} : {}
[200, headers, ["Response body"]]
}
end
end

describe "making a request" do
before do
get "anything"
end

it "includes the encoded header" do
assert last_response.headers.keys.include?("X-Printer-Encoded-Status")
end

it "encodes the status in the header" do
last_response.headers["X-Printer-Encoded-Status"].split("|")[0].must_equal "200"
end

it "encodes the content length in the header" do
last_response.headers["X-Printer-Encoded-Status"].split("|")[1].must_equal "Response body".length.to_s
end
end

describe "making a request where the X-Printer-PrintImmediately header is present" do
it "encodes the print immediately value into the header" do
get "/print-now"
last_response.headers["X-Printer-Encoded-Status"].split("|")[2].must_equal "1"
end
end
end

0 comments on commit 63ce11e

Please sign in to comment.