简体   繁体   English

IPP over HTTP:收到 400 个错误请求作为响应

[英]IPP over HTTP: getting 400 bad request as a response

I'm on iOS and I'm trying to send a HTTP POST request to create a print job on a printer through a Mac which acts as a IPP server.我在 iOS 上,我正在尝试发送 HTTP POST 请求,以通过充当 IPP 服务器的 Mac 在打印机上创建打印作业。 I can correctly print using airprint, I'm trying now to go low-level because I need to send raw data to the printer.我可以使用 airprint 正确打印,我现在正在尝试进行低级别打印,因为我需要将原始数据发送到打印机。

Something about my code:关于我的代码:

Everything is hardcoded.一切都是硬编码的。 I'm still trying to figure out where I go wrong, so I'm just in a development/testing phase.我仍在试图找出我哪里出错了,所以我正处于开发/测试阶段。 The first part is about the definition of the binary structure of an IPP print-job request (and it should be right, according to the RFC 2910 specification).第一部分是关于 IPP 打印作业请求的二进制结构的定义(根据 RFC 2910 规范,它应该是正确的)。

char data[239] = {0x01, 0x01, // IPP version
    0x00, 0x04, // Print-job request
    0x00, 0x00, 0x00, 0x50, // Arbitrary request ID
    0x01, // Attribute group
    // ATT 1
    0x47, // charset value-tag
    0x00, 0x12, // name-length
    'a','t','t','r','i','b','u','t','e','s','-','c','h','a','r','s','e','t', // name
    0x00, 0x05, // value-length
    'u','t','f','-','8', // value
    // ATT 2
    0x48, // natural-language value-tag
    0x00, 0x1B, // name-length
    'a','t','t','r','i','b','u','t','e','s','-','n','a','t','u','r','a','l','-','l','a','n','g','u','a','g','e', // name                       
    0x00, 0x05, // value-length
    'e','n','-','u','s', // value
    // ATT 3
    0x45, // uri type value-tag
    0x00, 0x0B, // name-length
    'p','r','i','n','t','e','r','-','u','r','i', // name
    0x00, 0x47, // value-length
    'i','p','p',':','/','/','A','n','d','r','e','a','s','-','M','a','c','B','o','o','k','-','P','r','o','-','2','.','l','o','c','a','l','.',':','6','3','1','/','p','r','i','n','t','e','r','s','/','H','P','_','D','e','s','k','j','e','t','_','F','4','5','0','0','_','s','e','r','i','e','s', // value
    // ATT 4
    0x42, // requesting user id value-tag
    0x00, 0x14, // name-length
    'r','e','q','u','e','s','t','i','n','g','-','u','s','e','r','-','n','a','m','e', // name
    0x00, 0x05, // value-length
    'g','u','e','s','t', // value
    // ATT 5
    0x49, // document format value-tag
    0x00, 0x0f, // document format
    'd','o','c','u','m','e','n','t','-','f','o','r','m','a','t',
    0x18, // TODO
    'a','p','p','l','i','c','a','t','i','o','n','/','o','c','t','e','t','-','s','t','r','e','a','m',
    0x03, // end of attributes
    't','e','s','t'}; // data

