]> err.no Git - sope/blobdiff - sope-appserver/NGObjWeb/DynamicElements/WOFileUpload.m
improved query string handling
[sope] / sope-appserver / NGObjWeb / DynamicElements / WOFileUpload.m
index d52f5cd05067696c6cc42e67d9f8233dab34718d..9e763c9d35b3d62cb4985e3838af736a2ba190ce 100644 (file)
@@ -1,29 +1,25 @@
 /*
-  Copyright (C) 2000-2003 SKYRIX Software AG
+  Copyright (C) 2000-2005 SKYRIX Software AG
 
-  This file is part of OGo
+  This file is part of SOPE.
 
-  OGo is free software; you can redistribute it and/or modify it under
+  SOPE is free software; you can redistribute it and/or modify it under
   the terms of the GNU Lesser General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version.
 
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
   License for more details.
 
   You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
+  License along with SOPE; see the file COPYING.  If not, write to the
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
 #include "WOInput.h"
-#include "common.h"
-#import <NGMime/NGMime.h>
-#import <NGHttp/NGHttp.h>
 
 @interface WOFileUpload : WOInput
 {
 
 @end /* WOFileUpload */
 
+#include "decommon.h"
+#include <NGMime/NGMime.h>
+#include <NGHttp/NGHttp.h>
+
 @interface WORequest(UsedPrivates)
 - (id)httpRequest;
 @end
@@ -49,141 +49,151 @@ static NGMimeType *multipartFormData = nil;
 
 + (void)initialize {
   static BOOL isInitialized = NO;
-  if (!isInitialized) {
-    isInitialized = YES;
+  if (isInitialized) return;
+  isInitialized = YES;
 
-    multipartFormData = [NGMimeType mimeType:@"multipart/form-data"];
-    multipartFormData = RETAIN(multipartFormData);
-  }
+  multipartFormData = [[NGMimeType mimeType:@"multipart/form-data"] retain];
 }
 
 - (id)initWithName:(NSString *)_name
   associations:(NSDictionary *)_config
