diff --git a/uppsrc/Core/Http.cpp b/uppsrc/Core/Http.cpp index 38008bb7e..8c5a64235 100644 --- a/uppsrc/Core/Http.cpp +++ b/uppsrc/Core/Http.cpp @@ -118,6 +118,25 @@ HttpRequest& HttpRequest::Post(const char *id, const String& data) return *this; } +HttpRequest& HttpRequest::Part(const char *id, const String& data, + const char *content_type, const char *filename) +{ + if(IsNull(multipart)) { + POST(); + multipart = AsString(Uuid::Create()); + ContentType("multipart/form-data; boundary=" + multipart); + } + postdata << "--" << multipart << "\r\n" + << "Content-Disposition: form-data; name=\"" << id << "\""; + if(filename && *filename) + postdata << "; filename=\"" << filename << "\""; + postdata << "\r\n"; + if(content_type && *content_type) + postdata << "Content-Type: " << content_type << "\r\n"; + postdata << "\r\n" << data << "\r\n"; + return *this; +} + HttpRequest& HttpRequest::UrlVar(const char *id, const String& data) { int c = *path.Last(); @@ -481,6 +500,8 @@ void HttpRequest::StartRequest() } data << " HTTP/1.1\r\n"; String pd = postdata; + if(!IsNull(multipart)) + pd << "--" << multipart << "--\r\n"; if(method == METHOD_GET || method == METHOD_HEAD) pd.Clear(); if(std_headers) { @@ -521,7 +542,8 @@ void HttpRequest::StartRequest() else if(!force_digest && (!IsNull(username) || !IsNull(password))) data << "Authorization: Basic " << Base64Encode(username + ":" + password) << "\r\n"; - data << request_headers << "\r\n" << pd; + data << request_headers; + data << "\r\n" << pd; LLOG("HTTP REQUEST " << host << ":" << port); LLOG("HTTP request:\n" << data); } @@ -717,7 +739,6 @@ void HttpRequest::Finish() } if(status_code >= 300 && status_code < 400) { String url = GetRedirectUrl(); - GET(); if(url.GetCount() && redirect_count++ < max_redirects) { LLOG("--- HTTP redirect " << url); Url(url); @@ -752,6 +773,8 @@ String HttpRequest::GetPhaseName() const "Receiving chunk header", "Receiving content chunk", "Receiving trailer", + "Request with continue", + "Waiting for continue header", "Finished", "Failed", }; diff --git a/uppsrc/Core/Inet.h b/uppsrc/Core/Inet.h index a1a5487ef..3ed452537 100644 --- a/uppsrc/Core/Inet.h +++ b/uppsrc/Core/Inet.h @@ -346,6 +346,7 @@ class HttpRequest : public TcpSocket { String digest; String request_headers; String postdata; + String multipart; VectorMap cookies; String protocol; @@ -435,13 +436,15 @@ public: HttpRequest& PostUData(const String& pd) { return PostData(UrlEncode(pd)); } HttpRequest& Post(const String& data) { POST(); return PostData(data); } HttpRequest& Post(const char *id, const String& data); - HttpRequest& ClearPost() { PostData(Null); GET(); return *this; } + HttpRequest& Part(const char *id, const String& data, + const char *content_type = NULL, const char *filename = NULL); + HttpRequest& ClearPost() { PostData(Null); multipart.Clear(); GET(); return *this; } HttpRequest& Headers(const String& h) { request_headers = h; return *this; } HttpRequest& ClearHeaders() { return Headers(Null); } HttpRequest& AddHeaders(const String& h) { request_headers.Cat(h); return *this; } HttpRequest& Header(const char *id, const String& data); - + HttpRequest& Cookie(const HttpCookie& c); HttpRequest& Cookie(const String& id, const String& value, const String& domain = Null, const String& path = Null); @@ -487,7 +490,7 @@ public: SSLPROXYREQUEST, SSLPROXYRESPONSE, SSLHANDSHAKE, REQUEST, HEADER, BODY, CHUNK_HEADER, CHUNK_BODY, TRAILER, - FINISHED, FAILED + FINISHED, FAILED, }; bool Do(); diff --git a/uppsrc/Core/src.tpp/HttpRequest$en-us.tpp b/uppsrc/Core/src.tpp/HttpRequest$en-us.tpp index 15534d659..489cdb3aa 100644 --- a/uppsrc/Core/src.tpp/HttpRequest$en-us.tpp +++ b/uppsrc/Core/src.tpp/HttpRequest$en-us.tpp @@ -202,6 +202,19 @@ ing][@(0.0.255) `&]_[*@3 data])&] the format used by HTML forms with `"POST`" method. Returns `*this.&] [s3;%% &] [s4; &] +[s5;:HttpRequest`:`:Part`(const char`*`,const String`&`,const char`*`,const char`*`): [_^HttpRequest^ H +ttpRequest][@(0.0.255) `&]_[* Part]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 id], +[@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 data], [@(0.0.255) const]_[@(0.0.255) c +har]_`*[*@3 content`_type]_`=_NULL, [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 filename]_ +`=_NULL)&] +[s2;%% First call sets HttpRequest to the multipart mode; unique +part boundary is generated automatically. [%-*@3 id] is name of +the part, [%-*@3 data] is cotnet. If [%-*@3 content`_type] is not +NULL nor empty, it defines `"Content`-Type`" part header. [%-*@3 filename] +can be used to define the `"filename`" part of `"Content`-Disposition`" +part header.&] +[s3;%% &] +[s4; &] [s5;:HttpRequest`:`:ClearPost`(`): [_^HttpRequest^ HttpRequest][@(0.0.255) `&]_[* ClearPost ]()&] [s2;%% Empties all Post data and sets the method to GET.&] diff --git a/uppsrc/CtrlCore/DrawTextX11.cpp b/uppsrc/CtrlCore/DrawTextX11.cpp index 9aa7eac95..f4869b46c 100644 --- a/uppsrc/CtrlCore/DrawTextX11.cpp +++ b/uppsrc/CtrlCore/DrawTextX11.cpp @@ -22,7 +22,7 @@ XftFont *CreateXftFont(Font font, int angle) String face = font.GetFaceName(); FcPattern *p = FcPatternCreate(); FcPatternAddString(p, FC_FAMILY, (FcChar8*)~face); - FcPatternAddInteger(p, FC_SLANT, font.IsItalic() ? 110 : 0); + FcPatternAddInteger(p, FC_SLANT, font.IsItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); FcPatternAddInteger(p, FC_PIXEL_SIZE, hg); FcPatternAddInteger(p, FC_WEIGHT, font.IsBold() ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); FcPatternAddBool(p, FC_MINSPACE, 1); diff --git a/uppsrc/Draw/FontFc.cpp b/uppsrc/Draw/FontFc.cpp index 25f127062..d75498eae 100644 --- a/uppsrc/Draw/FontFc.cpp +++ b/uppsrc/Draw/FontFc.cpp @@ -42,7 +42,7 @@ FcPattern *CreateFcPattern(Font font) String face = font.GetFaceName(); FcPattern *p = FcPatternCreate(); FcPatternAddString(p, FC_FAMILY, (FcChar8*)~face); - FcPatternAddInteger(p, FC_SLANT, font.IsItalic() ? 110 : 0); + FcPatternAddInteger(p, FC_SLANT, font.IsItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); FcPatternAddInteger(p, FC_PIXEL_SIZE, hg); FcPatternAddInteger(p, FC_WEIGHT, font.IsBold() ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); FcPatternAddBool(p, FC_MINSPACE, 1); diff --git a/uppsrc/Skylark/Http.cpp b/uppsrc/Skylark/Http.cpp index 94aa4c3d5..72b7b2514 100644 --- a/uppsrc/Skylark/Http.cpp +++ b/uppsrc/Skylark/Http.cpp @@ -370,4 +370,4 @@ Http& Http::UxRun(const String& js_code) return Ux("!", js_code); } -}; \ No newline at end of file +};