Reintroduce BUrlResult and add BDataRequest
* BUrlResult is back, with ContentType and Length methods. * BHttpResult subclasses it and use HTTP header fields to implement those * Introduce BDataRequest for "data" URIs. These embed the data inside the URI, either as plaintext or base64 encoded.
This commit is contained in:
parent
d43ede6002
commit
824dd0a834
29
headers/os/net/DataRequest.h
Normal file
29
headers/os/net/DataRequest.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2013 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Adrien Destugues, pulkomandy@pulkomandy.tk
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _B_DATA_REQUEST_H_
|
||||
#define _B_DATA_REQUEST_H_
|
||||
|
||||
|
||||
#include <UrlRequest.h>
|
||||
|
||||
|
||||
class BDataRequest: public BUrlRequest {
|
||||
public:
|
||||
BDataRequest(const BUrl& url,
|
||||
BUrlProtocolListener* listener = NULL,
|
||||
BUrlContext* context = NULL);
|
||||
const BUrlResult& Result() const;
|
||||
private:
|
||||
status_t _ProtocolLoop();
|
||||
private:
|
||||
BUrlResult fResult;
|
||||
};
|
||||
|
||||
#endif
|
@ -19,10 +19,13 @@ public:
|
||||
BUrlContext* context = NULL);
|
||||
virtual ~BFileRequest();
|
||||
|
||||
const BUrlResult& Result() const;
|
||||
void SetDisableListener(bool disable);
|
||||
|
||||
private:
|
||||
status_t _ProtocolLoop();
|
||||
private:
|
||||
BUrlResult fResult;
|
||||
};
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
const ssize_t size = -1);
|
||||
void AdoptHeaders(BHttpHeaders* const headers);
|
||||
|
||||
const BHttpResult& Result() const;
|
||||
const BUrlResult& Result() const;
|
||||
const char* StatusString(status_t threadStatus) const;
|
||||
|
||||
static bool IsInformationalStatusCode(int16 code);
|
||||
|
@ -2,22 +2,22 @@
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_RESULT_H_
|
||||
#define _B_URL_RESULT_H_
|
||||
#ifndef _B_HTTP_RESULT_H_
|
||||
#define _B_HTTP_RESULT_H_
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <DataIO.h>
|
||||
#include <HttpHeaders.h>
|
||||
#include <String.h>
|
||||
#include <Url.h>
|
||||
#include <UrlResult.h>
|
||||
|
||||
|
||||
class BUrlRequest;
|
||||
|
||||
|
||||
class BHttpResult {
|
||||
class BHttpResult: public BUrlResult {
|
||||
friend class BHttpRequest;
|
||||
|
||||
public:
|
||||
@ -30,6 +30,8 @@ public:
|
||||
|
||||
// Result parameters access
|
||||
const BUrl& Url() const;
|
||||
BString ContentType() const;
|
||||
size_t Length() const;
|
||||
|
||||
// HTTP-Specific stuff
|
||||
const BHttpHeaders& Headers() const;
|
||||
@ -45,7 +47,6 @@ public:
|
||||
private:
|
||||
BUrl fUrl;
|
||||
|
||||
// TODO: HTTP specific stuff should not live here.
|
||||
BHttpHeaders fHeaders;
|
||||
int32 fStatusCode;
|
||||
BString fStatusString;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <Url.h>
|
||||
#include <UrlContext.h>
|
||||
#include <UrlProtocolListener.h>
|
||||
#include <UrlResult.h>
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
@ -43,6 +44,7 @@ public:
|
||||
status_t Status() const;
|
||||
virtual const char* StatusString(status_t threadStatus)
|
||||
const;
|
||||
virtual const BUrlResult& Result() const = 0;
|
||||
|
||||
|
||||
protected:
|
||||
|
27
headers/os/net/UrlResult.h
Normal file
27
headers/os/net/UrlResult.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _B_URL_RESULT_H_
|
||||
#define _B_URL_RESULT_H_
|
||||
|
||||
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BUrlResult {
|
||||
public:
|
||||
virtual ~BUrlResult();
|
||||
void SetContentType(BString contentType);
|
||||
void SetLength(size_t length);
|
||||
|
||||
virtual BString ContentType() const;
|
||||
virtual size_t Length() const;
|
||||
|
||||
private:
|
||||
BString fContentType;
|
||||
BString fCharset;
|
||||
size_t fLength;
|
||||
};
|
||||
|
||||
#endif
|
106
src/kits/network/libnetapi/DataRequest.cpp
Normal file
106
src/kits/network/libnetapi/DataRequest.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2013 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Adrien Destugues, pulkomandy@pulkomandy.tk
|
||||
*/
|
||||
|
||||
|
||||
#include "DataRequest.h"
|
||||
|
||||
#include <HttpAuthentication.h>
|
||||
#include <mail_encoding.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
BDataRequest::BDataRequest(const BUrl& url, BUrlProtocolListener* listener,
|
||||
BUrlContext* context)
|
||||
: BUrlRequest(url, listener, context, "data URL parser", "data"),
|
||||
fResult()
|
||||
{
|
||||
fResult.SetContentType("text/plain");
|
||||
}
|
||||
|
||||
|
||||
const BUrlResult&
|
||||
BDataRequest::Result() const
|
||||
{
|
||||
return fResult;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDataRequest::_ProtocolLoop()
|
||||
{
|
||||
BString mimeType;
|
||||
BString charset;
|
||||
const char* payload;
|
||||
size_t length;
|
||||
bool isBase64 = false;
|
||||
|
||||
fUrl.UrlDecode(true);
|
||||
BString data = fUrl.Path();
|
||||
int separatorPosition = data.FindFirst(',');
|
||||
|
||||
if (fListener != NULL)
|
||||
fListener->ConnectionOpened(this);
|
||||
|
||||
if (separatorPosition >= 0) {
|
||||
BString meta = data;
|
||||
meta.Truncate(separatorPosition);
|
||||
data.Remove(0, separatorPosition + 1);
|
||||
|
||||
int pos = 0;
|
||||
while(meta.Length() > 0)
|
||||
{
|
||||
// Extract next parameter
|
||||
pos = meta.FindFirst(';', pos);
|
||||
|
||||
BString parameter = meta;
|
||||
if(pos >= 0) {
|
||||
parameter.Truncate(pos);
|
||||
meta.Remove(0, pos+1);
|
||||
} else
|
||||
meta.Truncate(0);
|
||||
|
||||
// Interpret the parameter
|
||||
if(parameter == "base64") {
|
||||
isBase64 = true;
|
||||
} else if(parameter.FindFirst("charset=") == 0) {
|
||||
charset = parameter;
|
||||
} else {
|
||||
// Must be the MIME type
|
||||
mimeType = parameter;
|
||||
}
|
||||
}
|
||||
|
||||
if (charset.Length() > 0)
|
||||
mimeType << ";" << charset;
|
||||
fResult.SetContentType(mimeType);
|
||||
}
|
||||
|
||||
if (isBase64) {
|
||||
char* buffer = new char[data.Length() * 4 / 3];
|
||||
payload = buffer;
|
||||
// payload must be a const char* so we can assign data.String() to
|
||||
// it below, but decode_64 modifies buffer.
|
||||
length = decode_base64(buffer, data.String(), data.Length());
|
||||
} else {
|
||||
payload = data.String();
|
||||
length = data.Length();
|
||||
}
|
||||
|
||||
fResult.SetLength(length);
|
||||
|
||||
if (fListener != NULL) {
|
||||
fListener->DownloadProgress(this, length, length);
|
||||
if (length > 0)
|
||||
fListener->DataReceived(this, payload, length);
|
||||
}
|
||||
|
||||
if (isBase64)
|
||||
delete payload;
|
||||
|
||||
return B_PROT_SUCCESS;
|
||||
}
|
@ -7,19 +7,18 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <File.h>
|
||||
#include <FileRequest.h>
|
||||
#include <NodeInfo.h>
|
||||
|
||||
|
||||
BFileRequest::BFileRequest(const BUrl& url, BUrlProtocolListener* listener,
|
||||
BUrlContext* context)
|
||||
:
|
||||
BUrlRequest(url, listener, context, "BUrlProtocol.File", "file")
|
||||
BUrlRequest(url, listener, context, "BUrlProtocol.File", "file"),
|
||||
fResult()
|
||||
{
|
||||
}
|
||||
|
||||
@ -29,6 +28,13 @@ BFileRequest::~BFileRequest()
|
||||
}
|
||||
|
||||
|
||||
const BUrlResult&
|
||||
BFileRequest::Result() const
|
||||
{
|
||||
return fResult;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BFileRequest::_ProtocolLoop()
|
||||
{
|
||||
@ -44,6 +50,7 @@ BFileRequest::_ProtocolLoop()
|
||||
off_t size = 0;
|
||||
file.GetSize(&size);
|
||||
fListener->DownloadProgress(this, size, size);
|
||||
fResult.SetLength(size);
|
||||
|
||||
ssize_t chunkSize;
|
||||
char chunk[4096];
|
||||
@ -51,5 +58,10 @@ BFileRequest::_ProtocolLoop()
|
||||
fListener->DataReceived(this, chunk, chunkSize);
|
||||
}
|
||||
|
||||
BNodeInfo info(&file);
|
||||
char mimeType[B_MIME_TYPE_LENGTH + 1];
|
||||
if (info.GetType(mimeType) == B_OK)
|
||||
fResult.SetContentType(mimeType);
|
||||
|
||||
return B_PROT_SUCCESS;
|
||||
}
|
||||
|
@ -58,6 +58,23 @@ BHttpResult::Url() const
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
BHttpResult::ContentType() const
|
||||
{
|
||||
return Headers()["Content-Type"];
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
BHttpResult::Length() const
|
||||
{
|
||||
const char* length = Headers()["Content-Length"];
|
||||
if (length == NULL)
|
||||
return 0;
|
||||
return atoi(length);
|
||||
}
|
||||
|
||||
|
||||
const BHttpHeaders&
|
||||
BHttpResult::Headers() const
|
||||
{
|
||||
|
@ -55,6 +55,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
# TODO: The HTTP stuff should all go into an add-on. It needs
|
||||
# linking against libcrypto.so and only the add-on should link
|
||||
# against it.
|
||||
DataRequest.cpp
|
||||
HttpAuthentication.cpp
|
||||
HttpHeaders.cpp
|
||||
HttpForm.cpp
|
||||
@ -74,6 +75,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
UrlProtocolListener.cpp
|
||||
UrlProtocolRoster.cpp
|
||||
UrlRequest.cpp
|
||||
UrlResult.cpp
|
||||
UrlSynchronousRequest.cpp
|
||||
|
||||
:
|
||||
|
@ -11,10 +11,11 @@
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <UrlRequest.h>
|
||||
#include <DataRequest.h>
|
||||
#include <Debug.h>
|
||||
#include <FileRequest.h>
|
||||
#include <HttpRequest.h>
|
||||
#include <Debug.h>
|
||||
#include <UrlRequest.h>
|
||||
|
||||
|
||||
static BUrlContext gDefaultContext;
|
||||
@ -36,6 +37,8 @@ BUrlProtocolRoster::MakeRequest(const BUrl& url,
|
||||
context);
|
||||
} else if (url.Protocol() == "file") {
|
||||
return new(std::nothrow) BFileRequest(url, listener, context);
|
||||
} else if (url.Protocol() == "data") {
|
||||
return new(std::nothrow) BDataRequest(url, listener, context);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
43
src/kits/network/libnetapi/UrlResult.cpp
Normal file
43
src/kits/network/libnetapi/UrlResult.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2013 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Adrien Destugues, pulkomandy@pulkomandy.tk
|
||||
*/
|
||||
|
||||
|
||||
#include <UrlResult.h>
|
||||
|
||||
|
||||
BUrlResult::~BUrlResult()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BUrlResult::SetContentType(BString contentType)
|
||||
{
|
||||
fContentType = contentType;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BUrlResult::SetLength(size_t length)
|
||||
{
|
||||
fLength = length;
|
||||
}
|
||||
|
||||
|
||||
BString
|
||||
BUrlResult::ContentType() const
|
||||
{
|
||||
return fContentType;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
BUrlResult::Length() const
|
||||
{
|
||||
return fLength;
|
||||
}
|
Loading…
Reference in New Issue
Block a user