-  template:(WOElement *)_root {
+  template:(WOElement *)_t
+{
 
-  if ((self = [super initWithName:_name associations:_config template:_root])) {
+  if ((self = [super initWithName:_name associations:_config template:_t])) {
     self->filePath = OWGetProperty(_config, @"filePath");
     self->data     = OWGetProperty(_config, @"data");
   }
   return self;
 }
 
-#if !LIB_FOUNDATION_BOEHM_GC
 - (void)dealloc {
-  RELEASE(self->filePath); self->filePath = nil;
-  RELEASE(self->data);     self->data     = nil;
+  [self->filePath release];
+  [self->data     release];
   [super dealloc];
 }
-#endif
 
-// ******************** responder ********************
+/* handling requests */
 
-- (void)takeValuesFromRequest:(WORequest *)_request
-  inContext:(WOContext *)_ctx
-{
-  if (![self->disabled boolValueInComponent:[_ctx component]]) {
-    NSString *currentId;
-    id       formValue  = nil;
-
-    currentId = OWFormElementName(self, _ctx);
+- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
+  NGMimeMultipartBody *body;
+  NGMimeType *contentType;
+  NSString   *currentId;
+  id         formValue  = nil;
+  NSArray    *parts;
+  unsigned   i, count;
+  
+  if ([self->disabled boolValueInComponent:[_ctx component]])
+    return;
+  
+  currentId = OWFormElementName(self, _ctx);
+  
+  if ((formValue = [_rq formValueForKey:currentId]) == nil)
+    return;
 
-    formValue = [_request formValueForKey:currentId];
-    if (formValue) {
-      NGMimeType *contentType = [[_request httpRequest] contentType];
+  contentType = [[_rq httpRequest] contentType];
       
-      if (![contentType hasSameType:multipartFormData]) {
-        NSLog(@"WARNING: tried to apply file-upload value of %@ from "
-              @"a non multipart-form request (value=%@) !",
-              [_ctx elementID], formValue);
-        return;
-      }
-  
-      //NSLog(@"%@: value=%@ ..", [self elementID], formValue);
-
-      if ([self->data isValueSettable])
-        [self->data setValue:formValue inComponent:[_ctx component]];
-
-      if ([self->filePath isValueSettable]) {
-        NGMimeMultipartBody *body = [[_request httpRequest] body];
-
-        if ([body isKindOfClass:[NGMimeMultipartBody class]]) {
-          NSArray  *parts   = [body parts];
-          unsigned i, count = [parts count];
-
-          // search for part of current form element
-          
-          for (i = 0; i < count; i++) {
-            id disposition;
-            id<NGMimePart> bodyPart;
-            
-            bodyPart = [parts objectAtIndex:i];
-            disposition =
-              [[bodyPart valuesOfHeaderFieldWithName:@"content-disposition"]
-                         nextObject];
+  if (![contentType hasSameType:multipartFormData]) {
+    [self warnWithFormat:
+           @"Tried to apply file-upload value of eid=%@ from "
+           @"a non multipart-form request (value=%@).",
+           [_ctx elementID], formValue];
+    return;
+  }
+  
+#if 0
+  NSLog(@"%@: value=%@ ..", [self elementID], formValue);
+#endif
+  
+  if ([self->data isValueSettable])
+    [self->data setValue:formValue inComponent:[_ctx component]];
+  
+  /* the remainder is for locating the file path */
+  
+  if (![self->filePath isValueSettable])
+    return;
+  
+  body = [[_rq httpRequest] body];
+  if (![body isKindOfClass:[NGMimeMultipartBody class]])
+    /* TODO: shouldn't we log something? */
+    return;
+  
+  /* search for part of current form element */
+  
+  parts = [body parts];
+  for (i = 0, count = [parts count]; i < count; i++) {
+    static Class DispClass = Nil;
+    NSString       *formName;
+    id             disposition;
+    id<NGMimePart> bodyPart;
             
-            if (disposition) {
-              static Class DispClass = Nil;
-              NSString *formName;
-              
-              if (DispClass == Nil)
-                DispClass = [NGMimeContentDispositionHeaderField class];
-              
-              if (![disposition isKindOfClass:DispClass]) {
-                disposition =
-                  [[DispClass alloc] initWithString:[disposition stringValue]];
-                AUTORELEASE(disposition);
-              }
+    bodyPart = [parts objectAtIndex:i];
+    disposition = [[bodyPart valuesOfHeaderFieldWithName:
+                              @"content-disposition"] nextObject];
+    
+    if (disposition == nil)
+      continue;
+    
+    if (DispClass == Nil)
+      DispClass = [NGMimeContentDispositionHeaderField class];
               
-              formName =
-               [(NGMimeContentDispositionHeaderField *)disposition name];
-              
-              if ([formName isEqualToString:currentId]) {
-                [self->filePath
-                    setValue:[disposition filename]
-                     inComponent:[_ctx component]];
-                break;
-              }
-            }
-          }
-        }
-      }
+    if (![disposition isKindOfClass:DispClass]) {
+      disposition =
+       [[DispClass alloc] initWithString:[disposition stringValue]];
+      disposition = [disposition autorelease];
+    }
+    
+    formName = [(NGMimeContentDispositionHeaderField *)disposition name];
+      
+    if ([formName isEqualToString:currentId]) {
+      [self->filePath setValue:[disposition filename]
+                     inComponent:[_ctx component]];
+      break;
     }
   }
 }
 
+/* generating response */
+
 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
-  if (![[_ctx request] isFromClientComponent]) {
-    NSString *v = [self->value stringValueInComponent:[_ctx component]];
+  NSString *v;
+  
+  if ([[_ctx request] isFromClientComponent])
+    return;
+  
+  v = [self->value stringValueInComponent:[_ctx component]];
       
-    WOResponse_AddCString(_response, "<input type=\"file\" name=\"");
-    [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
+  WOResponse_AddCString(_response, "<input type=\"file\" name=\"");
+  [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
+  WOResponse_AddChar(_response, '"');
+  if (v != nil) {
+    WOResponse_AddCString(_response, " value=\"");
+    [_response appendContentHTMLAttributeValue:v];
     WOResponse_AddChar(_response, '"');
-    if (v) {
-      WOResponse_AddCString(_response, " value=\"");
-      [_response appendContentHTMLAttributeValue:v];
-      WOResponse_AddChar(_response, '"');
-    }
-    [self appendExtraAttributesToResponse:_response inContext:_ctx];
+  }
+  [self appendExtraAttributesToResponse:_response inContext:_ctx];
   
-    if (self->otherTagString) {
-      WOResponse_AddString(_response,
-                           [self->otherTagString stringValueInComponent:
+  if (self->otherTagString) {
+    WOResponse_AddChar(_response, ' ');
+    WOResponse_AddString(_response,
+                        [self->otherTagString stringValueInComponent:
                                 [_ctx component]]);
-    }
-    WOResponse_AddCString(_response, " />");
   }
+  WOResponse_AddEmptyCloseParens(_response, _ctx);
 }
 
 /* description */
 
 - (NSString *)associationDescription {
-  NSMutableString *str = [[NSMutableString alloc] init];
+  NSMutableString *str;
+  
+  str = [NSMutableString stringWithCapacity:32];
   [str appendString:[super associationDescription]];
-
-  if (self->filePath) [str appendFormat:@" path=%@", self->filePath];
-  if (self->data)     [str appendFormat:@" data=%@", self->data];
-
-  return AUTORELEASE(str);
+  
+  if (self->filePath != nil) [str appendFormat:@" path=%@", self->filePath];
+  if (self->data     != nil) [str appendFormat:@" data=%@", self->data];
+  
+  return str;
 }
 
 @end /* WOFileUpload */