NSMutableData *printJob = [NSMutableData data];
[printJob appendBytes:data length:sizeof(data)];
NSString* requestDataLengthString = [[NSString alloc] initWithFormat:@"%d", [printJob length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://192.168.1.23:631/printers/HP_Deskjet_F4500_series"]];
[request setHTTPMethod:@"POST"];
[request setValue:requestDataLengthString forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/ipp" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"Andreas-MacBook-Pro-2.local" forHTTPHeaderField:@"Host"];
[request setValue:@"CUPS/1.5.0" forHTTPHeaderField:@"User-Agent"];
[request setValue:@"100-continue" forHTTPHeaderField:@"Expect"];
[request setHTTPBody:printJob];

[[NSURLConnection connectionWithRequest:request delegate:self] start];

Whenever I run this code, after 10 seconds I get a HTTP 400 bad request response.每当我运行此代码时,10 秒后我都会收到 HTTP 400 错误请求响应。

The strange thing is that the HTTP request seems perfectly the same as the one I can capture with a packet analyzer whenever the airprint printing sends a print-job to the ipp server (and it works).奇怪的是,每当 airprint 打印向 ipp 服务器发送打印作业时,HTTP 请求似乎与我可以使用数据包分析器捕获的请求完全相同(并且它可以工作)。

You have to use the correct ipp operation code for Print-Job :您必须为Print-Job使用正确的 ipp 操作代码:

  • incorrect: 0x00, 0x04, // =Validate-job request不正确: 0x00, 0x04, // =Validate-job request
  • correct : 0x00, 0x02, // Print-job request正确 : 0x00, 0x02, // Print-job request

You should use document-format text/plain instead of octet-stream .您应该使用文档格式text/plain而不是octet-stream Also make sure the printer supports the data-format or at least make sure CUPS is configured with appropriate converters (It looks like you speak to the HP-printer via CUPS).还要确保打印机支持数据格式或至少确保 CUPS 配置了适当的转换器(看起来您通过 CUPS 与 HP 打印机通话)。

Don't worry about the user-agent , it doesn't matter.不要担心user-agent ,没关系。 Instead take care about your http-protocol-handling!而是要注意您的 http 协议处理! By sending Expect: 100-continue you make CUPS expect chunked http.通过发送Expect: 100-continue可以让 CUPS 期望分块 http。 Don't send the Expect-Header and all should be fine.不要发送Expect-Header ,一切都应该没问题。

Make sure the length of the ipp-request plus data-length is correctly computed and put into the content-length-header.确保正确计算了 ipp-request 的长度加上 data-length 并将其放入 content-length-header 中。

NB: I have implemented a print request in Kotlin .注意:我已经在 Kotlin 中实现了一个打印请求 Porting to Objective-C or Swift should be possible if you find a replacement for DataInputStream , DataOutputStream and know how to POST http requests.如果您找到DataInputStreamDataOutputStream的替代品并且知道如何 POST http 请求,那么移植到 Objective-C 或 Swift 应该是可能的。 I'd be happy to assist you.我很乐意为您提供帮助。

The following prints for me.以下为我打印。 My printer accepts IPP on port 80 as well as 631.我的打印机在端口 80 和 631 上接受 IPP。

// See Print-Job Request sample on page 32 
//   in Appendix A: Protocol Examples 
//   of RFC 2910 IPP/1.1 Encoding and Transport
//     https://tools.ietf.org/html/rfc2910

    char data[239] = {0x01, 0x01, // IPP version
    0x00, 0x02, // Print-job request
    0x00, 0x00, 0x00, 0x50, // Arbitrary request ID
    0x01, // Attribute group
    // ATT 1
    0x47, // charset value-tag
    0x00, 0x12, // name-length
    'a','t','t','r','i','b','u','t','e','s','-','c','h','a','r','s','e','t', // name
    0x00, 0x05, // value-length
    'u','t','f','-','8', // value
    // ATT 2
    0x48, // natural-language value-tag
    0x00, 0x1B, // name-length
    'a','t','t','r','i','b','u','t','e','s','-','n','a','t','u','r','a','l','-','l','a','n','g','u','a','g','e', // name
    0x00, 0x02, // value-length
    'e','n', // value
    // ATT 3
    0x45, // uri type value-tag
    0x00, 0x0B, // name-length
    'p','r','i','n','t','e','r','-','u','r','i', // name
    0x00, 0x1A, // value-length
    'i','p','p',':','/','/','1','7','2','.','0','2','0','.','0','1','0','.','0','0','8',':','0','8','0','/', // value
    // ATT 4
    0x42, // requesting user id value-tag
    0x00, 0x14, // name-length
    'r','e','q','u','e','s','t','i','n','g','-','u','s','e','r','-','n','a','m','e', // name
    0x00, 0x09, // value-length
    'a','s','s','o','c','i','a','t','e', // value
    // ATT 5
    0x49, // document format value-tag
    0x00, 0x0f, // document format
    'd','o','c','u','m','e','n','t','-','f','o','r','m','a','t',
    0x00, 0x0f, // value-length
    'a','p','p','l','i','c','a','t','i','o','n','/','p','d','f',
    0x02, // start job-attributes tag
    0x21, // integer type value-tag
    0x00, 0x06, // name-length
    'c','o','p','i','e','s',
    0x00, 0x04, // value-length
    0x00, 0x00, 0x00, 0x01, // 1 copy
    // could add 'sides' with 'two-sided-long-edge' for double sided prints (see RFC)
    0x03 // end of attributes
    }; // follow with pdf file data

NSMutableData *printJob = [NSMutableData dataWithBytes:data length:sizeof(data)];

NSString *pdfFilePath = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"pdf"];
NSData* pdfData = [NSData dataWithContentsOfFile:pdfFilePath options:NSDataReadingUncached error:NULL];

[printJob appendData:pdfData];

NSString* requestDataLengthString = [[NSString alloc] initWithFormat:@"%ld", [printJob length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://172.020.010.008:080/"]];
[request setHTTPMethod:@"POST"];
[request setValue:requestDataLengthString forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/ipp" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:printJob];

NSError *error;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request
                                             returningResponse:&response
                                                         error:&error];

Something I suggest if you need help seeing working examples of any IPP call formatting is to use ipptool to generate the request and capture it to file.如果您需要帮助查看任何 IPP 调用格式的工作示例,我建议您使用 ipptool 生成请求并将其捕获到文件中。 I could not get Burp proxy to intercept it (even with the http_proxy environment variable), but this node script did the trick:我无法让 Burp 代理拦截它(即使使用 http_proxy 环境变量),但是这个节点脚本做到了:

const http = require('http');
const fs = require('fs');

http.createServer(function (req, res) {

    console.log('Request Received');

    var body = '';

    res.writeHead(200, {
        'Context-Type': 'text/plain',
        'Access-Control-Allow-Origin': '*'
    });

    req.on('data', function (chunk) {
        body += chunk;
    });

    req.on('end', function() {
        fs.writeFileSync('file.txt', body, 'utf8');
        res.end('{"msg": "OK"}');
    })

}).listen(8080, '127.0.0.1'); 
console.log('Server running at http://127.0.0.1:8080/')

Then you can call your node server:然后你可以调用你的节点服务器:

ipptool -vt -f sample.pdf ipp://127.0.0.1:8080/ print-job.test

and inspect the request:并检查请求:

hexdump -C -n256 file.txt

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 iOS 7 中出现错误“Error Domain=com.alamofire.error.serialization.response Code=-1011 ”Request failed: bad request (400)” - Getting error “Error Domain=com.alamofire.error.serialization.response Code=-1011 ”Request failed: bad request (400)" in iOS 7 通过传递字典创建 httpbody 时获取 400(错误请求) - Getting 400(bad request) when created httpbody by passing dictionary POST请求响应400 - POST request response 400 错误域= com.alamofire.error.serialization.response代码= -1011“请求失败:错误请求(400) - Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: bad request (400) Pinterest IOS SDK getBoardPins响应代码= -1011“请求失败:错误请求(400)” - Pinterest IOS SDK getBoardPins response Code=-1011 “Request failed: bad request (400)” iOS HTTP请求-获取错误响应消息 - iOS HTTP request - getting the error response message AFNetworking返回400错误请求 - AFNetworking return 400 bad request Spotify搜索目录请求:400错误的请求 - Spotify Search catalog request : 400 Bad request 请求后请求状态码错误400 - Bad request status code 400 after request Unity 5.1.1f1 Facebook SDK 6.2.2错误400:在iOS上获取播放器图片的错误请求 - Unity 5.1.1f1 Facebook SDK 6.2.2 Error 400: Bad request on getting player picture on iOS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM